| 1 | cmake_minimum_required(VERSION 3.25) |
| 2 | set(CMAKE_SYSTEM_VERSION 10.0.26100.0) |
| 3 | |
| 4 | project(wsl) |
| 5 | |
| 6 | # Rationalize TARGET_PLATFORM |
| 7 | # When neither CMAKE_GENERATOR_PLATFORM nor TARGET_PLATFORM is set, default to the host architecture. |
| 8 | if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "" AND "${TARGET_PLATFORM}" STREQUAL "") |
| 9 | if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "ARM64") |
| 10 | set(TARGET_PLATFORM "arm64") |
| 11 | else() |
| 12 | set(TARGET_PLATFORM "x64") |
| 13 | endif() |
| 14 | message(STATUS "No platform specified, defaulting to '${TARGET_PLATFORM}' based on host architecture.") |
| 15 | endif() |
| 16 | |
| 17 | if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "arm64" OR "${TARGET_PLATFORM}" STREQUAL "arm64") |
| 18 | set(TARGET_PLATFORM "arm64") |
| 19 | elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64|amd64" OR "${TARGET_PLATFORM}" MATCHES "x64|amd64") |
| 20 | set(TARGET_PLATFORM "x64") |
| 21 | else() |
| 22 | message(FATAL_ERROR "Unsupported platform: ${CMAKE_GENERATOR_PLATFORM}") |
| 23 | endif() |
| 24 | |
| 25 | |
| 26 | if (NOT ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION} STREQUAL ${CMAKE_SYSTEM_VERSION}) |
| 27 | message(FATAL_ERROR "Incorrect Windows SDK version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}, requires ${CMAKE_SYSTEM_VERSION}") |
| 28 | endif() |
| 29 | |
| 30 | # Default to debug build if unspecified (pipeline always passes -DCMAKE_BUILD_TYPE=Release) |
| 31 | if(NOT CMAKE_BUILD_TYPE) |
| 32 | set(CMAKE_BUILD_TYPE "Debug") |
| 33 | endif() |
| 34 | |
| 35 | # Only generate the build configuration that CMake is configured for |
| 36 | set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}" CACHE STRING "" FORCE) |
| 37 | |
| 38 | # Configure output directories |
| 39 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/${TARGET_PLATFORM}) |
| 40 | |
| 41 | # BUNDLE_ONLY mode: skip all source builds; only configure the msixbundle target and nuspec files. |
| 42 | # Used by the package pipeline stage to create the bundle from pre-built per-platform msix files. |
| 43 | option(BUNDLE_ONLY "Only configure the msixbundle target, skip all source builds" OFF) |
| 44 | if (BUNDLE_ONLY) |
| 45 | if (NOT PACKAGE_VERSION) |
| 46 | message(FATAL_ERROR "PACKAGE_VERSION is required for BUNDLE_ONLY mode") |
| 47 | endif() |
| 48 | |
| 49 | if (NOT PACKAGE_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+)$") |
| 50 | message(FATAL_ERROR "PACKAGE_VERSION is invalid: '${PACKAGE_VERSION}'") |
| 51 | endif() |
| 52 | |
| 53 | set(PACKAGE_SIGN_COMMAND echo Skipped package signing for:) |
| 54 | |
| 55 | add_subdirectory(nuget) |
| 56 | add_subdirectory(msixinstaller) |
| 57 | return() |
| 58 | endif() |
| 59 | |
| 60 | include(FetchContent) |
| 61 | |
| 62 | # Import GSL and nlohmannjson |
| 63 | |
| 64 | set(FETCHCONTENT_BASE_DIR ${CMAKE_BINARY_DIR}/_deps/${TARGET_PLATFORM}) |
| 65 | |
| 66 | # N.B. Changes to any of the FetchContent dependencies below (GSL, nlohmannjson) must be reflected in cgmanifest.json |
| 67 | |
| 68 | FetchContent_Declare(GSL |
| 69 | URL https://github.com/microsoft/GSL/archive/refs/tags/v4.0.0.tar.gz |
| 70 | URL_HASH SHA256=f0e32cb10654fea91ad56bde89170d78cfbf4363ee0b01d8f097de2ba49f6ce9) |
| 71 | |
| 72 | FetchContent_MakeAvailable(GSL) |
| 73 | FetchContent_GetProperties(GSL SOURCE_DIR GSL_SOURCE_DIR) |
| 74 | |
| 75 | |
| 76 | FetchContent_Declare(nlohmannjson |
| 77 | URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz |
| 78 | URL_HASH SHA256=42f6e95cad6ec532fd372391373363b62a14af6d771056dbfc86160e6dfff7aa ) |
| 79 | |
| 80 | FetchContent_MakeAvailable(nlohmannjson) |
| 81 | FetchContent_GetProperties(nlohmannjson SOURCE_DIR NLOHMAN_JSON_SOURCE_DIR) |
| 82 | |
| 83 | FetchContent_Declare(yaml-cpp |
| 84 | URL https://github.com/jbeder/yaml-cpp/releases/download/yaml-cpp-0.9.0/yaml-cpp-yaml-cpp-0.9.0.tar.gz |
| 85 | URL_HASH SHA256=298593d9c440fd9034b8b193d96318b76d49bc97c6ceadb7b0836edf0b6d7539) |
| 86 | |
| 87 | set(YAML_CPP_BUILD_TESTS OFF CACHE BOOL "" FORCE) |
| 88 | set(YAML_CPP_BUILD_TOOLS OFF CACHE BOOL "" FORCE) |
| 89 | set(YAML_CPP_BUILD_CONTRIB OFF CACHE BOOL "" FORCE) |
| 90 | set(YAML_MSVC_SHARED_RT OFF CACHE BOOL "" FORCE) |
| 91 | set(BUILD_TESTING OFF CACHE BOOL "" FORCE) # Prevents yaml-cpp from generating CTest* targets |
| 92 | |
| 93 | FetchContent_MakeAvailable(yaml-cpp) |
| 94 | |
| 95 | set(BOOST_VERSION "1.90.0") |
| 96 | set(BOOST_TARBALL "boost_${BOOST_VERSION}") |
| 97 | string(REPLACE "." "_" BOOST_TARBALL "${BOOST_TARBALL}") |
| 98 | |
| 99 | FetchContent_Declare( |
| 100 | boost_headers |
| 101 | URL https://archives.boost.io/release/${BOOST_VERSION}/source/${BOOST_TARBALL}.tar.gz |
| 102 | URL_HASH SHA256=5e93d582aff26868d581a52ae78c7d8edf3f3064742c6e77901a1f18a437eea9 |
| 103 | ) |
| 104 | |
| 105 | FetchContent_MakeAvailable(boost_headers) |
| 106 | |
| 107 | |
| 108 | # Import modules |
| 109 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") |
| 110 | find_package(IDL REQUIRED) |
| 111 | find_package(LINUXBUILD REQUIRED) |
| 112 | find_package(NUGET REQUIRED) |
| 113 | find_package(VERSION REQUIRED) |
| 114 | find_package(MC REQUIRED) |
| 115 | find_package(Appx REQUIRED) |
| 116 | find_package(CSharp REQUIRED) |
| 117 | |
| 118 | # Download nuget packages |
| 119 | restore_nuget_packages() |
| 120 | |
| 121 | # Load nuget packages versions and paths |
| 122 | parse_nuget_packages_versions() |
| 123 | |
| 124 | find_nuget_package(Microsoft.Direct3D.Linux DIRECT3D /build/native) |
| 125 | find_nuget_package(Microsoft.Identity.MSAL.WSL.Proxy MSAL /build/native/bin) |
| 126 | find_nuget_package(Microsoft.RemoteDesktop.Client.MSRDC.SessionHost MSRDC /build/native/bin) |
| 127 | find_nuget_package(Microsoft.Taef TAEF /) |
| 128 | find_nuget_package(Microsoft.Windows.ImplementationLibrary WIL /) |
| 129 | find_nuget_package(Microsoft.WSL.Kernel KERNEL /build/native) |
| 130 | find_nuget_package(Microsoft.WSL.bsdtar BSDTARD /build/native/bin) |
| 131 | find_nuget_package(Microsoft.WSL.LinuxSdk LINUXSDK /) |
| 132 | find_nuget_package(Microsoft.WSL.TestDistro TEST_DISTRO /) |
| 133 | find_nuget_package(Microsoft.WSL.TestData WSL_TEST_DATA /) |
| 134 | find_nuget_package(Microsoft.WSLg WSLG /build/native/bin) |
| 135 | find_nuget_package(vswhere VSWHERE /tools) |
| 136 | find_nuget_package(Wix WIX /tools/net6.0/any) |
| 137 | |
| 138 | # Architecture-specific nuget packages from the OS repo. |
| 139 | if (${TARGET_PLATFORM} STREQUAL "x64") |
| 140 | find_nuget_package(Microsoft.DXCore.Linux.amd64fre DXCORE /build/native) |
| 141 | find_nuget_package(Microsoft.WSL.Dependencies.amd64fre WSLDEPS /build/native) |
| 142 | endif() |
| 143 | |
| 144 | if (${TARGET_PLATFORM} STREQUAL "arm64") |
| 145 | find_nuget_package(Microsoft.DXCore.Linux.arm64fre DXCORE /build/native) |
| 146 | find_nuget_package(Microsoft.WSL.Dependencies.arm64fre WSLDEPS /build/native) |
| 147 | endif() |
| 148 | |
| 149 | # Wsl Settings packages |
| 150 | find_nuget_package(CommunityToolkit.Mvvm CTK_MVVM /) |
| 151 | find_nuget_package(CommunityToolkit.WinUI.Animations CTK_ANIMATIONS /) |
| 152 | find_nuget_package(CommunityToolkit.WinUI.Controls.SettingsControls CTK_STTNGS_CTRLS /) |
| 153 | find_nuget_package(Microsoft.Extensions.Hosting EXTS_HOSTING /) |
| 154 | find_nuget_package(Microsoft.NETCore.App.Runtime.win-${TARGET_PLATFORM} DOTNET_RUNTIME /) |
| 155 | find_nuget_package(Microsoft.WindowsAppSDK WIN_APP_SDK /) |
| 156 | find_nuget_package(Microsoft.Windows.SDK.NET.Ref WINDOWS_SDK_DOTNET /) |
| 157 | find_nuget_package(Microsoft.Xaml.Behaviors.WinUI.Managed XAML_BEHAVIORS /) |
| 158 | find_nuget_package(WinUIEx WINUIEX /) |
| 159 | |
| 160 | # WSLC C# API packages |
| 161 | find_nuget_package(Microsoft.Windows.CsWinRT CSWINRT /) |
| 162 | |
| 163 | set(WSLG_TS_PLUGIN_DLL "WSLDVCPlugin.dll") |
| 164 | |
| 165 | set(SUPPORTED_LANGS cs-CZ;da-DK;de-DE;en-GB;en-US;es-ES;fi-FI;fr-FR;hu-HU;it-IT;ja-JP;ko-KR;nb-NO;nl-NL;pl-PL;pt-BR;pt-PT;ru-RU;sv-SE;tr-TR;zh-CN;zh-TW) |
| 166 | |
| 167 | if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/UserConfig.cmake") |
| 168 | find_package(USER REQUIRED PATHS ${CMAKE_CURRENT_LIST_DIR}) |
| 169 | endif() |
| 170 | |
| 171 | if (WSL_DEVICEHOST_BIN) |
| 172 | set(WSL_VIRTIO_NET_IDL_PATH "${WSL_DEVICEHOST_BIN}/WslDeviceHost.idl") |
| 173 | set(WSL_DEVICE_HOST_DLL_PATH "${WSL_DEVICEHOST_BIN}/wsldevicehost.dll") |
| 174 | set(WSL_DEVICE_HOST_VERSION "9.0.0-localbuild") |
| 175 | else() |
| 176 | find_nuget_package(Microsoft.WSL.DeviceHost WSL_DEVICE_HOST /build/native) |
| 177 | set(WSL_VIRTIO_NET_IDL_PATH "${WSL_DEVICE_HOST_SOURCE_DIR}/idl/WslDeviceHost.idl") |
| 178 | set(WSL_DEVICE_HOST_DLL_PATH "${WSL_DEVICE_HOST_SOURCE_DIR}/bin/${TARGET_PLATFORM}/wsldevicehost.dll") |
| 179 | endif() |
| 180 | |
| 181 | # Optional target configuration |
| 182 | |
| 183 | if (NOT DEFINED WSL_BUILD_WSL_SETTINGS) |
| 184 | set(WSL_BUILD_WSL_SETTINGS false) |
| 185 | endif () |
| 186 | |
| 187 | if (NOT DEFINED WSL_INCLUDE_SDK_CSHARP) |
| 188 | set(WSL_INCLUDE_SDK_CSHARP false) |
| 189 | endif () |
| 190 | |
| 191 | # Number of sources combined into each unity translation unit. |
| 192 | # Set to 0 to compile every file separately. |
| 193 | set(WSL_UNITY_BATCH_SIZE_DEFAULT 0) |
| 194 | |
| 195 | if (NOT DEFINED WSL_UNITY_BATCH_SIZE) |
| 196 | set(WSL_UNITY_BATCH_SIZE ${WSL_UNITY_BATCH_SIZE_DEFAULT}) |
| 197 | endif () |
| 198 | |
| 199 | if (NOT WSL_UNITY_BATCH_SIZE MATCHES "^[0-9]+$") |
| 200 | message(FATAL_ERROR "WSL_UNITY_BATCH_SIZE must be a non-negative integer: got '${WSL_UNITY_BATCH_SIZE}'") |
| 201 | endif () |
| 202 | |
| 203 | # Applies to every target created below. Targets that can't be unified opt out |
| 204 | # individually with UNITY_BUILD OFF. |
| 205 | # N.B. This is set after the FetchContent dependencies are made available so that |
| 206 | # third party targets keep building file by file. |
| 207 | if (WSL_UNITY_BATCH_SIZE GREATER 0) |
| 208 | set(CMAKE_UNITY_BUILD ON) |
| 209 | set(CMAKE_UNITY_BUILD_MODE BATCH) |
| 210 | set(CMAKE_UNITY_BUILD_BATCH_SIZE ${WSL_UNITY_BATCH_SIZE}) |
| 211 | message(STATUS "Unity build enabled with a batch size of ${WSL_UNITY_BATCH_SIZE}") |
| 212 | endif () |
| 213 | find_commit_hash(COMMIT_HASH) |
| 214 | |
| 215 | if (NOT PACKAGE_VERSION) |
| 216 | find_version(PACKAGE_VERSION WSL_NUGET_PACKAGE_VERSION) # Fetch the package version from git if not specified |
| 217 | endif () |
| 218 | |
| 219 | if (NOT PACKAGE_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+)$") |
| 220 | message(FATAL_ERROR "PACKAGE_VERSION must be four dot-separated numeric components (e.g., '1.2.3.4'): got '${PACKAGE_VERSION}'") |
| 221 | endif() |
| 222 | |
| 223 | set(PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) |
| 224 | set(PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2}) |
| 225 | set(PACKAGE_VERSION_REVISION ${CMAKE_MATCH_3}) |
| 226 | |
| 227 | # The store requires the revision number to be 0, so enforce this on official builds |
| 228 | if (OFFICIAL_BUILD AND NOT PACKAGE_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.0$") |
| 229 | message(FATAL_ERROR "PACKAGE_VERSION is invalid: '${PACKAGE_VERSION}'. Needs to match '([0-9]+).([0-9]+).([0-9]+).0' for official builds") |
| 230 | endif() |
| 231 | |
| 232 | if (${TARGET_PLATFORM} STREQUAL "x64") |
| 233 | set(DCAT_PRODUCT_NAME WSL.amd64) |
| 234 | endif() |
| 235 | |
| 236 | if (${TARGET_PLATFORM} STREQUAL "arm64") |
| 237 | set(DCAT_PRODUCT_NAME WSL.arm64) |
| 238 | endif() |
| 239 | |
| 240 | set(DCAT_REGISTRATION_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Update\\TargetingInfo\\DynamicInstalled\\${DCAT_PRODUCT_NAME}") |
| 241 | |
| 242 | # Configure output directories |
| 243 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/${TARGET_PLATFORM}) |
| 244 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug) |
| 245 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release) |
| 246 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) |
| 247 | |
| 248 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) |
| 249 | |
| 250 | # Packaging variables |
| 251 | set(BIN ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}) |
| 252 | file(MAKE_DIRECTORY ${BIN}) |
| 253 | |
| 254 | set (GENERATED_DIR ${CMAKE_BINARY_DIR}/generated) |
| 255 | file(MAKE_DIRECTORY ${GENERATED_DIR}) |
| 256 | |
| 257 | # Generate Source Link JSON so debuggers can fetch source from GitHub (pipeline builds only) |
| 258 | if (DEFINED PIPELINE_BUILD_ID) |
| 259 | set(SOURCELINK_JSON "${GENERATED_DIR}/sourcelink.json") |
| 260 | file(WRITE "${SOURCELINK_JSON}" "{\"documents\":{\"${CMAKE_SOURCE_DIR}/*\":\"https://raw.githubusercontent.com/microsoft/WSL/${COMMIT_HASH}/*\"}}") |
| 261 | endif() |
| 262 | |
| 263 | set(PACKAGE_CERTIFICATE ${GENERATED_DIR}/dev-cert.pfx) |
| 264 | |
| 265 | # Link the third-party binaries we ship (and their PDBs) into bin so packaging |
| 266 | # and the pipeline's symbol publishing step find them. Without the PDBs here, |
| 267 | # Watson can't resolve function names in their crash frames. |
| 268 | string(REPLACE ".dll" ".pdb" WSLG_TS_PLUGIN_PDB ${WSLG_TS_PLUGIN_DLL}) |
| 269 | file(CREATE_LINK ${WSLG_SOURCE_DIR}/${TARGET_PLATFORM}/${WSLG_TS_PLUGIN_DLL} ${BIN}/${WSLG_TS_PLUGIN_DLL}) |
| 270 | file(CREATE_LINK ${WSLG_SOURCE_DIR}/${TARGET_PLATFORM}/${WSLG_TS_PLUGIN_PDB} ${BIN}/${WSLG_TS_PLUGIN_PDB}) |
| 271 | file(CREATE_LINK ${WSLDEPS_SOURCE_DIR}/bin/wsldeps.dll ${BIN}/wsldeps.dll) |
| 272 | file(CREATE_LINK ${WSLDEPS_SOURCE_DIR}/bin/wsldeps.pdb ${BIN}/wsldeps.pdb) |
| 273 | # wsldevicehost.dll is packaged directly from its NuGet package, so only its PDB |
| 274 | # needs linking into bin for symbol publishing. |
| 275 | if (NOT WSL_DEVICEHOST_BIN) |
| 276 | file(CREATE_LINK ${WSL_DEVICE_HOST_SOURCE_DIR}/bin/${TARGET_PLATFORM}/wsldevicehost.pdb ${BIN}/wsldevicehost.pdb) |
| 277 | endif() |
| 278 | |
| 279 | if (${SKIP_PACKAGE_SIGNING}) |
| 280 | set(PACKAGE_SIGN_COMMAND echo Skipped package signing for:) |
| 281 | else() |
| 282 | if (NOT EXISTS ${PACKAGE_CERTIFICATE}) |
| 283 | execute_process( |
| 284 | COMMAND powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File "${CMAKE_CURRENT_LIST_DIR}/tools/create-dev-cert.ps1" -OutputPath "${PACKAGE_CERTIFICATE}" |
| 285 | COMMAND_ERROR_IS_FATAL ANY) |
| 286 | endif() |
| 287 | |
| 288 | set(PACKAGE_SIGN_COMMAND SignTool.exe sign /a /v /fd SHA256 /f ${PACKAGE_CERTIFICATE}) |
| 289 | endif() |
| 290 | |
| 291 | |
| 292 | # Generate local test script |
| 293 | configure_file(${CMAKE_CURRENT_LIST_DIR}/tools/test/test.bat.in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/test.bat) |
| 294 | |
| 295 | # Common build flags |
| 296 | set(CMAKE_CXX_STANDARD 20) |
| 297 | |
| 298 | if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") |
| 299 | set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug) |
| 300 | else() |
| 301 | set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) |
| 302 | endif() |
| 303 | |
| 304 | if (${TARGET_PLATFORM} STREQUAL "x64") |
| 305 | add_compile_definitions(_AMD64_) |
| 306 | set(DISTRO_HOSTTYPE x86_64) |
| 307 | endif() |
| 308 | |
| 309 | if (${TARGET_PLATFORM} STREQUAL "arm64") |
| 310 | add_compile_definitions(_ARM64_) |
| 311 | set(DISTRO_HOSTTYPE aarch64) |
| 312 | endif() |
| 313 | |
| 314 | add_definitions(/sdl) # Default-initialize class members |
| 315 | add_definitions(/FS) # Enable parallel PDB access |
| 316 | add_compile_definitions(UNICODE |
| 317 | WIL_SUPPRESS_PRIVATE_API_USE |
| 318 | CPPWINRT_SUPPRESS_STATIC_INITIALIZERS |
| 319 | NOMINMAX |
| 320 | _CRT_SECURE_NO_WARNINGS |
| 321 | KERNEL_VERSION="${KERNEL_VERSION}" |
| 322 | WSLDEPS_VERSION="${WSLDEPS_VERSION}" |
| 323 | WSLG_VERSION="${WSLG_VERSION}" |
| 324 | WSLG_TS_PLUGIN_DLL=L"${WSLG_TS_PLUGIN_DLL}" |
| 325 | WSL_DEVICE_HOST_VERSION="${WSL_DEVICE_HOST_VERSION}" |
| 326 | COMMIT_HASH="${COMMIT_HASH}" |
| 327 | WSL_PACKAGE_VERSION="${PACKAGE_VERSION}" |
| 328 | MSRDC_VERSION="${MSRDC_VERSION}" |
| 329 | DIRECT3D_VERSION="${DIRECT3D_VERSION}" |
| 330 | DXCORE_VERSION="${DXCORE_VERSION}" |
| 331 | WSL_PACKAGE_VERSION_MAJOR=${PACKAGE_VERSION_MAJOR} |
| 332 | WSL_PACKAGE_VERSION_MINOR=${PACKAGE_VERSION_MINOR} |
| 333 | WSL_PACKAGE_VERSION_REVISION=${PACKAGE_VERSION_REVISION} |
| 334 | DISTRO_HOSTTYPE="${DISTRO_HOSTTYPE}" |
| 335 | WSL_BUILD_WSL_SETTINGS=${WSL_BUILD_WSL_SETTINGS} |
| 336 | DCAT_PRODUCT_NAME=R"\(${DCAT_PRODUCT_NAME}\)" |
| 337 | DCAT_REGISTRATION_KEY=R"\(${DCAT_REGISTRATION_KEY}\)") |
| 338 | |
| 339 | if (${OFFICIAL_BUILD}) |
| 340 | add_compile_definitions(WSL_OFFICIAL_BUILD) |
| 341 | endif() |
| 342 | |
| 343 | if (${WSL_BUILD_THIN_PACKAGE}) |
| 344 | add_compile_definitions(WSL_DEV_THIN_MSI_PACKAGE="${BIN}/wsl.msi") |
| 345 | endif () |
| 346 | |
| 347 | string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) # make sure /Zi is removed from the debug flags |
| 348 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /W3 /WX /ZH:SHA_256") |
| 349 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7 -DDEBUG -DDBG") |
| 350 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /guard:cf /Qspectre") |
| 351 | |
| 352 | # Linker flags |
| 353 | set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /debug:full /debugtype:cv,fixup /guard:cf /DYNAMICBASE") |
| 354 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /debug:full /debugtype:cv,fixup /guard:cf /DYNAMICBASE") |
| 355 | if (DEFINED SOURCELINK_JSON) |
| 356 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SOURCELINK:\"${SOURCELINK_JSON}\"") |
| 357 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SOURCELINK:\"${SOURCELINK_JSON}\"") |
| 358 | endif() |
| 359 | if (${TARGET_PLATFORM} STREQUAL "x64") |
| 360 | set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /CETCOMPAT") |
| 361 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /CETCOMPAT") |
| 362 | endif() |
| 363 | |
| 364 | # Hybrid CRT: static-link the C++ runtime and STL (/MT|/MTd from CMAKE_MSVC_RUNTIME_LIBRARY), |
| 365 | # but dynamic-link the Universal CRT (ucrt.dll) which is an OS component on Windows 10+. |
| 366 | # This eliminates the VCRUNTIME/MSVCP redistributable dependency while avoiding the size |
| 367 | # cost of statically linking the UCRT. See https://aka.ms/hybridcrt for details. |
| 368 | set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libucrt.lib /defaultlib:ucrt.lib") |
| 369 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libucrt.lib /defaultlib:ucrt.lib") |
| 370 | set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libucrtd.lib /defaultlib:ucrtd.lib") |
| 371 | set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libucrtd.lib /defaultlib:ucrtd.lib") |
| 372 | |
| 373 | # Common link libraries |
| 374 | link_directories(${WSLDEPS_SOURCE_DIR}/lib/) |
| 375 | set(COMMON_LINK_LIBRARIES |
| 376 | ws2_32.lib |
| 377 | Userenv.lib |
| 378 | RuntimeObject.lib |
| 379 | Pathcch.lib |
| 380 | ntdll.lib |
| 381 | RpcRT4.lib |
| 382 | Mswsock.lib |
| 383 | Shlwapi.lib |
| 384 | synchronization.lib |
| 385 | Bcrypt.lib |
| 386 | Crypt32.lib |
| 387 | icu.lib) |
| 388 | |
| 389 | set(MSI_LINK_LIBRARIES |
| 390 | Wintrust.lib |
| 391 | msi.lib) |
| 392 | |
| 393 | set(HCS_LINK_LIBRARIES |
| 394 | computecore.lib |
| 395 | computenetwork.lib |
| 396 | Iphlpapi.lib) |
| 397 | |
| 398 | set(SERVICE_LINK_LIBRARIES |
| 399 | MI.lib |
| 400 | wsldeps.lib) |
| 401 | |
| 402 | # Linux |
| 403 | if(${TARGET_PLATFORM} STREQUAL "" OR ${TARGET_PLATFORM} STREQUAL "x64") |
| 404 | set(LLVM_ARCH x86_64) |
| 405 | elseif(${TARGET_PLATFORM} STREQUAL "arm64") |
| 406 | set(LLVM_ARCH aarch64) |
| 407 | else() |
| 408 | message(FATAL_ERROR "Unsupported platform: '${TARGET_PLATFORM}'") |
| 409 | endif() |
| 410 | |
| 411 | # Determine the Visual Studio installation directory which contains LLVM tools. |
| 412 | # Supported versions: VS2022 and VS2026. |
| 413 | # Prefer VS2022 to keep local clang-format output aligned with pipeline expectations. |
| 414 | function(find_vs_install_dir VERSION_RANGE OUTPUT_VAR) |
| 415 | execute_process( |
| 416 | COMMAND "${VSWHERE_SOURCE_DIR}/vswhere.exe" -version "${VERSION_RANGE}" -products * -requires Microsoft.VisualStudio.Component.VC.Llvm.Clang -property installationPath -prerelease -latest |
| 417 | OUTPUT_VARIABLE _vs_install_dir |
| 418 | OUTPUT_STRIP_TRAILING_WHITESPACE |
| 419 | COMMAND_ERROR_IS_FATAL ANY |
| 420 | ) |
| 421 | |
| 422 | set(${OUTPUT_VAR} "${_vs_install_dir}" PARENT_SCOPE) |
| 423 | endfunction() |
| 424 | |
| 425 | find_vs_install_dir("[17.0,18.0)" VS_INSTALL_DIR) |
| 426 | |
| 427 | if (NOT VS_INSTALL_DIR) |
| 428 | find_vs_install_dir("[18.0,19.0)" VS_INSTALL_DIR) |
| 429 | if (VS_INSTALL_DIR) |
| 430 | message(WARNING "Visual Studio 2022 was not found; using Visual Studio 2026 instead. clang-format output may differ from pipeline expectations.") |
| 431 | endif() |
| 432 | endif() |
| 433 | |
| 434 | if (NOT VS_INSTALL_DIR) |
| 435 | message(FATAL_ERROR "Could not determine Visual Studio installation directory.") |
| 436 | endif() |
| 437 | |
| 438 | # Pick the first line returned from vswhere, in case multiple versions are returned. |
| 439 | # TODO: Remove this and require VS 2026 once the CI supports it. |
| 440 | string(REGEX MATCH "([^\n\r]+)" VS_INSTALL_DIR "${VS_INSTALL_DIR}") |
| 441 | |
| 442 | if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "AMD64") |
| 443 | set(LLVM_INSTALL_DIR "${VS_INSTALL_DIR}/VC/Tools/Llvm/x64/bin") |
| 444 | else() |
| 445 | set(LLVM_INSTALL_DIR "${VS_INSTALL_DIR}/VC/Tools/Llvm/${CMAKE_HOST_SYSTEM_PROCESSOR}/bin") |
| 446 | endif() |
| 447 | |
| 448 | if (NOT EXISTS ${LLVM_INSTALL_DIR}) |
| 449 | message(FATAL_ERROR "C++ Clang Compiler for Windows is not installed at ${LLVM_INSTALL_DIR}. Please install it from the Visual Studio Installer.") |
| 450 | endif() |
| 451 | |
| 452 | # Generate the clang-format script which contains a path to clang-format.exe |
| 453 | configure_file(${CMAKE_CURRENT_LIST_DIR}/tools/FormatSource.ps1.in ${CMAKE_BINARY_DIR}/FormatSource.ps1) |
| 454 | |
| 455 | # Pre-commit hook mode: warn (default), error, or fix |
| 456 | set(WSL_PRE_COMMIT_MODE "warn" CACHE STRING "Pre-commit hook behavior: warn, error, or fix") |
| 457 | |
| 458 | # Generate the pre-commit hook into the build tree |
| 459 | file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/tools/hooks) |
| 460 | configure_file(${CMAKE_CURRENT_LIST_DIR}/tools/hooks/pre-commit.in ${CMAKE_BINARY_DIR}/tools/hooks/pre-commit @ONLY) |
| 461 | |
| 462 | set(LINUXSDK_PATH ${LINUXSDK_SOURCE_DIR}/${LLVM_ARCH}) |
| 463 | set(LLVM_TARGET "${LLVM_ARCH}-unknown-linux-musl") |
| 464 | set(LINUX_CC ${LLVM_INSTALL_DIR}/clang.exe) |
| 465 | set(LINUX_CXX ${LLVM_INSTALL_DIR}/clang++.exe) |
| 466 | set(LINUX_AR ${LLVM_INSTALL_DIR}/llvm-ar.exe) |
| 467 | set(LINUX_COMMON_FLAGS --gcc-toolchain=${LINUXSDK_PATH} |
| 468 | -fpic |
| 469 | -B${LINUXSDK_PATH} |
| 470 | -isysroot ${LINUXSDK_PATH} |
| 471 | -isystem ${LINUXSDK_PATH}/include/c++/v1 |
| 472 | -isystem ${LINUXSDK_PATH}/include |
| 473 | -isystem ${GSL_SOURCE_DIR}/include |
| 474 | -isystem "${WSLDEPS_SOURCE_DIR}/include/lxcore" |
| 475 | -isystem "${WSLDEPS_SOURCE_DIR}/include/schemas" |
| 476 | -I "${CMAKE_CURRENT_LIST_DIR}/src/linux/inc" |
| 477 | -I "${CMAKE_CURRENT_LIST_DIR}/src/linux/mountutil" |
| 478 | -I "${CMAKE_CURRENT_LIST_DIR}/src/linux/plan9" |
| 479 | -I "${CMAKE_CURRENT_LIST_DIR}/src/shared/configfile" |
| 480 | -I "${CMAKE_CURRENT_LIST_DIR}/src/shared/inc" |
| 481 | -I "${NLOHMAN_JSON_SOURCE_DIR}/include" |
| 482 | -I "${CMAKE_BINARY_DIR}/generated" |
| 483 | --no-standard-libraries |
| 484 | -Werror |
| 485 | -Wall |
| 486 | -Wpointer-arith |
| 487 | -D_POSIX_C_SOURCE=200809L |
| 488 | -Dswprintf_s=swprintf |
| 489 | -fms-extensions |
| 490 | -target ${LLVM_TARGET} |
| 491 | -D_GNU_SOURCE=1 |
| 492 | -D_LARGEFILE64_SOURCE |
| 493 | -DWSL_PACKAGE_VERSION="${PACKAGE_VERSION}" |
| 494 | -DWSL_PACKAGE_VERSION_MAJOR=${PACKAGE_VERSION_MAJOR} |
| 495 | -DWSL_PACKAGE_VERSION_MINOR=${PACKAGE_VERSION_MINOR} |
| 496 | -DWSL_PACKAGE_VERSION_REVISION=${PACKAGE_VERSION_REVISION} |
| 497 | ) |
| 498 | |
| 499 | if (${TARGET_PLATFORM} STREQUAL "x64") |
| 500 | set(LINUX_COMMON_FLAGS ${LINUX_COMMON_FLAGS} -D_AMD64_) |
| 501 | endif() |
| 502 | |
| 503 | if (${TARGET_PLATFORM} STREQUAL "arm64") |
| 504 | set(LINUX_COMMON_FLAGS ${LINUX_COMMON_FLAGS} -D_ARM64_) |
| 505 | endif() |
| 506 | |
| 507 | set(LINUX_CXXFLAGS ${LINUX_COMMON_FLAGS} -std=c++20) |
| 508 | set(LINUX_CFLAGS ${LINUX_COMMON_FLAGS} -std=c99) |
| 509 | |
| 510 | string(TOLOWER ${CMAKE_BUILD_TYPE} build_type) |
| 511 | if (build_type STREQUAL debug) |
| 512 | set(LINUX_BUILD_TYPE_FLAGS -g3 -fno-inline-functions -DDEBUG -DDBG) |
| 513 | else() |
| 514 | set(LINUX_BUILD_TYPE_FLAGS -g -O2 -DNDEBUG) |
| 515 | endif() |
| 516 | |
| 517 | set(LINUX_LDFLAGS -target ${LLVM_TARGET} |
| 518 | --gcc-toolchain=${LINUXSDK_PATH} |
| 519 | -B${LINUXSDK_PATH} |
| 520 | -isysroot ${LINUXSDK_PATH} |
| 521 | -nostartfiles |
| 522 | --no-standard-libraries |
| 523 | -fuse-ld=lld.exe |
| 524 | -L${LINUXSDK_PATH}/lib |
| 525 | -L${LINUXSDK_PATH}/lib/linux |
| 526 | -L${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE} |
| 527 | -lclang_rt.builtins-${LLVM_ARCH} |
| 528 | -l:libc.a |
| 529 | -static) |
| 530 | |
| 531 | set(COMMON_LINUX_LINK_LIBRARIES configfile) |
| 532 | file(GLOB COMMON_LINUX_HEADERS CONFIGURE_DEPENDS "${CMAKE_CURRENT_LIST_DIR}/src/shared/inc/*.h") |
| 533 | |
| 534 | if(DEFINED ENV{WSL_DEV_BINARY_PATH}) |
| 535 | set(WSL_DEV_BINARY_PATH $ENV{WSL_DEV_BINARY_PATH}) |
| 536 | endif() |
| 537 | |
| 538 | if (DEFINED WSL_DEV_BINARY_PATH) # Development shortcut to make the package smaller |
| 539 | add_compile_definitions(WSL_SYSTEM_DISTRO_PATH="${WSL_DEV_BINARY_PATH}/system.vhd" |
| 540 | WSL_KERNEL_PATH="${WSL_DEV_BINARY_PATH}/kernel" |
| 541 | WSL_KERNEL_MODULES_PATH="${WSL_DEV_BINARY_PATH}/artifacts.vhd" |
| 542 | WSL_DEV_INSTALL_PATH="${WSL_DEV_BINARY_PATH}" |
| 543 | WSL_GPU_LIB_PATH="${WSL_DEV_BINARY_PATH}/lib") |
| 544 | endif() |
| 545 | |
| 546 | # Common include paths |
| 547 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wil/include) |
| 548 | include_directories(${boost_headers_SOURCE_DIR}) |
| 549 | include_directories(${WSLDEPS_SOURCE_DIR}/include) |
| 550 | include_directories(${WSLDEPS_SOURCE_DIR}/include/Windows) |
| 551 | include_directories(${WSLDEPS_SOURCE_DIR}/include/schemas) |
| 552 | include_directories(${WSLDEPS_SOURCE_DIR}/include/lxcore) |
| 553 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/shared/inc) |
| 554 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/windows/inc) |
| 555 | include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/windows/wsldevicehoststub/inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}) |
| 556 | include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/windows/service/inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}) |
| 557 | include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/windows/wslinstaller/inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}) |
| 558 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/linux/init/inc) |
| 559 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/windows/common) |
| 560 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/shared/configfile) |
| 561 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/localization) |
| 562 | include_directories(${CMAKE_BINARY_DIR}/generated) |
| 563 | |
| 564 | include_directories(${WIL_SOURCE_DIR}/include) |
| 565 | include_directories(${GSL_SOURCE_DIR}/include) |
| 566 | include_directories(${TAEF_SOURCE_DIR}/build/include) |
| 567 | |
| 568 | include_directories(${NLOHMAN_JSON_SOURCE_DIR}/include) |
| 569 | link_directories(${TAEF_SOURCE_DIR}/build/Library/${TARGET_PLATFORM}) |
| 570 | set(TAEF_LINK_LIBRARIES |
| 571 | TE.Common.lib |
| 572 | Wex.Common.lib |
| 573 | Wex.Logger.lib) |
| 574 | |
| 575 | # Subprojects |
| 576 | add_subdirectory(nuget) |
| 577 | add_subdirectory(msixgluepackage) |
| 578 | add_subdirectory(msipackage) |
| 579 | add_subdirectory(msixinstaller) |
| 580 | add_subdirectory(src/windows/wsldevicehoststub/inc) |
| 581 | add_subdirectory(src/windows/common) |
| 582 | add_subdirectory(src/windows/service) |
| 583 | add_subdirectory(src/windows/wsldevicehoststub) |
| 584 | add_subdirectory(src/windows/wslcsession) |
| 585 | add_subdirectory(src/windows/wslinstaller/inc) |
| 586 | add_subdirectory(src/windows/wslinstaller/stub) |
| 587 | add_subdirectory(src/windows/wslinstaller/exe) |
| 588 | add_subdirectory(src/shared/configfile) |
| 589 | add_subdirectory(src/windows/wsl) |
| 590 | add_subdirectory(src/windows/wslg) |
| 591 | add_subdirectory(src/windows/wslhost) |
| 592 | add_subdirectory(src/windows/wslrelay) |
| 593 | add_subdirectory(src/windows/wslinstall) |
| 594 | add_subdirectory(src/windows/wslc) |
| 595 | add_subdirectory(src/windows/WslcSDK) |
| 596 | |
| 597 | if (WSL_BUILD_WSL_SETTINGS) |
| 598 | add_subdirectory(src/windows/libwsl) |
| 599 | add_subdirectory(src/windows/wslsettings) |
| 600 | endif() |
| 601 | |
| 602 | add_subdirectory(src/linux/netlinkutil) |
| 603 | add_subdirectory(src/linux/mountutil) |
| 604 | add_subdirectory(src/linux/plan9) |
| 605 | add_subdirectory(src/linux/init) |
| 606 | add_subdirectory(localization) |
| 607 | |
| 608 | add_subdirectory(test/windows) |
| 609 | |
| 610 | if (DEFINED PIPELINE_BUILD_ID) |
| 611 | add_subdirectory(cloudtest) |
| 612 | endif() |
| 613 | |
| 614 | |
| 615 | if(DEFINED ENV{WSL_POST_BUILD_COMMAND}) |
| 616 | set(WSL_POST_BUILD_COMMAND $ENV{WSL_POST_BUILD_COMMAND}) |
| 617 | endif () |