Setting Up Windows Subsystem For Linux Version 1 (WSL1) on Windows 10

Disclaimer: These instructions were tested with Windows 10 build 19042 in May of 2021. The latest version of Ubuntu at this time is 20.04. Any version will likely work just fine, however, some of the instructions may be out-dated in time. Also, this document only shows how to setup WSL version 1 (the latest is version 2). Since we only need the capabilities of version 1, that's what I'm showing. If you want to install version 2, you will have to do more work. The first link below goes into detail on how to install version 2.

This webpage is based on information from these links: Realize, that Microsoft is notorious for broken links. If the link above no longer works, you're on your own (and Google is your friend). To find out exactly which version of Windows 10 you have, type winver at the command prompt (or in the Start Menu) and a dialog box will show you the version.


Topics:

Enabling WSL and Downloading Ubuntu

  1. Before installing any Linux distros for WSL, you must ensure that the "Windows Subsystem for Linux" optional feature is enabled. To do that, open PowerShell as Adminstrator and run this command:
    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
    
    After running the command, reboot the computer. It will install more things during the shutdown and restart phase.
  2. The next step is to download a Linux distribution. The recommended distribution is Ubuntu 20.04 LTS. Open PowerShell (non-Administrator) and run this command:
    Invoke-WebRequest -Uri https://aka.ms/wslubuntu2004 -OutFile Ubuntu.appx -UseBasicParsing
    
    This will download the distribution. The file will be named Ubuntu.appx and is about 450 MBs. It may take a few minutes to download depending on the network speed.
  3. Now, it's time to "install" the distribution. In PowerShell (non-Administrator), run this command:
    Add-AppxPackage .\Ubuntu.appx
    
    And that's it! Ubuntu 20.04 LTS has been installed and is ready to be setup. That's the topic of the next section.

More details:

