| 1 | # Building WSL |
| 2 | |
| 3 | ## Prerequisites |
| 4 | |
| 5 | All prerequisites can be installed automatically by running: |
| 6 | |
| 7 | ``` |
| 8 | tools\setup-dev-env.ps1 |
| 9 | ``` |
| 10 | |
| 11 | This uses [WinGet Configuration](https://learn.microsoft.com/windows/package-manager/configuration/) to install Developer Mode, CMake, Visual Studio 2022, and the required workloads from [`.vsconfig`](https://github.com/microsoft/WSL/blob/master/.vsconfig). If VS 2022 is already installed, the script detects your edition (Community, Professional, or Enterprise) and uses the matching configuration. If no VS 2022 is found, it defaults to Community. |
| 12 | |
| 13 | You can also run a WinGet configuration directly for your edition: |
| 14 | |
| 15 | ``` |
| 16 | winget configure --enable |
| 17 | winget configure -f .config/configuration.winget # Community (default) |
| 18 | winget configure -f .config/configuration.vsProfessional.winget # Professional |
| 19 | winget configure -f .config/configuration.vsEnterprise.winget # Enterprise |
| 20 | ``` |
| 21 | |
| 22 | > **Note:** `winget configure --enable` is required to enable the configuration feature. The `setup-dev-env.ps1` script runs this automatically. |
| 23 | |
| 24 | <details> |
| 25 | <summary>Manual installation</summary> |
| 26 | |
| 27 | If you prefer to install prerequisites manually: |
| 28 | |
| 29 | - CMake >= 3.25 |
| 30 | - Can be installed with `winget install Kitware.CMake` |
| 31 | - Visual Studio 2022 with the required components: |
| 32 | - Use VS Installer → More → Import configuration and select [`.vsconfig`](https://github.com/microsoft/WSL/blob/master/.vsconfig) |
| 33 | - Or: `winget install Microsoft.VisualStudio.2022.Community --override "--wait --quiet --config .vsconfig"` |
| 34 | - Enable [Developer Mode](https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) in Windows Settings, or run builds with Administrator privileges (required for symbolic link support) |
| 35 | |
| 36 | </details> |
| 37 | |
| 38 | ### ARM64 development |
| 39 | |
| 40 | When building on ARM64 Windows, the [WiX](https://wixtoolset.org/) toolset (`wix.exe`) requires the **x64 .NET 6.0 runtime** because it is an x64 binary. The ARM64 .NET runtime alone is not sufficient. |
| 41 | |
| 42 | To install the x64 .NET 6.0 runtime, run the following commands in PowerShell: |
| 43 | |
| 44 | ```powershell |
| 45 | # Download the official dotnet-install script |
| 46 | Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "$env:TEMP\dotnet-install.ps1" |
| 47 | |
| 48 | # Install the x64 .NET 6.0 runtime |
| 49 | powershell -ExecutionPolicy Bypass -File "$env:TEMP\dotnet-install.ps1" -Channel 6.0 -Runtime dotnet -Architecture x64 -InstallDir "C:\Program Files\dotnet\x64" |
| 50 | ``` |
| 51 | |
| 52 | Then set the `DOTNET_ROOT_X64` environment variable so the runtime is discoverable: |
| 53 | |
| 54 | ```powershell |
| 55 | # Set for the current session |
| 56 | $env:DOTNET_ROOT_X64 = "C:\Program Files\dotnet\x64" |
| 57 | |
| 58 | # Set permanently for your user |
| 59 | [System.Environment]::SetEnvironmentVariable("DOTNET_ROOT_X64", "C:\Program Files\dotnet\x64", "User") |
| 60 | ``` |
| 61 | |
| 62 | > **Note:** You may need to restart VS Code or open a new terminal for the environment variable to take effect. |
| 63 | |
| 64 | ## Building WSL |
| 65 | |
| 66 | Once you have cloned the repository, generate the Visual Studio solution by running: |
| 67 | |
| 68 | ``` |
| 69 | cmake . |
| 70 | ``` |
| 71 | |
| 72 | This will generate a `wsl.sln` file that you can build either with Visual Studio, or via `cmake --build .`. |
| 73 | |
| 74 | Build parameters: |
| 75 | |
| 76 | - `cmake . -A arm64`: Build a package for ARM64 |
| 77 | - `cmake . -DCMAKE_BUILD_TYPE=Release`: Build for release (paired with cmake --build . --config Release) |
| 78 | - `cmake . -DBUILD_BUNDLE=TRUE`: Build a bundle msix package (requires building ARM64 first) |
| 79 | |
| 80 | Note: To build and deploy faster during development, see options in `UserConfig.cmake`. |
| 81 | |
| 82 | |
| 83 | ## Deploying WSL |
| 84 | |
| 85 | Once the build is complete, you can install WSL by installing the MSI package found under `bin\<platform>\<target>\wsl.msi`, or by running `powershell tools\deploy\deploy-to-host.ps1`. |
| 86 | |
| 87 | To deploy on a Hyper-V virtual machine, you can use `powershell tools\deploy\deploy-to-vm.ps1 -VmName <vm> -Username <username> -Password <password>` |
| 88 | |
| 89 | ## Running tests |
| 90 | |
| 91 | To run unit tests, run: `bin\<platform>\<target>\test.bat`. There's quite a lot of tests so you probably don't want to run everything. Here's a reasonable subset: |
| 92 | `bin\<platform>\<target>\test.bat /name:*UnitTest*` |
| 93 | |
| 94 | To run a specific test case run: |
| 95 | `bin\<platform>\<target>\test.bat /name:<class>::<test>` |
| 96 | Example: `bin\x64\debug\test.bat /name:UnitTests::UnitTests::ModernInstall` |
| 97 | |
| 98 | To run the tests for WSL1, add `-Version 1`. |
| 99 | Example: `bin\x64\debug\test.bat -Version 1` |
| 100 | |
| 101 | |
| 102 | After running the tests once, you can add `-f` to skip the package installation, which makes the tests faster (this requires test_distro to be the default WSL distribution). |
| 103 | |
| 104 | Example: |
| 105 | |
| 106 | ``` |
| 107 | wsl --set-default test_distro |
| 108 | bin\x64\debug\test.bat /name:*UnitTest* -f |
| 109 | ``` |
| 110 | |
| 111 | ## Debugging tests |
| 112 | |
| 113 | See [debugging](debugging.md) for general debugging instructions. |
| 114 | |
| 115 | To automatically attach WinDbgX to the unit test process, use: `/attachdebugger` when calling `test.bat`. |
| 116 | To wait for a debugger to be manually attached, use: `/waitfordebugger`. |
| 117 | Use `/breakonfailure` to automatically break on the first test failure. |
| 118 | |
| 119 | ## Tips and tricks |
| 120 | |
| 121 | **Building and deploying faster** |
| 122 | |
| 123 | To iterate faster, create a copy of [```UserConfig.cmake.sample```](https://github.com/microsoft/WSL/blob/master/UserConfig.cmake.sample): |
| 124 | |
| 125 | ``` |
| 126 | copy UserConfig.cmake.sample UserConfig.cmake |
| 127 | ``` |
| 128 | |
| 129 | And uncomment this line: |
| 130 | |
| 131 | ``` |
| 132 | # set(WSL_DEV_BINARY_PATH "C:/wsldev") |
| 133 | ``` |
| 134 | |
| 135 | This will change the build logic to build a smaller package that installs faster. |
| 136 | Also see: |
| 137 | |
| 138 | - `WSL_BUILD_THIN_PACKAGE` to build an even smaller package |
| 139 | - `WSL_POST_BUILD_COMMAND` to automatically deploy the package during build |
| 140 | |
| 141 | **Code formatting** |
| 142 | |
| 143 | Every pull request needs to be clang-formatted before it can be merged. |
| 144 | |
| 145 | The code can be manually formatted by running: `powershell .\FormatSource.ps1 -ModifiedOnly $false`. |
| 146 | |
| 147 | To automatically check formatting before each commit, run CMake configure (e.g. `cmake .`) and then: `tools\SetupClangFormat.bat` |
| 148 | |
| 149 | The pre-commit hook behavior can be configured by setting `WSL_PRE_COMMIT_MODE` in `UserConfig.cmake`: |
| 150 | |
| 151 | - `warn` (default) – report formatting issues without blocking the commit |
| 152 | - `error` – block the commit when formatting issues are found |
| 153 | - `fix` – automatically fix formatting and re-stage files |