|
| 1 | +name: Setup build |
| 2 | +description: Sets up the build environment for the current job |
| 3 | + |
| 4 | +inputs: |
| 5 | + windows-sdk-version: |
| 6 | + description: The Windows SDK version to use, e.g. "10.0.22621.0" |
| 7 | + required: false |
| 8 | + type: string |
| 9 | + msvc-version: |
| 10 | + description: The Windows MSVC version to use, e.g. "14.42" |
| 11 | + required: false |
| 12 | + type: string |
| 13 | + setup-vs-dev-env: |
| 14 | + description: Whether to set up a Visual Studio Dev Environment |
| 15 | + default: false |
| 16 | + required: false |
| 17 | + type: boolean |
| 18 | + host-arch: |
| 19 | + description: | |
| 20 | + The output's host architecture, "x86", "amd64" or "arm64". Defaults to the build architecture |
| 21 | + (a.k.a. the current runner's architecture). |
| 22 | + This is the target architecture for the Visual Studio Developer Environment. |
| 23 | + required: false |
| 24 | + type: string |
| 25 | + |
| 26 | +outputs: |
| 27 | + windows-build-tools-version: |
| 28 | + description: | |
| 29 | + The full version of the Windows build tools installed, eg. "14.42.34433". This is only set |
| 30 | + if the `msvc-version` input was provided, and only on Windows. |
| 31 | + value: ${{ steps.install-msvc.outputs.windows-build-tools-version }} |
| 32 | + |
| 33 | +runs: |
| 34 | + using: composite |
| 35 | + steps: |
| 36 | + - name: Sanitize input |
| 37 | + id: sanitize-input |
| 38 | + shell: pwsh |
| 39 | + run: | |
| 40 | + if ($IsWindows) { |
| 41 | + $BuildOS = "windows" |
| 42 | + } elseif ($IsMacOS) { |
| 43 | + $BuildOS = "macosx" |
| 44 | + } else { |
| 45 | + Write-Output "::error::Unsupported build OS." |
| 46 | + exit 1 |
| 47 | + } |
| 48 | +
|
| 49 | + $Arch = ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture).ToString() |
| 50 | + switch ($Arch) { |
| 51 | + "X64" { $BuildArch = "amd64" } |
| 52 | + "Arm64" { $BuildArch = "arm64" } |
| 53 | + default { |
| 54 | + Write-Output "::error::Unsupported build architecture: `"$Arch`"" |
| 55 | + exit 1 |
| 56 | + } |
| 57 | + } |
| 58 | +
|
| 59 | + # Validate the MSVC version input. |
| 60 | + # If specified, it is expected to have a format "major.minor", without the build and |
| 61 | + # revision numbers. When a value such as "14.42" is parsed as a `System.Version`, the build |
| 62 | + # and revision numbers in that object are set to -1. |
| 63 | + $MSVCVersion = "${{ inputs.msvc-version }}" |
| 64 | + if ($MSVCVersion -ne "") { |
| 65 | + $ParsedMSVCVersion = [System.Version]::Parse($MSVCVersion) |
| 66 | + if ($ParsedMSVCVersion -eq $null) { |
| 67 | + Write-Output "::error::Invalid Windows MSVC version: `"${MSVCVersion}`"." |
| 68 | + exit 1 |
| 69 | + } |
| 70 | + if ($ParsedMSVCVersion.Major -ne 14) { |
| 71 | + Write-Output "::error::Unsupported Windows MSVC version (major version not supported): `"${MSVCVersion}`"." |
| 72 | + exit 1 |
| 73 | + } |
| 74 | + if ($ParsedMSVCVersion.Build -ne -1) { |
| 75 | + Write-Output "::error::Unsupported Windows MSVC version (build version was specified): `"${MSVCVersion}`"." |
| 76 | + exit 1 |
| 77 | + } |
| 78 | + if ($ParsedMSVCVersion.Revision -ne -1) { |
| 79 | + Write-Output "::error::Unsupported Windows MSVC version (revision version was specified): `"${MSVCVersion}`"." |
| 80 | + exit 1 |
| 81 | + } |
| 82 | + } |
| 83 | +
|
| 84 | + if ("${{ inputs.setup-vs-dev-env }}" -eq "true") { |
| 85 | + switch ("${{ inputs.host-arch }}") { |
| 86 | + "x86" { $HostArch = "x86" } |
| 87 | + "amd64" { $HostArch = "amd64" } |
| 88 | + "arm64" { $HostArch = "arm64" } |
| 89 | + "" { $HostArch = $BuildArch } |
| 90 | + default { |
| 91 | + Write-Output "::error::Unsupported host architecture: `"${{ inputs.host-arch }}`"" |
| 92 | + exit 1 |
| 93 | + } |
| 94 | + } |
| 95 | + } else { |
| 96 | + $HostArch = $BuildArch |
| 97 | + } |
| 98 | +
|
| 99 | + Write-Output "ℹ️ Build OS: $BuildOS" |
| 100 | + Write-Output "ℹ️ Build architecture: $BuildArch" |
| 101 | + Write-Output "ℹ️ Host architecture: $HostArch" |
| 102 | +
|
| 103 | + @" |
| 104 | + build-os=$BuildOS |
| 105 | + build-arch=$BuildArch |
| 106 | + host-arch=$HostArch |
| 107 | + "@ | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append |
| 108 | +
|
| 109 | + - name: Install Windows SDK version ${{ inputs.windows-sdk-version }} |
| 110 | + if: steps.sanitize-input.outputs.build-os == 'windows' && inputs.windows-sdk-version != '' |
| 111 | + shell: pwsh |
| 112 | + run: | |
| 113 | + $WinSdkVersionString = "${{ inputs.windows-sdk-version }}" |
| 114 | + $WinSdkVersion = [System.Version]::Parse($WinSdkVersionString) |
| 115 | + $WinSdkVersionBuild = $WinSdkVersion.Build |
| 116 | +
|
| 117 | + $Win10SdkRoot = Get-ItemPropertyValue ` |
| 118 | + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots" ` |
| 119 | + -Name "KitsRoot10" |
| 120 | + $Win10SdkLib = Join-Path $Win10SdkRoot "Lib" |
| 121 | + $Win10SdkInclude = Join-Path $Win10SdkRoot "Include" |
| 122 | + $Win10SdkIncludeVersion = Join-Path $Win10SdkInclude $WinSdkVersionString |
| 123 | +
|
| 124 | + if (Test-Path -Path $Win10SdkIncludeVersion -PathType Container) { |
| 125 | + Write-Output "ℹ️ MSVCPackageVersionWindows SDK ${WinSdkVersionString} already installed." |
| 126 | + } else { |
| 127 | + # Install the missing SDK. |
| 128 | + Write-Output "ℹ️ Installing Windows SDK ${WinSdkVersionString}..." |
| 129 | +
|
| 130 | + $InstallerLocation = Join-Path "${env:ProgramFiles(x86)}" "Microsoft Visual Studio" "Installer" |
| 131 | + $VSWhere = Join-Path "${InstallerLocation}" "VSWhere.exe" |
| 132 | + $VSInstaller = Join-Path "${InstallerLocation}" "vs_installer.exe" |
| 133 | + $InstallPath = (& "$VSWhere" -latest -products * -format json | ConvertFrom-Json).installationPath |
| 134 | + $process = Start-Process "$VSInstaller" ` |
| 135 | + -PassThru ` |
| 136 | + -ArgumentList "modify", ` |
| 137 | + "--installPath", "`"$InstallPath`"", ` |
| 138 | + "--channelId", "https://aka.ms/vs/17/release/channel", ` |
| 139 | + "--quiet", "--norestart", "--nocache", ` |
| 140 | + "--add", "Microsoft.VisualStudio.Component.Windows11SDK.${WinSdkVersionBuild}" |
| 141 | + $process.WaitForExit() |
| 142 | +
|
| 143 | + if (Test-Path -Path $Win10SdkIncludeVersion -PathType Container) { |
| 144 | + Write-Output "ℹ️ Windows SDK ${WinSdkVersionString} installed successfully." |
| 145 | + } else { |
| 146 | + Write-Output "::error::Failed to install Windows SDK ${WinSdkVersionString}." |
| 147 | + Write-Output "Installer log:" |
| 148 | + $log = Get-ChildItem "${env:TEMP}" -Filter "dd_installer_*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1 |
| 149 | + Get-Content $log.FullName |
| 150 | + exit 1 |
| 151 | + } |
| 152 | + } |
| 153 | +
|
| 154 | + # Remove more recent Windows SDKs, if present. This is used to work |
| 155 | + # around issues where LLVM uses the most recent Windows SDK. |
| 156 | + # This should be removed once a more permanent solution is found. |
| 157 | + # See https://github.com/compnerd/swift-build/issues/958 for details. |
| 158 | + Get-ChildItem -Path $Win10SdkInclude -Directory | ForEach-Object { |
| 159 | + $IncludeDirName = $_.Name |
| 160 | + try { |
| 161 | + $IncludeDirVersion = [System.Version]::Parse($IncludeDirName) |
| 162 | + if ($IncludeDirVersion -gt $WinSdkVersion) { |
| 163 | + $LibDirVersion = Join-Path $Win10SdkLib $IncludeDirName |
| 164 | + Write-Output "ℹ️ Removing folders for Windows SDK ${IncludeDirVersion}." |
| 165 | + Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction Ignore |
| 166 | + Remove-Item -Path $LibDirVersion -Recurse -Force -ErrorAction Ignore |
| 167 | + } |
| 168 | + } catch { |
| 169 | + # Skip if the directory cannot be parsed as a version. |
| 170 | + } |
| 171 | + } |
| 172 | +
|
| 173 | + - name: Install Windows MSVC version ${{ inputs.msvc-version }} |
| 174 | + if: steps.sanitize-input.outputs.build-os == 'windows' && inputs.msvc-version != '' |
| 175 | + id: setup-msvc |
| 176 | + shell: pwsh |
| 177 | + run: | |
| 178 | + # This is assuming a VS2022 toolchain. e.g. |
| 179 | + # MSVC 14.42 corresponds to the 14.42.17.12 package. |
| 180 | + # MSVC 14.43 corresponds to the 14.43.17.13 package. |
| 181 | + $MSVCVersionString = "${{ inputs.msvc-version }}" |
| 182 | +
|
| 183 | + $InstallerLocation = Join-Path "${env:ProgramFiles(x86)}" "Microsoft Visual Studio" "Installer" |
| 184 | + $VSWhere = Join-Path "${InstallerLocation}" "VSWhere.exe" |
| 185 | + $VSInstaller = Join-Path "${InstallerLocation}" "vs_installer.exe" |
| 186 | + $InstallPath = (& "$VSWhere" -latest -products * -format json | ConvertFrom-Json).installationPath |
| 187 | + $MSVCDir = Join-Path $InstallPath "VC" "Tools" "MSVC" |
| 188 | +
|
| 189 | + # Compute the MSVC version package name from the MSVC version, assuming this is coming from |
| 190 | + # a VS2022 installation. The version package follows the following format: |
| 191 | + # * Major and minor version are the same as the MSVC version. |
| 192 | + # * Build version is always 17 (VS2002 is VS17). |
| 193 | + # * The revision is set to the number of minor versions since VS17 release. |
| 194 | + $MSVCVersion = [System.Version]::Parse($MSVCVersionString) |
| 195 | + $MajorVersion = $MSVCVersion.Major |
| 196 | + $MinorVersion = $MSVCVersion.Minor |
| 197 | + $BuildVersion = 17 |
| 198 | + $RevisionVersion = $MinorVersion - 30 |
| 199 | + $MSVCPackageVersion = "${MajorVersion}.${MinorVersion}.${BuildVersion}.${RevisionVersion}" |
| 200 | +
|
| 201 | + # Install the missing MSVC version. |
| 202 | + Write-Output "ℹ️ Installing MSVC packages for ${MSVCPackageVersion}..." |
| 203 | + $process = Start-Process "$VSInstaller" ` |
| 204 | + -PassThru ` |
| 205 | + -ArgumentList "modify", ` |
| 206 | + "--installPath", "`"$InstallPath`"", ` |
| 207 | + "--channelId", "https://aka.ms/vs/17/release/channel", ` |
| 208 | + "--quiet", "--norestart", "--nocache", ` |
| 209 | + "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.x86.x64", ` |
| 210 | + "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.ATL", ` |
| 211 | + "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.ARM64", ` |
| 212 | + "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.ATL.ARM64" |
| 213 | + $process.WaitForExit() |
| 214 | +
|
| 215 | + # Check if the MSVC version was installed successfully. |
| 216 | + $MSVCBuildToolsVersion = "" |
| 217 | + foreach ($dir in Get-ChildItem -Path $MSVCDir -Directory) { |
| 218 | + $MSVCDirName = $dir.Name |
| 219 | + if ($MSVCDirName.StartsWith($MSVCVersionString)) { |
| 220 | + Write-Output "ℹ️ MSVC ${MSVCVersionString} installed successfully." |
| 221 | + $MSVCBuildToolsVersion = $MsvcDirName |
| 222 | + break |
| 223 | + } |
| 224 | + } |
| 225 | +
|
| 226 | + if ($MSVCBuildToolsVersion -eq "") { |
| 227 | + Write-Output "::error::Failed to install MSVC ${MSVCVersionString}." |
| 228 | + Write-Output "Installer log:" |
| 229 | + $log = Get-ChildItem "${env:TEMP}" -Filter "dd_installer_*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1 |
| 230 | + Get-Content $log.FullName |
| 231 | + exit 1 |
| 232 | + } else { |
| 233 | + Write-Output "ℹ️ MSVC ${MSVCBuildToolsVersion} installed successfully." |
| 234 | + "windows-build-tools-version=${MSVCBuildToolsVersion}" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append |
| 235 | + } |
| 236 | +
|
| 237 | + - name: Setup Visual Studio Developer Environment |
| 238 | + if: steps.sanitize-input.outputs.build-os == 'windows' && inputs.setup-vs-dev-env == 'true' |
| 239 | + uses: compnerd/gha-setup-vsdevenv@5eb3eae1490d4f7875d574c4973539f69109700d # main |
| 240 | + with: |
| 241 | + host_arch: ${{ steps.sanitize-input.outputs.build-arch }} |
| 242 | + arch: ${{ steps.sanitize-input.outputs.host-arch }} |
| 243 | + winsdk: ${{ inputs.windows-sdk-version }} |
| 244 | + toolset_version: ${{ inputs.msvc-version }} |
0 commit comments