Setting Up WSL

  1. Once WSL and a Linux distribution has been downloaded and installed, it is ready to be enabled for each user. Type ubuntu in the Start Menu and if it is installed you should see something like the image below. (You're start menu is likely to look different.)

  2. Run the app called Ubuntu 20.04 LTS from the Start Menu and it will open a command window. DO NOT run this as Administrator.

  3. After a few minutes it will prompt you to create a username and password. Even though it says you can create any username and password, DO NOT DO THAT! Use your Digipen username and password. It will be much easier to remember. If you choose a different username and password and you forget either one, you CAN NOT get it back. You will have to delete your entire account and start over. The IT dept. has absolutely no way to help you.

    Congratulations! You are now running Linux (inside of Windows)! You can tell because the command prompt has changed:

    If you are familiar with Linux you can skip the rest of this brief tutorial and just start having fun with it! However, if you are new to Linux, you can continue on and see how to get a build environment and memory debugger setup.

Updating and Installing Software in Linux

Disclaimer: The screenshots in this section were taken while running Ubuntu version 18.04 (and an older build of Windows 10), so the exact output will likely be different on your system.

  1. The next step is to update some things in Linux so you can install some software. Run the command:
    sudo apt update
    
    It will prompt you for your password (the one the just created, which is the same as your Digipen Windows password, right?) It will run for a minute or so and then tell you it's done:


  2. The next step is to make sure all of the installed software is up to date. To do that, run this command:
    sudo apt upgrade
    
    It will figure out which packages (apps) have been updated and then download and install them. Depending on how out-of-date your system is, this could take no time (everything is up to date) or many minutes (lots of outdated software).

    The output (not shown) will look something like the pictures shown in step #3 and #4 below.


  3. Ok, now you're ready to install some development tools. Run this command next:
    sudo apt install build-essential gcc g++ valgrind
    
    This will install the GCC C compiler, C++ compiler, Valgrind (the memory debugger) and some other dev tools (make, etc.). It will take a few minutes.


  4. In a few minutes you'll see something like this when it's done:
    Congratulations! You've just setup a development environment, installed a C and C++ compiler, and installed a memory debugger! You can now close the command window.

Testing Valgrind in Linux

  1. Ok, so now you want to test things out to see if you've set up everything correctly. Let's use the WarBoats program to test it out. In Windows, navigate to your WarBoats project. (If you don't have a WarBoats project, any project that has dynamic memory allocation will work.) You can even make a simple one-liner C program that forces a memory leak:
    #include <stdlib.h>
    int main(void)
    {
      malloc(123); /* Leaks 123 bytes of memory */
      return 0;
    }
    
    Open up a command prompt in the WarBoats (or whatever project) folder. Now, you're at the command line, but you are still in Windows.


  2. Type wsl (that's lowercase WSL) on the command line and you will be switched over to Linux. Again, it's easy to see because your command prompt has changed:

    Remember the command wsl as it is the command you use to switch into Linux. You will still be in the same directory as you were in Windows (which is very convenient). To get out of Linux and return back to Windows, simply type exit while you're in Linux. If you happen to type exit while you're in Windows, it will close the command prompt and you'll have to reopen it.

    Notice the directory you're in. My example shows: /mnt/c/Users/mmead/Documents/warboats
    When you're in Linux, the entire C drive for Windows is located in /mnt/c. Also notice that directories are separated by a forward slash / in Linux. Windows uses a backslash \.


  3. In case you have some old Windows files hanging around, run make clean and then make to build the project as a Linux project. The binary files (e.g. executables, object files) from Linux and Windows are incompatible, so you must rebuild them when switching between Windows and Linux. Trivial to do with a makefile, of course. (You are using makefiles, right?)

    Once you've built the project, execute it to make sure it actually works. Remember, in Linux and Mac, you run the program like this with a leading dot and forward slash:

    ./warboats 1
    
    The next screenshot shows you what happens after running the program.


  4. This shows the last few lines of output from the first test:

    Ok, it looks like things are working. Now, let's add a memory leak!


  5. Load your file (Ocean.cpp for WarBoats) into any text editor and add a memory leak. I've just removed the delete (freeing memory) in the DestroyOcean function. In the code below theOcean is a pointer to a dynamically-allocated structure. Failing to delete that will cause a memory leak.


  6. Run make again (not shown) to rebuild with the leak. Then, run this command:
    valgrind -q --leak-check=full --show-reachable=yes ./warboats 1 > /dev/null
    
    This will cause Valgrind to run WarBoats (the first test only) and to look for memory problems. The end of the command:
    > /dev/null 
    
    suppresses the output from WarBoats (redirects it to nowhere). At this point, we don't care what the output is because we just want to see Valgrind's output. We can see that Valgrind found the memory leak:

    It says that 48 bytes were leaked. This is simply because that's the sizeof(Ocean). Here are the relevant structures to see for yourself. (There are 4 bytes of padding for alignment in the Ocean struct)

      //! Statistics of the "game"
    struct ShotStats
    {
      int hits;       //!< The number of boat hits
      int misses;     //!< The number of boat misses
      int duplicates; //!< The number of duplicate (misses/hits)
      int sunk;       //!< The number of boats sunk
    };
    
      //! The attributes of the ocean
    struct Ocean
    {
      int *grid;        //!< The 2D ocean 
      Boat *boats;      //!< The dynamic array of boats
      int num_boats;    //!< Number of boats in the ocean
      int x_quadrants;  //!< Ocean size along x-axis
      int y_quadrants;  //!< Ocean size along y-axis
      ShotStats stats;  //!< Status of the attack
    };
    
    You can ignore the error on the first line of output:
    error calling PR_SET_PTRACER, vgdb might block
    
    as it probably won't affect any of you. If you're interested, you can find some information on that error here or Google for more.


  7. Now, go back to the text editor and fix the leak (not shown). Then, run make again, and then run valgrind again. The leaks are gone!


Links

  1. Windows Subsystem for Linux Documentation - This is from Microsoft
  2. How to open a PowerShell as Adminstrator.
  3. Installing WSL on Windows 10
  4. Downloading Linux distributions
  5. VcXsrv - A free and open source X Server for Windows
  6. Startup apps - How to configure apps to start automatically when Windows is booted.
  7. Disable the annoying "chimes" in bash on Windows 10