├── README.md ├── .gitignore ├── .github ├── workflows │ ├── release-5-10-swift-toolchain-schedule.yml │ ├── release-6-0-swift-toolchain-schedule.yml │ ├── test-setup-build.yml │ └── build-toolchain.yml └── actions │ ├── setup-sccache │ └── action.yml │ ├── setup-build │ └── action.yml │ └── configure-cmake-project │ └── action.yml ├── LICENSE ├── docs ├── ReleaseProcess.md └── WindowsQuickStart.md ├── stable.xml └── default.xml /README.md: -------------------------------------------------------------------------------- 1 | # **//swift/build** 2 | 3 | `//swift/build` homes the CI configuration for GitHub Actions based builds as 4 | well as a repo manifest to provide the ability to sync the full repository set. 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | 8 | .*.sw[nop] 9 | 10 | -------------------------------------------------------------------------------- /.github/workflows/release-5-10-swift-toolchain-schedule.yml: -------------------------------------------------------------------------------- 1 | name: Release 5.10 Toolchains 2 | 3 | on: 4 | workflow_dispatch: 5 | # Schedule to build a new release toolchain nightly. 6 | # Note: This is disabled on compnerd/swift-build as the 7 | # build times out when running the GitHub workflow in that repo. 8 | # schedule: 9 | # - cron: "10 0 * * */1" 10 | 11 | jobs: 12 | # Each job builds a release toolchain for a specific Swift version. 13 | build-release-5_10: 14 | # Note: GitHub requires the use of an 'owner/repo' path before the 15 | # workflow file path when we want to use a workflow from another branch. 16 | uses: compnerd/swift-build/.github/workflows/swift-toolchain.yml@release/5.10 17 | secrets: 18 | SYMBOL_SERVER_PAT: ${{ secrets.SYMBOL_SERVER_PAT }} 19 | CERTIFICATE: ${{ secrets.CERTIFICATE }} 20 | PASSPHRASE: ${{ secrets.PASSPHRASE }} 21 | -------------------------------------------------------------------------------- /.github/workflows/release-6-0-swift-toolchain-schedule.yml: -------------------------------------------------------------------------------- 1 | name: Release 6.0 Toolchains 2 | 3 | on: 4 | workflow_dispatch: 5 | # Schedule to build a new release toolchain nightly. 6 | # Note: This is disabled on compnerd/swift-build as the 7 | # build times out when running the GitHub workflow in that repo. 8 | # schedule: 9 | # - cron: "10 0 * * */1" 10 | 11 | jobs: 12 | # Each job builds a release toolchain for a specific Swift version. 13 | build-release-6_0: 14 | # Note: GitHub requires the use of an 'owner/repo' path before the 15 | # workflow file path when we want to use a workflow from another branch. 16 | uses: compnerd/swift-build/.github/workflows/swift-toolchain.yml@release/6.0 17 | secrets: 18 | SYMBOL_SERVER_PAT: ${{ secrets.SYMBOL_SERVER_PAT }} 19 | CERTIFICATE: ${{ secrets.CERTIFICATE }} 20 | PASSPHRASE: ${{ secrets.PASSPHRASE }} 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Saleem Abdulrasool and contributors 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /docs/ReleaseProcess.md: -------------------------------------------------------------------------------- 1 | # Release Process 2 | 3 | The swift-build repository needs a new release branch that tracks a corresponding 4 | Swift release branch, every time Swift cuts a new release branch. This branch 5 | in responsible for building the toolchain for that branch only. 6 | 7 | This guide details which things need to be updated when 8 | the `swift-build` release branch is created. 9 | 10 | ## Github swift-toolchain workflow update 11 | 12 | The swift-toolchain workflow needs to be updated once a new branch is created. 13 | 14 | Firstly, the branch that the `repo` tool uses is inferred from the Swift version given to the 15 | github action. The repo tool checks 16 | out the Swift repos from the manifest provided in the XML file. These lines 17 | specify the Swift version passed to the Github action: 18 | 19 | ```yaml 20 | swift_version: 21 | description: 'Swift Version' 22 | default: '0.0.0' 23 | required: false 24 | type: string 25 | ``` 26 | 27 | Instead of the the '0.0.0', the default should be changed to the version that's 28 | used by the release branch. For instance, for the 5.10 Swift release the default 29 | should be set to '5.10.0': 30 | 31 | ```yaml 32 | swift_version: 33 | description: 'Swift Version' 34 | default: '5.10.0' 35 | required: false 36 | type: string 37 | ``` 38 | 39 | Then, the `repo` tool manifest should be updated. It's specified in the `default.xml` file. 40 | Branches should follow the release conventions instead of main. The primary branch for most repos 41 | is specified in the `default` XML item: 42 | 43 | ```xml 44 | 45 | ``` 46 | 47 | This should be changed to appropriate release default, e.g. `release/5.10`. 48 | Certain other repos need a different default. For example, llvm-project uses 49 | the `swift/release/5.10` convention instead, and thus it has to be specified 50 | manually in the repo reference item, so for the 5.10 release it should look like: 51 | ```xml 52 | 53 | ``` 54 | 55 | You can look at the `default.xml` file in the prior release branch to see which repos need to follow 56 | custom conventions instead of using the default release branch name. 57 | 58 | ## Release workflow update 59 | 60 | THe release-swift-toolchain-schedule workflow needs to be updated once a new release branch is 61 | created, to ensure that new releases are being built continously automatically for it. 62 | You can do that by updating the `release-switch-toolchain-schedule.yml` file, and add a new 63 | job that invokes the `swift-toolchain.yml` workflow for the specified release branch. 64 | For instance, for a 5.10 release, you can add the following entry to the `jobs` section 65 | of the `release-swift-toolchain-schedule.yml` file: 66 | 67 | ```yaml 68 | build-release-5_10: 69 | uses: compnerd/swift-build/.github/workflows/swift-toolchain.yml@release/5.10 70 | secrets: 71 | ... 72 | ``` 73 | -------------------------------------------------------------------------------- /.github/actions/setup-sccache/action.yml: -------------------------------------------------------------------------------- 1 | name: "Setup sccache" 2 | description: "Sets up sccache with S3 or local disk configuration" 3 | 4 | inputs: 5 | disk-max-size: 6 | description: "The maximum size of the local disk cache in MB if S3 is unavailable." 7 | required: true 8 | disk-cache-key: 9 | description: "The key to use for the local disk cache." 10 | required: true 11 | s3-bucket: 12 | description: "The s3 bucket to use for cache storage." 13 | required: false 14 | s3-bucket-encryption: 15 | description: "Whether to enable server-side encryption for the S3 bucket." 16 | required: false 17 | default: "true" 18 | aws-arn: 19 | description: "The ARN of the AWS role to assume which has read/write access to the S3 bucket." 20 | required: false 21 | aws-region: 22 | description: "The region of the S3 bucket to use for the cache" 23 | required: false 24 | 25 | runs: 26 | using: composite 27 | steps: 28 | - name: Configure caching enviornment 29 | shell: pwsh 30 | run: | 31 | $AWSArn = '${{ inputs.aws-arn }}' 32 | if ($AWSArn) { 33 | $requiredParams = @{ 34 | 's3-bucket' = '${{ inputs.s3-bucket }}' 35 | 's3-bucket-encryption' = '${{ inputs.s3-bucket-encryption }}' 36 | 'aws-region' = '${{ inputs.aws-region }}' 37 | } 38 | 39 | foreach ($param in $requiredParams.GetEnumerator()) { 40 | if ([string]::IsNullOrEmpty($param.Value)) { 41 | Write-Error -Message "$($param.Key) input cannot be empty when aws-arn is provided" -ErrorAction Stop 42 | } 43 | } 44 | 45 | Write-Host "Using S3 bucket ${{ inputs.s3-bucket }} for cache storage." 46 | "SCCACHE_BUCKET=${{ inputs.s3-bucket }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 47 | "SCCACHE_REGION=${{ inputs.aws-region }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 48 | "SCCACHE_S3_SERVER_SIDE_ENCRYPTION=${{ inputs.s3-bucket-encryption }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 49 | } else { 50 | Write-Host "Using local disk cache." 51 | "SCCACHE_DIRECT=on" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 52 | } 53 | 54 | - name: Authenticate to AWS 55 | id: aws-credentials 56 | uses: aws-actions/configure-aws-credentials@ececac1a45f3b08a01d2dd070d28d111c5fe6722 # v4.1.0 57 | if: inputs.aws-arn != '' 58 | with: 59 | role-to-assume: ${{ inputs.aws-arn }} 60 | role-session-name: ToolchainCISccacheAccess 61 | aws-region: ${{ inputs.aws-region }} 62 | special-characters-workaround: 'true' # special characters in secrets can cause SignatureDoesNotMatch errors 63 | 64 | - name: Setup sccache (remote) 65 | if: inputs.aws-arn != '' && steps.aws-credentials.outcome == 'success' 66 | uses: hendrikmuhs/ccache-action@63069e3931dedbf3b63792097479563182fe70d1 # v1.2.18 67 | with: 68 | variant: sccache 69 | 70 | - name: Setup sccache (local) 71 | if: inputs.aws-arn == '' 72 | uses: hendrikmuhs/ccache-action@63069e3931dedbf3b63792097479563182fe70d1 # v1.2.18 73 | with: 74 | max-size: ${{ inputs.disk-max-size }} 75 | key: ${{ inputs.disk-cache-key }} 76 | variant: sccache 77 | -------------------------------------------------------------------------------- /stable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/WindowsQuickStart.md: -------------------------------------------------------------------------------- 1 | # Building the toolchain on Windows 2 | 3 | Visual Studio 2022 is required to build Swift on Windows; any edition is fine. 4 | Visual Studio 2017 should be possible to use, though it may require some 5 | additional work to repair the build. Visual Studio 2019 can be used to build, 6 | though some of the automation will need to be adjusted for paths. 7 | 8 | ## Preflight 9 | 10 | > [!IMPORTANT] 11 | > The following commands must be run in the Windows Command Prompt launched from 12 | the start menu. They wil not work if run in Windows Powershell or if run in a 13 | Windows Command Prompt launched from inside an existing installation of Visual 14 | Studio. 15 | 16 | ### Visual Studio 17 | 18 | Installing Visual Studio can be done manually or in an unattended manner. The 19 | following snippet installs the necessary components of Visual Studio 2022 in an 20 | automated fashion. 21 | 22 | ```cmd 23 | curl.exe -sOL https://aka.ms/vs/17/release/vs_community.exe 24 | vs_community.exe ^ 25 | --add Microsoft.NetCore.Component.SDK ^ 26 | --add Microsoft.VisualStudio.Component.Git ^ 27 | --add Microsoft.VisualStudio.Component.VC.CMake.Project ^ 28 | --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ^ 29 | --add Microsoft.VisualStudio.Component.VC.Tools.ARM64 ^ 30 | --add Microsoft.VisualStudio.Component.VC.ATL ^ 31 | --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 ^ 32 | --add Microsoft.VisualStudio.Component.Windows10SDK ^ 33 | --add Microsoft.VisualStudio.Component.Windows11SDK.22621 34 | del /q vs_community.exe 35 | ``` 36 | 37 | ### Install Python 38 | 39 | The `repo` tool uses Python, and as such, we need a Python installation on the host. We recommend installing **Python 3.10.1** to ensure compatibility with the provided scripts and examples. Download and install Python 3.10.1 for your platform from [https://www.python.org/downloads/release/python-3101/](https://www.python.org/downloads/release/python-3101/). 40 | 41 | ### Enable Symbolic Links Support 42 | 43 | > [!NOTE] 44 | > This step only needs to be completed if your User is not an Administrator, as Adminstrators already have permission to create symbolic links. 45 | 46 | Grant your user the `SeCreateSymbolicLinkPrivilege` rights. This can be done by 47 | applying a Group Policy Object to the system. Run `gpedit.msc` and navigate to 48 | 49 | ~~~ 50 | Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment 51 | ~~~ 52 | 53 | In the `Create symbolic links` entry, add your user. You will need to restart 54 | your session for the permission to be applied globally. 55 | 56 | See [Microsoft documentation](https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links) 57 | for additional information about this and the implications of changing this 58 | permission. 59 | 60 | ### Enable Symbolic Links, Line Ending Conversion in Git 61 | 62 | Some of the repositories depend on symbolic links when checking out the sources. 63 | Additionally, some of the test inputs are line-ending sensitive and will need to 64 | be checked out with a specific line ending. You can simply set the global 65 | defaults to ensure that the features are configured properly for all 66 | repositories. 67 | 68 | ```cmd 69 | git config --global --add core.autocrlf false 70 | git config --global --add core.symlinks true 71 | ``` 72 | 73 | ### Environment Setup 74 | 75 | The remainder of the instructions assume that everything is being performed in 76 | the instruction standard location. The sources are expected to reside on a 77 | drive labelled `S`. If your sources are on another drive letter, you can use 78 | the `subst` command to create a temporary, session local, drive mapping. 79 | 80 | ```cmd 81 | subst S: %UserProfile%\source 82 | ``` 83 | 84 | The development drive must be formatted with NTFS or ReFS to ensure that 85 | symbolic link support is available. ExFAT does not support this functionality, 86 | and while portable, would not allow required functionality to build Swift. 87 | 88 | ### Cloning Repositories 89 | 90 | The easiest way to clone the repositories is by using the 91 | [repo tool](https://gerrit.googlesource.com/git-repo). See the documentation 92 | from repo to install repo. 93 | 94 | ```cmd 95 | S: 96 | md Applications 97 | curl.exe -sLo S:\Applications\repo https://storage.googleapis.com/git-repo-downloads/repo 98 | md SourceCache 99 | cd SourceCache 100 | set PYTHONUTF8=1 101 | python S:\Applications\repo init -u https://github.com/compnerd/swift-build 102 | python S:\Applications\repo sync -j 8 103 | ``` 104 | 105 | Subsequently, you can update all the repositories using `python S:\Applications\repo sync`. 106 | 107 | If you wish to sync to a point that is known to build successfully, you can use the smart sync option: 108 | 109 | ``` 110 | python S:\Applications\repo sync -s 111 | ``` 112 | 113 | You may also sync to specific toolchain versions by providing `repo` with the corresponding manifest file. Download `swift-build/stable.xml` at some revision, then sync with 114 | ``` 115 | python S:\Applications\repo sync -m path\to\stable.xml 116 | ``` 117 | 118 | If you wish to build a specific release branch, you can specify the `-b` (branch) option to `repo` to checkout the branch: 119 | ``` 120 | python S:\Applications\repo init -b release/6.0 121 | python S:\Applications\repo sync 122 | ``` 123 | 124 | You may also do this at the initial checkout time as: 125 | ``` 126 | python S:\Applications\repo init -u https://github.com/compnerd/swift-build -b release/6.0 127 | ``` 128 | 129 | ## Building 130 | 131 | The full toolchain can be built in an automated fashion. The following script 132 | will perform a build and package of the toolchain. 133 | 134 | ``` 135 | S:\SourceCache\swift\utils\build.cmd -Windows 136 | ``` 137 | 138 | ### Building for local debugging and testing 139 | 140 | Additional `-DebugInfo` build script flag is required to build to build the toolchain with 141 | debug information. For example, the following script invocation 142 | will build the toolchain with PDB debug information, and will also skip the 143 | installer packaging, which is rarely needed for local development. 144 | 145 | ``` 146 | S:\SourceCache\swift\utils\build.cmd -Windows -DebugInfo -SkipPackaging 147 | ``` 148 | 149 | The `-Test` flag can be used to build the tests for a toolchain component. For instance, 150 | the following script invocation will ensure that the test targets for all components 151 | that support testing are built: 152 | 153 | ``` 154 | S:\SourceCache\swift\utils\build.cmd -Windows -DebugInfo -SkipPackaging -Test '*' 155 | ``` 156 | 157 | ### Speeding up the build with sccache 158 | 159 | The `-EnableCaching` flag can be used to speed up the build. This will automatically download 160 | SCCache before building. Note that this flag will help speed up the build of the C/C++ code 161 | but not the Swift code as `sccache` doesn't currently support Swift. 162 | 163 | ``` 164 | S:\SourceCache\swift\utils\build.cmd -Windows -EnableCaching 165 | ``` 166 | 167 | ## Using the Toolchain 168 | 169 | ### Environment Setup 170 | 171 | The Windows toolchain depends on some environment variables. If you wish to use 172 | the locally built toolchain without installing with the distribution packaging, 173 | you will need to manually configure the enviornment everytime you wish to use 174 | the toolchain. 175 | 176 | > [!CAUTION] 177 | > **DO NOT** add this to your environment by default. The normal toolchain build will not function properly with the environment configuration. 178 | 179 | ```cmd 180 | set SDKROOT=S:\Program Files\Swift\Platforms\Windows.platform\Developer\SDKs\Windows.sdk 181 | path S:\b\Python%PROCESSOR_ARCHITECTURE%-3.10.1\tools;S:\Program Files\Swift\Runtimes\0.0.0\usr\bin;S:\Program Files\Swift\Toolchains\0.0.0+Asserts\usr\bin;%PATH% 182 | ``` 183 | 184 | ### PowerShell Helper 185 | 186 | The following content in your Powershell profile file (whose path is stored in the built-in `$Profile` variable) would help quickly switch a shell to the proper configuration for using the just built toolchain. 187 | 188 | ```pwsh 189 | function Set-SwiftEnv { 190 | $SwiftRoot = "S:\Program Files\Swift" 191 | $env:SDKROOT = "${SwiftRoot}\Platforms\Windows.platform\Developer\SDKs\Windows.sdk" 192 | $env:Path = "S:\b\Python${env:PROCESSOR_ARCHITECTURE}-3.10.1\tools;${SwiftRoot}\Runtimes\0.0.0\usr\bin;${SwiftRoot}\Toolchains\0.0.0+Asserts\usr\bin;${env:Path}" 193 | } 194 | Set-Alias -Name SwiftEnv -Value Set-SwiftEnv 195 | ``` 196 | 197 | It can be used by sourcing the file and executing the function as follows: 198 | ```pwsh 199 | Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process 200 | . $Profile 201 | Set-SwiftEnv 202 | ``` 203 | 204 | ## Troubleshooting 205 | 206 | If you run into build failures with the following errors: 207 | ``` 208 | clang: error: no such file or directory: '\INCREMENTAL:NO' 209 | clang: error: no such file or directory: '\OPT:REF' 210 | clang: error: no such file or directory: '\OPT:ICF' 211 | ``` 212 | the reason is that the CMake on your system is too _new_. The latest version of CMake you should use is [CMake 3.29.x](https://cmake.org/files/v3.29/). 213 | -------------------------------------------------------------------------------- /.github/workflows/test-setup-build.yml: -------------------------------------------------------------------------------- 1 | name: Test the setup-build action 2 | on: 3 | pull_request: 4 | branches: 5 | - 'main' 6 | paths: 7 | - '.github/actions/setup-build/action.yml' 8 | - '.github/workflows/test-setup-build.yml' 9 | workflow_dispatch: 10 | inputs: 11 | windows-runner: 12 | description: "The Windows runner to use" 13 | required: false 14 | type: string 15 | workflow_call: 16 | inputs: 17 | windows-runner: 18 | description: "The Windows runner to use" 19 | required: false 20 | type: string 21 | 22 | env: 23 | TEST_WIN_SDK_VERSION: "10.0.22621.0" 24 | TEST_MSVC_VERSION: "14.40" 25 | TEST_BUILD_TOOLS_EXPECTED_VERSION: "14.40.33807" 26 | TEST_UPSTREAM_SWIFT_VERSION: "5.10" 27 | TEST_BCNY_SWIFT_VERSION: "6.0.0-20241216.0" 28 | TEST_BCNY_SWIFT_REPO: "thebrowsercompany/swift-build" 29 | 30 | jobs: 31 | test-setup-build-windows-vs-dev-env: 32 | name: MSVC + WinSDK With Dev Environment 33 | runs-on: ${{ inputs.windows-runner || 'windows-latest' }} 34 | steps: 35 | - name: Checkout 36 | uses: actions/checkout@v4.2.2 37 | 38 | - name: Set up build 39 | id: setup-build 40 | uses: ./.github/actions/setup-build 41 | with: 42 | windows-sdk-version: ${{ env.TEST_WIN_SDK_VERSION }} 43 | msvc-version: ${{ env.TEST_MSVC_VERSION }} 44 | setup-vs-dev-env: true 45 | 46 | - name: Check environment 47 | run: | 48 | $HasError = $false 49 | 50 | $ParsedWinSdkVersion = [System.Version]::Parse($env:TEST_WIN_SDK_VERSION) 51 | $Win10SdkRoot = Get-ItemPropertyValue ` 52 | -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots" ` 53 | -Name "KitsRoot10" 54 | $Win10SdkInclude = Join-Path $Win10SdkRoot "Include" 55 | 56 | # Check if the Windows SDK version is installed. 57 | $ExpectedWinSdkDir = Join-Path $Win10SdkInclude "$($env:TEST_WIN_SDK_VERSION)" 58 | if (Test-Path -Path $ExpectedWinSdkDir) { 59 | Write-Output "✅ Windows SDK version `"${env:TEST_WIN_SDK_VERSION}`" is installed." 60 | } else { 61 | Write-Output "::error::Expected Windows SDK version not found: `"${env:TEST_WIN_SDK_VERSION}`"." 62 | $HasError = $true 63 | } 64 | 65 | # Check if Windows SDK versions greater than the expected version are installed. 66 | $UnexpectedSdkFound = $false 67 | Get-ChildItem -Path $Win10SdkInclude -Directory | ForEach-Object { 68 | $Version = $_.Name 69 | try { 70 | $ParsedVersion = [System.Version]::Parse($Version) 71 | if ($ParsedVersion -gt $ParsedWinSdkVersion) { 72 | Write-Output "::error::Unexpected Windows SDK version found: `"${Version}`" (greater than expected: `"${env:TEST_WIN_SDK_VERSION}`")." 73 | $HasError = $true 74 | $UnexpectedSdkFound = $true 75 | } 76 | } catch { 77 | # Skip if the directory cannot be parsed as a version. 78 | } 79 | } 80 | if (-not $UnexpectedSdkFound) { 81 | Write-Output "✅ No unexpected Windows SDK versions greater than `"${env:TEST_WIN_SDK_VERSION}`" found." 82 | } 83 | 84 | $BuildToolsVersion = "${{ steps.setup-build.outputs.windows-build-tools-version }}" 85 | if ($BuildToolsVersion -ne $env:TEST_BUILD_TOOLS_EXPECTED_VERSION) { 86 | Write-Output "::error::Expected build tools version `"${env:TEST_BUILD_TOOLS_EXPECTED_VERSION}`", but got `"${BuildToolsVersion}`"." 87 | $HasError = $true 88 | } else { 89 | Write-Output "✅ Build tools version `"${BuildToolsVersion}`" matches expected version." 90 | } 91 | 92 | # Check if the correct MSVC version is installed. 93 | $InstallerLocation = Join-Path "${env:ProgramFiles(x86)}" "Microsoft Visual Studio" "Installer" 94 | $VSWhere = Join-Path "${InstallerLocation}" "vswhere.exe" 95 | $InstallPath = (& "$VSWhere" -latest -products * -format json | ConvertFrom-Json).installationPath 96 | $MSVCDir = Join-Path $InstallPath "VC" "Tools" "MSVC" $BuildToolsVersion 97 | if (Test-Path -Path $MSVCDir) { 98 | Write-Output "✅ MSVC version `"${env:TEST_MSVC_VERSION}`" is installed." 99 | } else { 100 | Write-Output "::error::MSVC directory not found: `"${MSVCDir}`"." 101 | $HasError = $true 102 | } 103 | 104 | # Check the current cl.exe version by expanding the _MSC_VER macro. 105 | $tempFile = [System.IO.Path]::GetTempFileName().Replace('.tmp', '.c') 106 | Set-Content -Path $tempFile -Value "_MSC_VER" 107 | $clOutput = & cl /nologo /EP $tempFile 2>&1 108 | $lastLine = $clOutput | Select-Object -Last 1 109 | Remove-Item $tempFile -Force 110 | 111 | # _MSC_VER expands to a number like 1940 for MSVC 14.40. 112 | $ParsedMSVCVersion = [System.Version]::Parse($env:TEST_MSVC_VERSION) 113 | $ExpectedVersion = ($ParsedMSVCVersion.Major + 5) * 100 + $ParsedMSVCVersion.Minor 114 | if ($lastLine -eq $ExpectedVersion) { 115 | Write-Output "✅ cl.exe reports expected _MSC_VER `"${ExpectedVersion}`"." 116 | } else { 117 | Write-Output "::error::Unexpected MSVC version found: `"${lastLine}`" (expected: `"${ExpectedVersion}`")." 118 | $HasError = $true 119 | } 120 | 121 | # Check that the Windows SDK version is set in the environment. 122 | if ($env:UCRTVersion -eq $env:TEST_WIN_SDK_VERSION) { 123 | Write-Output "✅ UCRTVersion environment variable is set to `"${env:TEST_WIN_SDK_VERSION}`"." 124 | } else { 125 | Write-Output "::error::UCRTVersion environment variable (`"${env:UCRTVersion}`") is not set to the expected Windows SDK version (`"${env:TEST_WIN_SDK_VERSION}`")." 126 | $HasError = $true 127 | } 128 | 129 | if ($HasError) { 130 | Write-Output "::error::There were errors in the environment setup. Check the logs for details." 131 | exit 1 132 | } else { 133 | Write-Output "🎉 All environment checks passed successfully." 134 | } 135 | 136 | test-setup-build-windows-no-dev-env: 137 | name: MSVC + WinSDK No Dev Environment 138 | runs-on: ${{ inputs.windows-runner || 'windows-latest' }} 139 | steps: 140 | - name: Checkout 141 | uses: actions/checkout@v4.2.2 142 | 143 | - name: Set up build 144 | id: setup-build 145 | uses: ./.github/actions/setup-build 146 | with: 147 | windows-sdk-version: ${{ env.TEST_WIN_SDK_VERSION }} 148 | msvc-version: ${{ env.TEST_MSVC_VERSION }} 149 | setup-vs-dev-env: false 150 | 151 | - name: Check environment 152 | run: | 153 | $HasError = $false 154 | 155 | $ParsedWinSdkVersion = [System.Version]::Parse($env:TEST_WIN_SDK_VERSION) 156 | $Win10SdkRoot = Get-ItemPropertyValue ` 157 | -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots" ` 158 | -Name "KitsRoot10" 159 | $Win10SdkInclude = Join-Path $Win10SdkRoot "Include" 160 | 161 | # Check if the Windows SDK version is installed. 162 | $ExpectedWinSdkDir = Join-Path $Win10SdkInclude "$($env:TEST_WIN_SDK_VERSION)" 163 | if (Test-Path -Path $ExpectedWinSdkDir) { 164 | Write-Output "✅ Windows SDK version `"${env:TEST_WIN_SDK_VERSION}`" is installed." 165 | } else { 166 | Write-Output "::error::Expected Windows SDK version not found: `"${env:TEST_WIN_SDK_VERSION}`"." 167 | $HasError = $true 168 | } 169 | 170 | # Check if Windows SDK versions greater than the expected version are installed. 171 | $UnexpectedSdkFound = $false 172 | Get-ChildItem -Path $Win10SdkInclude -Directory | ForEach-Object { 173 | $Version = $_.Name 174 | try { 175 | $ParsedVersion = [System.Version]::Parse($Version) 176 | if ($ParsedVersion -gt $ParsedWinSdkVersion) { 177 | Write-Output "::error::Unexpected Windows SDK version found: `"${Version}`" (greater than expected: `"${env:TEST_WIN_SDK_VERSION}`")." 178 | $HasError = $true 179 | $UnexpectedSdkFound = $true 180 | } 181 | } catch { 182 | # Skip if the directory cannot be parsed as a version. 183 | } 184 | } 185 | if (-not $UnexpectedSdkFound) { 186 | Write-Output "✅ No unexpected Windows SDK versions greater than `"${env:TEST_WIN_SDK_VERSION}`" found." 187 | } 188 | 189 | # Check the action output. 190 | $BuildToolsVersion = "${{ steps.setup-build.outputs.windows-build-tools-version }}" 191 | if ($BuildToolsVersion -ne $env:TEST_BUILD_TOOLS_EXPECTED_VERSION) { 192 | Write-Output "::error::Expected build tools version `"${env:TEST_BUILD_TOOLS_EXPECTED_VERSION}`", but got `"${BuildToolsVersion}`"." 193 | $HasError = $true 194 | } else { 195 | Write-Output "✅ Build tools version `"${BuildToolsVersion}`" matches expected version." 196 | } 197 | 198 | # Check if the correct MSVC version is installed. 199 | $InstallerLocation = Join-Path "${env:ProgramFiles(x86)}" "Microsoft Visual Studio" "Installer" 200 | $VSWhere = Join-Path "${InstallerLocation}" "vswhere.exe" 201 | $InstallPath = (& "$VSWhere" -latest -products * -format json | ConvertFrom-Json).installationPath 202 | $MSVCDir = Join-Path $InstallPath "VC" "Tools" "MSVC" $BuildToolsVersion 203 | if (Test-Path -Path $MSVCDir) { 204 | Write-Output "✅ MSVC version `"${env:TEST_MSVC_VERSION}`" is installed." 205 | } else { 206 | Write-Output "::error::MSVC directory not found: `"${MSVCDir}`"." 207 | $HasError = $true 208 | } 209 | 210 | # Check that cl.exe was not set. 211 | $CLExe = Get-Command -Name cl.exe -ErrorAction Ignore 212 | if ($CLExe) { 213 | Write-Output "::error::cl.exe was unexpectedly found in the PATH: `"${CLExe.Path}`"." 214 | $HasError = $true 215 | } else { 216 | Write-Output "✅ cl.exe is not set in the PATH, as expected." 217 | } 218 | 219 | # Check that the VS Dev Environment was not set. 220 | if ($env:UCRTVersion) { 221 | Write-Output "::error::UCRTVersion environment variable was set to `"${env:UCRTVersion}`"." 222 | $HasError = $true 223 | } else { 224 | Write-Output "✅ UCRTVersion environment variable is set to `"${env:TEST_WIN_SDK_VERSION}`"." 225 | } 226 | 227 | if ($HasError) { 228 | Write-Output "::error::There were errors in the environment setup. Check the logs for details." 229 | exit 1 230 | } else { 231 | Write-Output "🎉 All environment checks passed successfully." 232 | } 233 | 234 | test-incorrect-windows-sdk-version: 235 | name: Incorrect Windows SDK Version 236 | runs-on: ${{ inputs.windows-runner || 'windows-latest' }} 237 | steps: 238 | - name: Checkout 239 | uses: actions/checkout@v4.2.2 240 | 241 | - name: Set up build with incorrect Windows SDK version 242 | id: setup-build 243 | uses: ./.github/actions/setup-build 244 | with: 245 | windows-sdk-version: "99.99.9999.0" # Intentionally incorrect version 246 | continue-on-error: true 247 | 248 | - name: Download log file 249 | uses: actions/download-artifact@v4 250 | with: 251 | name: ${{ github.job }}-windows-sdk-installer-log 252 | path: ${{ github.workspace }}/windows-sdk-installer-log 253 | 254 | - name: Check the log file existence 255 | run: | 256 | $LogFile = Get-ChildItem -Path "${{ github.workspace }}/windows-sdk-installer-log" 257 | if (-Not (Test-Path -Path $LogFile)) { 258 | Write-Output "::error::Log file not found." 259 | exit 1 260 | } else { 261 | Write-Output "✅ Log file found. File contents:" 262 | Get-Content -Path "$LogFile" 263 | } 264 | 265 | test-incorrect-msvc-version: 266 | name: Incorrect MSVC Version 267 | runs-on: ${{ inputs.windows-runner || 'windows-latest' }} 268 | steps: 269 | - name: Checkout 270 | uses: actions/checkout@v4.2.2 271 | 272 | - name: Set up build with incorrect MSVC version 273 | id: setup-build 274 | uses: ./.github/actions/setup-build 275 | with: 276 | msvc-version: "14.99" # Intentionally incorrect version 277 | continue-on-error: true 278 | 279 | - name: Download log file 280 | uses: actions/download-artifact@v4 281 | with: 282 | name: ${{ github.job }}-msvc-installer-log 283 | path: ${{ github.workspace }}/msvc-installer-log 284 | 285 | - name: Check the log file existence 286 | run: | 287 | $LogFile = Get-ChildItem -Path "${{ github.workspace }}/msvc-installer-log" 288 | if (-Not (Test-Path -Path $LogFile)) { 289 | Write-Output "::error::Log file not found." 290 | exit 1 291 | } else { 292 | Write-Output "✅ Log file found. File contents:" 293 | Get-Content -Path "$LogFile" 294 | } 295 | 296 | test-upstream-swift-install: 297 | name: Upstream Swift Installation 298 | runs-on: ${{ inputs.windows-runner || 'windows-latest' }} 299 | steps: 300 | - name: Checkout 301 | uses: actions/checkout@v4.2.2 302 | 303 | - name: Set up build with upstream Swift 304 | id: setup-build 305 | uses: ./.github/actions/setup-build 306 | with: 307 | swift-version: ${{ env.TEST_UPSTREAM_SWIFT_VERSION }} 308 | 309 | - name: Check Swift installation 310 | run: | 311 | $SwiftVersion = & swift --version 312 | if ($SwiftVersion -match "Swift version ${env:TEST_UPSTREAM_SWIFT_VERSION}") { 313 | Write-Output "✅ Upstream Swift version `"$env:TEST_UPSTREAM_SWIFT_VERSION`" is installed." 314 | } else { 315 | Write-Output "::error::Expected to find Swift version `"$env:TEST_UPSTREAM_SWIFT_VERSION`" in output:" 316 | Write-Output "$SwiftVersion" 317 | exit 1 318 | } 319 | 320 | test-bcny-swift-install: 321 | name: BCNY Swift Installation 322 | runs-on: ${{ inputs.windows-runner || 'windows-latest' }} 323 | steps: 324 | - name: Checkout 325 | uses: actions/checkout@v4.2.2 326 | - name: Set up build with BCNY Swift 327 | id: setup-build 328 | uses: ./.github/actions/setup-build 329 | with: 330 | swift-version: ${{ env.TEST_BCNY_SWIFT_VERSION }} 331 | swift-repo: ${{ env.TEST_BCNY_SWIFT_REPO }} 332 | 333 | - name: Check Swift installation 334 | run: | 335 | # Get the expected Swift version from the environment variable (i.e. "6.0" for "6.0.0-20241216.0") 336 | $ExpectedSwiftVersion = ${env:TEST_BCNY_SWIFT_VERSION} -replace '-.*$', '' | ForEach-Object { ($_ -split '\.')[0..1] -join '.' } 337 | $SwiftVersionOutput = & swift --version 338 | if (${SwiftVersionOutput} -match "Swift version ${ExpectedSwiftVersion}") { 339 | Write-Output "✅ BCNY Swift version `"${env:TEST_BCNY_SWIFT_VERSION}`" is installed." 340 | } else { 341 | Write-Output "::error::Expected to find Swift version `"${ExpectedSwiftVersion}`" in output:" 342 | Write-Output "${SwiftVersionOutput}" 343 | exit 1 344 | } 345 | -------------------------------------------------------------------------------- /.github/actions/setup-build/action.yml: -------------------------------------------------------------------------------- 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 | swift-version: 26 | description: The Swift version to use, e.g. "6.0.1" for the upstream Apple Swift repository. 27 | Or "6.0.0-20261216.0" for a specific snapshot from another repository. 28 | If unspecified, the Swift toolchain is not set up. 29 | required: false 30 | type: string 31 | swift-repo: 32 | description: | 33 | The Swift repository to use, e.g. "thebrowsercompany/swift-build". If unspecified, and 34 | `swift-version` is specified, the upstream Apple Swift repository is used. 35 | required: false 36 | type: string 37 | 38 | outputs: 39 | windows-build-tools-version: 40 | description: | 41 | The full version of the Windows build tools installed, eg. "14.42.34433". This is only set 42 | if the `msvc-version` input was provided, and only on Windows. 43 | value: ${{ steps.setup-msvc.outputs.windows-build-tools-version }} 44 | 45 | runs: 46 | using: composite 47 | steps: 48 | - name: Sanitize input 49 | id: sanitize-input 50 | shell: pwsh 51 | run: | 52 | if ($IsWindows) { 53 | $BuildOS = "windows" 54 | } elseif ($IsMacOS) { 55 | $BuildOS = "macosx" 56 | } else { 57 | Write-Output "::error::Unsupported build OS." 58 | exit 1 59 | } 60 | 61 | $Arch = ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture).ToString() 62 | switch ($Arch) { 63 | "X64" { $BuildArch = "amd64" } 64 | "Arm64" { $BuildArch = "arm64" } 65 | default { 66 | Write-Output "::error::Unsupported build architecture: `"$Arch`"" 67 | exit 1 68 | } 69 | } 70 | 71 | # Validate the MSVC version input. 72 | # If specified, it is expected to have a format "major.minor", without the build and 73 | # revision numbers. When a value such as "14.42" is parsed as a `System.Version`, the build 74 | # and revision numbers in that object are set to -1. 75 | $MSVCVersion = "${{ inputs.msvc-version }}" 76 | if ($MSVCVersion -ne "") { 77 | $ParsedMSVCVersion = [System.Version]::Parse($MSVCVersion) 78 | if ($ParsedMSVCVersion -eq $null) { 79 | Write-Output "::error::Invalid Windows MSVC version: `"${MSVCVersion}`"." 80 | exit 1 81 | } 82 | if ($ParsedMSVCVersion.Major -ne 14) { 83 | Write-Output "::error::Unsupported Windows MSVC version (major version not supported): `"${MSVCVersion}`"." 84 | exit 1 85 | } 86 | if ($ParsedMSVCVersion.Build -ne -1) { 87 | Write-Output "::error::Unsupported Windows MSVC version (build version was specified): `"${MSVCVersion}`"." 88 | exit 1 89 | } 90 | if ($ParsedMSVCVersion.Revision -ne -1) { 91 | Write-Output "::error::Unsupported Windows MSVC version (revision version was specified): `"${MSVCVersion}`"." 92 | exit 1 93 | } 94 | } 95 | 96 | if ("${{ inputs.setup-vs-dev-env }}" -eq "true") { 97 | switch ("${{ inputs.host-arch }}") { 98 | "x86" { $HostArch = "x86" } 99 | "amd64" { $HostArch = "amd64" } 100 | "arm64" { $HostArch = "arm64" } 101 | "" { $HostArch = $BuildArch } 102 | default { 103 | Write-Output "::error::Unsupported host architecture: `"${{ inputs.host-arch }}`"" 104 | exit 1 105 | } 106 | } 107 | } else { 108 | $HostArch = $BuildArch 109 | } 110 | 111 | ${SwiftVersion} = "${{ inputs.swift-version }}" 112 | ${SwiftRepo} = "${{ inputs.swift-repo }}" 113 | if ($SwiftRepo -ne "" -and $SwiftVersion -eq "") { 114 | Write-Output "::error::The `swift-repo` input was specified, but the `swift-version` input was not. Please specify a Swift toolchain version to use." 115 | exit 1 116 | } 117 | 118 | Write-Output "ℹ️ Build OS: $BuildOS" 119 | Write-Output "ℹ️ Build architecture: $BuildArch" 120 | Write-Output "ℹ️ Host architecture: $HostArch" 121 | 122 | # Derive the Swift version and repository from the inputs. 123 | if ($SwiftVersion -ne "") { 124 | if ($SwiftRepo -eq "") { 125 | $SwiftBranch = "swift-${SwiftVersion}-release" 126 | $SwiftTag = "${SwiftVersion}-RELEASE" 127 | Write-Output "ℹ️ Using upstream Swift toolchain: $SwiftVersion (branch: $SwiftBranch, tag: $SwiftTag)" 128 | } else { 129 | # Note: This only supports Windows for now. 130 | $SwiftReleaseAssetName = "installer-${BuildArch}.exe" 131 | $SwiftReleaseTagName = "swift-${SwiftVersion}" 132 | Write-Output "ℹ️ Using custom Swift toolchain: $SwiftVersion (repository: $SwiftRepo, tag: $SwiftReleaseTagName, asset: $SwiftReleaseAssetName)" 133 | } 134 | } 135 | 136 | @" 137 | build-os=$BuildOS 138 | build-arch=$BuildArch 139 | host-arch=$HostArch 140 | swift-branch=$SwiftBranch 141 | swift-tag=$SwiftTag 142 | swift-release-asset=$SwiftReleaseAssetName 143 | swift-release-tag=$SwiftReleaseTagName 144 | "@ | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append 145 | 146 | - name: Install Windows SDK version ${{ inputs.windows-sdk-version }} 147 | if: steps.sanitize-input.outputs.build-os == 'windows' && inputs.windows-sdk-version != '' 148 | id: setup-windows-sdk 149 | shell: pwsh 150 | run: | 151 | $WinSdkVersionString = "${{ inputs.windows-sdk-version }}" 152 | $WinSdkVersion = [System.Version]::Parse($WinSdkVersionString) 153 | $WinSdkVersionBuild = $WinSdkVersion.Build 154 | 155 | $Win10SdkRoot = Get-ItemPropertyValue ` 156 | -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots" ` 157 | -Name "KitsRoot10" 158 | $Win10SdkLib = Join-Path $Win10SdkRoot "Lib" 159 | $Win10SdkInclude = Join-Path $Win10SdkRoot "Include" 160 | $Win10SdkIncludeVersion = Join-Path $Win10SdkInclude $WinSdkVersionString 161 | 162 | if (Test-Path -Path $Win10SdkIncludeVersion -PathType Container) { 163 | Write-Output "ℹ️ MSVCPackageVersionWindows SDK ${WinSdkVersionString} already installed." 164 | } else { 165 | # Install the missing SDK. 166 | Write-Output "ℹ️ Installing Windows SDK ${WinSdkVersionString}..." 167 | 168 | $InstallerLocation = Join-Path "${env:ProgramFiles(x86)}" "Microsoft Visual Studio" "Installer" 169 | $VSWhere = Join-Path "${InstallerLocation}" "VSWhere.exe" 170 | $VSInstaller = Join-Path "${InstallerLocation}" "vs_installer.exe" 171 | $InstallPath = (& "$VSWhere" -latest -products * -format json | ConvertFrom-Json).installationPath 172 | $process = Start-Process "$VSInstaller" ` 173 | -PassThru ` 174 | -ArgumentList "modify", ` 175 | "--noUpdateInstaller", ` 176 | "--installPath", "`"$InstallPath`"", ` 177 | "--channelId", "https://aka.ms/vs/17/release/channel", ` 178 | "--quiet", "--norestart", "--nocache", ` 179 | "--add", "Microsoft.VisualStudio.Component.Windows11SDK.${WinSdkVersionBuild}" 180 | $process.WaitForExit() 181 | 182 | if (Test-Path -Path $Win10SdkIncludeVersion -PathType Container) { 183 | Write-Output "ℹ️ Windows SDK ${WinSdkVersionString} installed successfully." 184 | } else { 185 | Write-Output "::error::Failed to install Windows SDK ${WinSdkVersionString}. Check the installer log for details." 186 | $LogFile = Get-ChildItem "${env:TEMP}" -Filter "dd_installer_*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1 187 | "log-file=$($LogFile.FullName)" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append 188 | exit 1 189 | } 190 | } 191 | 192 | # Remove more recent Windows SDKs, if present. This is used to work 193 | # around issues where LLVM uses the most recent Windows SDK. 194 | # This should be removed once a more permanent solution is found. 195 | # See https://github.com/compnerd/swift-build/issues/958 for details. 196 | Get-ChildItem -Path $Win10SdkInclude -Directory | ForEach-Object { 197 | $IncludeDirName = $_.Name 198 | try { 199 | $IncludeDirVersion = [System.Version]::Parse($IncludeDirName) 200 | if ($IncludeDirVersion -gt $WinSdkVersion) { 201 | $LibDirVersion = Join-Path $Win10SdkLib $IncludeDirName 202 | Write-Output "ℹ️ Removing folders for Windows SDK ${IncludeDirVersion}." 203 | Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction Ignore 204 | Remove-Item -Path $LibDirVersion -Recurse -Force -ErrorAction Ignore 205 | } 206 | } catch { 207 | # Skip if the directory cannot be parsed as a version. 208 | } 209 | } 210 | 211 | - name: Upload installer log 212 | if: always() && steps.setup-windows-sdk.outputs.log-file != '' 213 | uses: actions/upload-artifact@v4 214 | with: 215 | name: ${{ github.job }}-windows-sdk-installer-log 216 | path: ${{ steps.setup-windows-sdk.outputs.log-file }} 217 | 218 | - name: Install Windows MSVC version ${{ inputs.msvc-version }} 219 | if: steps.sanitize-input.outputs.build-os == 'windows' && inputs.msvc-version != '' 220 | id: setup-msvc 221 | shell: pwsh 222 | run: | 223 | # This is assuming a VS2022 toolchain. e.g. 224 | # MSVC 14.42 corresponds to the 14.42.17.12 package. 225 | # MSVC 14.43 corresponds to the 14.43.17.13 package. 226 | $MSVCVersionString = "${{ inputs.msvc-version }}" 227 | 228 | $InstallerLocation = Join-Path "${env:ProgramFiles(x86)}" "Microsoft Visual Studio" "Installer" 229 | $VSWhere = Join-Path "${InstallerLocation}" "VSWhere.exe" 230 | $VSInstaller = Join-Path "${InstallerLocation}" "vs_installer.exe" 231 | $VSWhereJSON = (& "$VSWhere" -latest -products * -format json | ConvertFrom-Json) 232 | $InstallPath = $VSWhereJSON.installationPath 233 | $ProductID = $VSWhereJSON.productId 234 | $MSVCDir = Join-Path $InstallPath "VC" "Tools" "MSVC" 235 | 236 | # Compute the MSVC version package name from the MSVC version, assuming this is coming from 237 | # a VS2022 installation. The version package follows the following format: 238 | # * Major and minor version are the same as the MSVC version. 239 | # * Build version is always 17 (VS2002 is VS17). 240 | # * The revision is set to the number of minor versions since VS17 release. 241 | $MSVCVersion = [System.Version]::Parse($MSVCVersionString) 242 | $MajorVersion = $MSVCVersion.Major 243 | $MinorVersion = $MSVCVersion.Minor 244 | $BuildVersion = 17 245 | $RevisionVersion = $MinorVersion - 30 246 | $MSVCPackageVersion = "${MajorVersion}.${MinorVersion}.${BuildVersion}.${RevisionVersion}" 247 | 248 | # Download the latest VS Installer to update the VS Installer installation. This is needed 249 | # due to a bug in the VS Installer that causes it to fail to self-update. For details, see 250 | # https://developercommunity.visualstudio.com/t/Visual-Studio-Installer-randomly-fails-t/10924708 251 | $VSInstallerURI = switch ($ProductID) { 252 | "Microsoft.VisualStudio.Product.Community" { 253 | "https://aka.ms/vs/17/release/vs_community.exe" 254 | } 255 | "Microsoft.VisualStudio.Product.Enterprise" { 256 | "https://aka.ms/vs/17/release/vs_enterprise.exe" 257 | } 258 | "Microsoft.VisualStudio.Product.Professional" { 259 | "https://aka.ms/vs/17/release/vs_professional.exe" 260 | } 261 | "Microsoft.VisualStudio.Product.BuildTools" { 262 | "https://aka.ms/vs/17/release/vs_buildtools.exe" 263 | } 264 | default { 265 | Write-Output "::error::Unsupported Visual Studio product ID: $ProductID" 266 | exit 1 267 | } 268 | } 269 | $VSProductInstaller = Join-Path "${env:TEMP}" "vs_installer.exe" 270 | Invoke-WebRequest $VSInstallerURI -OutFile $VSProductInstaller -ErrorAction Stop 271 | 272 | Write-Output "ℹ️ Updating Visual Studio Installer..." 273 | $process = Start-Process "$VSProductInstaller" ` 274 | -PassThru ` 275 | -ArgumentList "--update", "--quiet", "--wait" 276 | $process.WaitForExit() 277 | 278 | # Install the missing MSVC version. 279 | Write-Output "ℹ️ Installing MSVC packages for ${MSVCPackageVersion}..." 280 | $process = Start-Process "$VSInstaller" ` 281 | -PassThru ` 282 | -ArgumentList "modify", ` 283 | "--installPath", "`"$InstallPath`"", ` 284 | "--channelId", "https://aka.ms/vs/17/release/channel", ` 285 | "--quiet", "--norestart", "--nocache", ` 286 | "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.x86.x64", ` 287 | "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.ATL", ` 288 | "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.ARM64", ` 289 | "--add", "Microsoft.VisualStudio.Component.VC.${MSVCPackageVersion}.ATL.ARM64" 290 | $process.WaitForExit() 291 | 292 | # Check if the MSVC version was installed successfully. 293 | $MSVCBuildToolsVersion = "" 294 | foreach ($dir in Get-ChildItem -Path $MSVCDir -Directory) { 295 | $MSVCDirName = $dir.Name 296 | if ($MSVCDirName.StartsWith($MSVCVersionString)) { 297 | Write-Output "ℹ️ MSVC ${MSVCVersionString} installed successfully." 298 | $MSVCBuildToolsVersion = $MsvcDirName 299 | break 300 | } 301 | } 302 | 303 | if ($MSVCBuildToolsVersion -eq "") { 304 | Write-Output "::error::Failed to install MSVC ${MSVCVersionString}. Check the installer log for details." 305 | $LogFile = Get-ChildItem "${env:TEMP}" -Filter "dd_installer_*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1 306 | "log-file=$($LogFile.FullName)" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append 307 | exit 1 308 | } else { 309 | Write-Output "ℹ️ MSVC ${MSVCBuildToolsVersion} installed successfully." 310 | "windows-build-tools-version=${MSVCBuildToolsVersion}" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append 311 | } 312 | 313 | - name: Upload installer log 314 | if: always() && steps.setup-msvc.outputs.log-file != '' 315 | uses: actions/upload-artifact@v4 316 | with: 317 | name: ${{ github.job }}-msvc-installer-log 318 | path: ${{ steps.setup-msvc.outputs.log-file }} 319 | 320 | - name: Setup Visual Studio Developer Environment 321 | if: steps.sanitize-input.outputs.build-os == 'windows' && inputs.setup-vs-dev-env == 'true' 322 | uses: compnerd/gha-setup-vsdevenv@5eb3eae1490d4f7875d574c4973539f69109700d # main 323 | with: 324 | host_arch: ${{ steps.sanitize-input.outputs.build-arch }} 325 | arch: ${{ steps.sanitize-input.outputs.host-arch }} 326 | winsdk: ${{ inputs.windows-sdk-version }} 327 | toolset_version: ${{ inputs.msvc-version }} 328 | 329 | - name: Setup Swift toolchain (Upstream) 330 | if: inputs.swift-version != '' && inputs.swift-repo == '' 331 | uses: compnerd/gha-setup-swift@main 332 | with: 333 | cache: 'true' 334 | source: 'swift.org' 335 | swift-version: ${{ steps.sanitize-input.outputs.swift-branch }} 336 | swift-build: ${{ steps.sanitize-input.outputs.swift-tag }} 337 | 338 | - name: Setup Swift toolchain (Custom) 339 | if: inputs.swift-version != '' && inputs.swift-repo != '' 340 | uses: compnerd/gha-setup-swift@main 341 | with: 342 | cache: 'true' 343 | source: 'custom' 344 | github-repo: ${{ inputs.swift-repo }} 345 | github-token: ${{ github.token }} 346 | release-asset-name: ${{ steps.sanitize-input.outputs.swift-release-asset }} 347 | release-tag-name: ${{ steps.sanitize-input.outputs.swift-release-tag }} 348 | 349 | - name: Update Swift toolchain module maps 350 | if: steps.sanitize-input.outputs.build-os == 'windows' && inputs.swift-version != '' 351 | shell: pwsh 352 | run: | 353 | $SwiftBinFolder = Split-Path -Path (Get-Command swift).Source -Parent 354 | $SwiftUsrFolder = Split-Path -Path $SwiftBinFolder -Parent 355 | $SwiftClangIncludeFolder = Join-Path $SwiftUsrFolder "lib" "swift" "clang" "include" 356 | $SwiftClangModuleMap = Join-Path $SwiftClangIncludeFolder "module.modulemap" 357 | curl -s ` 358 | -H "Authorization: Bearer ${{ github.token }}" ` 359 | https://raw.githubusercontent.com/llvm/llvm-project/main/clang/lib/Headers/module.modulemap ` 360 | -o SwiftClangModuleMap 361 | if ($LASTEXITCODE -eq 0) { 362 | Write-Output "ℹ️ Updated Swift Clang module map." 363 | } else { 364 | Write-Output "::error::Failed to update Swift Clang module map. curl failed with exit code $LASTEXITCODE." 365 | exit 1 366 | } 367 | 368 | $WindowsSdkShareFolder = Join-Path ${env:SDKROOT} "usr" "share" 369 | 370 | $WinSdkModuleMap = Join-Path $WindowsSdkShareFolder "winsdk.modulemap" 371 | curl -s ` 372 | -H "Authorization: Bearer ${{ github.token }}" ` 373 | https://raw.githubusercontent.com/swiftlang/swift/main/stdlib/public/Platform/winsdk_um.modulemap ` 374 | -o $WinSdkModuleMap 375 | if ($LASTEXITCODE -eq 0) { 376 | Write-Output "ℹ️ Updated Windows SDK module map." 377 | } else { 378 | Write-Output "::error::Failed to update Windows SDK module map. curl failed with exit code $LASTEXITCODE." 379 | exit 1 380 | } 381 | 382 | $UCRTModuleMap = Join-Path $WindowsSdkShareFolder "ucrt.modulemap" 383 | curl -s ` 384 | -H "Authorization: Bearer ${{ github.token }}" ` 385 | https://raw.githubusercontent.com/swiftlang/swift/main/stdlib/public/Platform/ucrt.modulemap ` 386 | -o $UCRTModuleMap 387 | if ($LASTEXITCODE -eq 0) { 388 | Write-Output "ℹ️ Updated UCRT module map." 389 | } else { 390 | Write-Output "::error::Failed to update UCRT module map. curl failed with exit code $LASTEXITCODE." 391 | exit 1 392 | } 393 | 394 | $VCRuntimeModuleMap = Join-Path $WindowsSdkShareFolder "vcruntime.modulemap" 395 | curl -s ` 396 | -H "Authorization: Bearer ${{ github.token }}" ` 397 | https://raw.githubusercontent.com/swiftlang/swift/main/stdlib/public/Platform/vcruntime.modulemap ` 398 | -o $VCRuntimeModuleMap 399 | if ($LASTEXITCODE -eq 0) { 400 | Write-Output "ℹ️ Updated VCRuntime module map." 401 | } else { 402 | Write-Output "::error::Failed to update VCRuntime module map. curl failed with exit code $LASTEXITCODE." 403 | exit 1 404 | } 405 | -------------------------------------------------------------------------------- /.github/actions/configure-cmake-project/action.yml: -------------------------------------------------------------------------------- 1 | name: Configure CMake Project 2 | description: Configure a CMake project using the specified build type and configuration. 3 | 4 | inputs: 5 | project-name: 6 | description: Name of the CMake project to build. 7 | required: true 8 | swift-version: 9 | description: Built Swift compiler version. 10 | required: true 11 | enable-caching: 12 | description: Enable sccache. 13 | required: false 14 | default: false 15 | debug-info: 16 | description: Enable debug information in the build. 17 | required: false 18 | default: false 19 | build-os: 20 | description: Build operating system (e.g., "Windows", "Darwin"). 21 | required: true 22 | build-arch: 23 | description: Build architecture (e.g., "x86_64", "arm64"). 24 | required: true 25 | os: 26 | description: Operating system to build for (e.g., "Windows", "Android"). 27 | required: true 28 | arch: 29 | description: Architecture to build for (e.g., "amd64", "arm64"). 30 | required: true 31 | src-dir: 32 | description: Path to the source directory of the CMake project. 33 | required: true 34 | bin-dir: 35 | description: Path to the output directory for the build artifacts. 36 | required: true 37 | install-dir: 38 | description: Path to the installation directory for the built artifacts. 39 | required: false 40 | default: '' 41 | android-api-level: 42 | description: Android API level to target. 43 | required: false 44 | default: '' 45 | android-clang-version: 46 | description: Version of the Android Clang toolchain to use. 47 | required: false 48 | default: '' 49 | ndk-path: 50 | description: Path to the Android NDK. 51 | required: false 52 | default: '' 53 | swift-sdk-path: 54 | description: Path to the Swift SDK. 55 | required: false 56 | default: '' 57 | msvc-compilers: 58 | description: List of languages to build with the MSVC compilers (e.g. "C", "CXX", "ASM_MASM"). 59 | required: false 60 | default: '@()' 61 | built-compilers: 62 | description: | 63 | List of languages to build with the built compilers (e.g. "C", "CXX", "ASM", "Swift"). 64 | required: false 65 | default: '@()' 66 | pinned-compilers: 67 | description: | 68 | List of languages to build with the pinned compilers (e.g. "C", "CXX", "ASM", "Swift"). 69 | required: false 70 | default: '@()' 71 | use-gnu-driver: 72 | description: Use the GNU driver for building the project. 73 | required: false 74 | default: false 75 | cache-script: 76 | description: Optional path to a CMake Cache file. 77 | required: false 78 | default: '' 79 | cmake-defines: 80 | description: | 81 | Additional CMake definitions to pass to the build system (e.g. "CMAKE_BUILD_TYPE=Release"). 82 | required: false 83 | default: '@{}' 84 | 85 | runs: 86 | using: 'composite' 87 | steps: 88 | - name: Configure ${{ inputs.project-name }} 89 | shell: pwsh 90 | run: | 91 | Remove-Item env:\SDKROOT -ErrorAction SilentlyContinue 92 | $ExeSuffix = if ($IsWindows) { ".exe" } else { "" } 93 | 94 | $ProjectName = '${{ inputs.project-name }}' 95 | $SwiftVersion = '${{ inputs.swift-version }}' 96 | $EnableCaching = ${{ inputs.enable-caching == 'true' && '$True' || '$False' }} 97 | $DebugInfo = ${{ inputs.debug-info == 'true' && '$True' || '$False' }} 98 | $BuildOS = '${{ inputs.build-os }}' 99 | $BuildArch = '${{ inputs.build-arch }}' 100 | $OS = '${{ inputs.os }}' 101 | $Arch = '${{ inputs.arch }}' 102 | $SrcDir = '${{ inputs.src-dir }}' 103 | $BinDir = '${{ inputs.bin-dir }}' 104 | $InstallDir = '${{ inputs.install-dir }}' 105 | $AndroidAPILevel = '${{ inputs.android-api-level }}' 106 | $AndroidClangVersion = '${{ inputs.android-clang-version }}' 107 | $NDKPath = '${{ inputs.ndk-path }}' 108 | $SwiftSDK = '${{ inputs.swift-sdk-path }}' 109 | $UseMSVCCompilers = ${{ inputs.msvc-compilers }} 110 | $UseBuiltCompilers = ${{ inputs.built-compilers }} 111 | $UsePinnedCompilers = ${{ inputs.pinned-compilers }} 112 | $UseGNUDriver = ${{ inputs.use-gnu-driver == 'true' && '$True' || '$False' }} 113 | $CacheScript = '${{ inputs.cache-script }}' 114 | $CMakeDefines = ${{ inputs.cmake-defines }} 115 | 116 | function Add-KeyValueIfNew([hashtable]$Hashtable, [string]$Key, [string]$Value) { 117 | if (-not $Hashtable.Contains($Key)) { 118 | $Hashtable.Add($Key, $Value) 119 | } 120 | } 121 | 122 | function Add-FlagsDefine([hashtable]$Defines, [string]$Name, [string[]]$Value) { 123 | if ($Defines.Contains($Name)) { 124 | $Defines[$name] = @($Defines[$name]) + $Value 125 | } else { 126 | $Defines.Add($Name, $Value) 127 | } 128 | } 129 | 130 | $CMakeArch = switch ($OS) { 131 | 'Windows' { 132 | switch ($Arch) { 133 | 'arm64' { 'ARM64' } 134 | 'amd64' { 'AMD64' } 135 | 'x86' { 'i686' } 136 | default { throw "Unsupported Windows architecture: $Arch" } 137 | } 138 | } 139 | 'Android' { 140 | switch ($Arch) { 141 | 'arm64' { 'aarch64' } 142 | 'x86_64' { 'x86_64' } 143 | 'i686' { 'i686' } 144 | 'armv7' { 'armv7-a' } 145 | default { throw "Unsupported Android architecture: $Arch" } 146 | } 147 | } 148 | "Darwin" { $Arch } 149 | default { throw "Unsupported OS: $OS" } 150 | } 151 | 152 | $Triple = switch ($OS) { 153 | 'Windows' { 154 | switch ($Arch) { 155 | 'x86' { "i686-unknown-windows-msvc" } 156 | 'amd64' { "x86_64-unknown-windows-msvc" } 157 | 'arm64' { "aarch64-unknown-windows-msvc" } 158 | default { throw "Unsupported Windows architecture: $Arch" } 159 | } 160 | } 161 | 'Android' { 162 | switch ($Arch) { 163 | 'i686' { "i686-unknown-linux-android${AndroidAPILevel}" } 164 | 'x86_64' { "x86_64-unknown-linux-android${AndroidAPILevel}" } 165 | 'armv7' { "armv7-unknown-linux-androideabi${AndroidAPILevel}" } 166 | 'arm64' { "aarch64-unknown-linux-android${AndroidAPILevel}" } 167 | default { throw "Unsupported Android architecture: $Arch" } 168 | } 169 | } 170 | 'Darwin' { "${Arch}-apple-macosx15.0" } 171 | default { throw "Unsupported OS: $OS" } 172 | } 173 | 174 | $UseASM = $UseBuiltCompilers.Contains("ASM") -or $UsePinnedCompilers.Contains("ASM") 175 | $UseASM_MASM = $UseMSVCCompilers.Contains("ASM_MASM") 176 | $UseC = $UseBuiltCompilers.Contains("C") -or $UseMSVCCompilers.Contains("C") -or $UsePinnedCompilers.Contains("C") 177 | $UseCXX = $UseBuiltCompilers.Contains("CXX") -or $UseMSVCCompilers.Contains("CXX") -or $UsePinnedCompilers.Contains("CXX") 178 | $UseSwift = $UseBuiltCompilers.Contains("Swift") -or $UsePinnedCompilers.Contains("Swift") 179 | 180 | # Add additional defines (unless already present) 181 | $Defines = $CMakeDefines.Clone() 182 | 183 | Add-KeyValueIfNew $Defines CMAKE_BUILD_TYPE Release 184 | 185 | # Avoid specifying `CMAKE_SYSTEM_NAME` and `CMAKE_SYSTEM_PROCESSOR` on 186 | # Windows and in the case that we are not cross-compiling. 187 | if ($OS -ne $BuildOS -or $Arch -ne $BuildArch) { 188 | Add-KeyValueIfNew $Defines CMAKE_SYSTEM_NAME $OS 189 | Add-KeyValueIfNew $Defines CMAKE_SYSTEM_PROCESSOR $CMakeArch 190 | } 191 | 192 | # Always prefer the CONFIG format for the packages so that we can build 193 | # against the build tree. 194 | Add-KeyValueIfNew $Defines CMAKE_FIND_PACKAGE_PREFER_CONFIG YES 195 | 196 | switch ($OS) { 197 | 'Windows' { 198 | if ($UseASM) { 199 | $Driver = $(if ($UseGNUDriver) { "clang.exe" } else { "clang-cl.exe" }) 200 | $ASM = if ($UseBuiltCompilers.Contains("ASM")) { 201 | "${env:GITHUB_WORKSPACE}/BinaryCache/Library/Developer/Toolchains/${SwiftVersion}+Asserts/usr/bin/${Driver}" 202 | } elseif ($UsePinnedCompilers.Contains("ASM")) { 203 | # The pinned toolchain is already in the path. 204 | $Driver 205 | } 206 | 207 | Add-KeyValueIfNew $Defines CMAKE_ASM_COMPILER $ASM 208 | Add-KeyValueIfNew $Defines CMAKE_ASM_FLAGS @("--target=$Triple") 209 | Add-KeyValueIfNew $Defines CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "/MD" 210 | 211 | if ($DebugInfo) { 212 | $ASMDebugFlags = if ($UseGNUDriver) { @("-gcodeview") } else { @("-clang:-gcodeview") } 213 | 214 | # CMake does not set a default value for the ASM compiler debug 215 | # information format flags with non-MSVC compilers, so we explicitly 216 | # set a default here. 217 | Add-FlagsDefine $Defines CMAKE_ASM_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded $ASMDebugFlags 218 | } 219 | } 220 | 221 | if ($UseASM_MASM) { 222 | $ASM_MASM = if (${Arch} -eq "x86") { 223 | "ml.exe" 224 | } else { 225 | "ml64.exe" 226 | } 227 | 228 | Add-KeyValueIfNew $Defines CMAKE_ASM_MASM_COMPILER $ASM_MASM 229 | Add-KeyValueIfNew $Defines CMAKE_ASM_MASM_FLAGS @("/nologo" , "/quiet") 230 | } 231 | 232 | if ($UseC) { 233 | $CC = if ($UseMSVCCompilers.Contains("C")) { 234 | "cl.exe" 235 | } else { 236 | $Driver = $(if ($UseGNUDriver) { "clang.exe" } else { "clang-cl.exe" }) 237 | if ($UseBuiltCompilers.Contains("C")) { 238 | "${env:GITHUB_WORKSPACE}/BinaryCache/Library/Developer/Toolchains/${SwiftVersion}+Asserts/usr/bin/${Driver}" 239 | } elseif ($UsePinnedCompilers.Contains("C")) { 240 | # The pinned toolchain is already in the path. 241 | $Driver 242 | } 243 | } 244 | 245 | Add-KeyValueIfNew $Defines CMAKE_C_COMPILER $CC 246 | Add-KeyValueIfNew $Defines CMAKE_C_COMPILER_TARGET $Triple 247 | 248 | $CFLAGS = if ($UseGNUDriver) { 249 | # TODO(compnerd) we should consider enabling stack protector usage for standard libraries. 250 | @("-fno-stack-protector", "-ffunction-sections", "-fdata-sections", "-fomit-frame-pointer") 251 | } elseif ($UseMSVCCompilers.Contains("C")) { 252 | @("/GS-", "/Gw", "/Gy", "/Oy", "/Oi", "/Zc:preprocessor", "/Zc:inline") 253 | } else { 254 | # clang-cl does not support the /Zc:preprocessor flag. 255 | @("/GS-", "/Gw", "/Gy", "/Oy", "/Oi", "/Zc:inline") 256 | } 257 | 258 | Add-FlagsDefine $Defines CMAKE_C_FLAGS $CFLAGS 259 | } 260 | 261 | if ($UseCXX) { 262 | $CXX = if ($UseMSVCCompilers.Contains("CXX")) { 263 | "cl.exe" 264 | } else { 265 | $Driver = $(if ($UseGNUDriver) { "clang++.exe" } else { "clang-cl.exe" }) 266 | if ($UseBuiltCompilers.Contains("CXX")) { 267 | "${env:GITHUB_WORKSPACE}/BinaryCache/Library/Developer/Toolchains/${SwiftVersion}+Asserts/usr/bin/${Driver}" 268 | } elseif ($UsePinnedCompilers.Contains("CXX")) { 269 | # The pinned toolchain is already in the path. 270 | $Driver 271 | } 272 | } 273 | 274 | Add-KeyValueIfNew $Defines CMAKE_CXX_COMPILER $CXX 275 | Add-KeyValueIfNew $Defines CMAKE_CXX_COMPILER_TARGET $Triple 276 | 277 | $CXXFLAGS = if ($UseGNUDriver) { 278 | # TODO(compnerd) we should consider enabling stack protector usage for standard libraries. 279 | @("-fno-stack-protector", "-ffunction-sections", "-fdata-sections", "-fomit-frame-pointer") 280 | } elseif ($UseMSVCCompilers.Contains("CXX")) { 281 | @("/GS-", "/Gw", "/Gy", "/Oy", "/Oi", "/Zc:preprocessor", "/Zc:inline", "/Zc:__cplusplus") 282 | } else { 283 | # clang-cl does not support the /Zc:preprocessor flag. 284 | @("/GS-", "/Gw", "/Gy", "/Oy", "/Oi", "/Zc:inline", "/Zc:__cplusplus") 285 | } 286 | 287 | Add-FlagsDefine $Defines CMAKE_CXX_FLAGS $CXXFLAGS 288 | } 289 | 290 | if ($UseSwift) { 291 | if ($UseBuiltCompilers.Contains("Swift")) { 292 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER_WORKS "YES" 293 | } 294 | 295 | $SWIFTC = if ($UseBuiltCompilers.Contains("Swift")) { 296 | "${env:GITHUB_WORKSPACE}/BinaryCache/Library/Developer/Toolchains/${SwiftVersion}+Asserts/usr/bin/swiftc.exe" 297 | } elseif ($UsePinnedCompilers.Contains("Swift")) { 298 | "swiftc.exe" 299 | } 300 | 301 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER $SWIFTC 302 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER_TARGET $Triple 303 | 304 | # TODO(compnerd): remove this once we have the early swift-driver 305 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER_USE_OLD_DRIVER "YES" 306 | 307 | [string[]] $SwiftFlags = if ($SwiftSDK) { 308 | @("-sdk", $SwiftSDK) 309 | } else { 310 | @() 311 | } 312 | 313 | $SwiftFlags += if ($DebugInfo) { 314 | @("-g", "-debug-info-format=codeview", "-Xlinker", "/DEBUG") 315 | } else { 316 | @("-gnone") 317 | } 318 | 319 | # Disable EnC as that introduces padding in the conformance tables 320 | $SwiftFlags += @("-Xlinker", "/INCREMENTAL:NO") 321 | # Swift requires COMDAT folding and de-duplication 322 | $SwiftFlags += @("-Xlinker", "/OPT:REF", "-Xlinker", "/OPT:ICF") 323 | 324 | Add-FlagsDefine $Defines CMAKE_Swift_FLAGS $SwiftFlags 325 | # Workaround CMake 3.26+ enabling `-wmo` by default on release builds 326 | Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELEASE "-O" 327 | Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELWITHDEBINFO "-O" 328 | } 329 | 330 | $LinkerFlags = if ($UseGNUDriver) { 331 | @("-Xlinker", "/INCREMENTAL:NO", "-Xlinker", "/OPT:REF", "-Xlinker", "/OPT:ICF") 332 | } else { 333 | @("/INCREMENTAL:NO", "/OPT:REF", "/OPT:ICF") 334 | } 335 | 336 | if ($DebugInfo) { 337 | if ($UseASM -or $UseC -or $UseCXX) { 338 | # Prefer `/Z7` over `/ZI` 339 | # By setting the debug information format, the appropriate C/C++ 340 | # flags will be set for codeview debug information format so there 341 | # is no need to set them explicitly above. 342 | Add-KeyValueIfNew $Defines CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded 343 | Add-KeyValueIfNew $Defines CMAKE_POLICY_DEFAULT_CMP0141 NEW 344 | 345 | $LinkerFlags += if ($UseGNUDriver) { 346 | @("-Xlinker", "/DEBUG") 347 | } else { 348 | @("/DEBUG") 349 | } 350 | 351 | } 352 | } 353 | 354 | Add-FlagsDefine $Defines CMAKE_EXE_LINKER_FLAGS $LinkerFlags 355 | Add-FlagsDefine $Defines CMAKE_SHARED_LINKER_FLAGS $LinkerFlags 356 | } 357 | 358 | 'Android' { 359 | $AndroidArchABI = switch ($Arch) { 360 | 'i686' { "x86" } 361 | 'x86_64' { "x86_64" } 362 | 'armv7' { "armeabi-v7a" } 363 | 'arm64' { "arm64-v8a" } 364 | default { throw "Unsupported architecture: $Arch" } 365 | } 366 | $AndroidArchLLVM = switch ($BuildArch) { 367 | 'amd64' { "x86_64" } 368 | 'arm64' { "aarch64" } 369 | default { throw "Unsupported architecture: $Arch" } 370 | } 371 | $AndroidNDKPath = $NDKPath 372 | $AndroidPrebuiltRoot = "$AndroidNDKPath\toolchains\llvm\prebuilt\$($BuildOS.ToLowerInvariant())-$($AndroidArchLLVM)" 373 | $AndroidSysroot = "$AndroidPrebuiltRoot\sysroot" 374 | 375 | Add-KeyValueIfNew $Defines CMAKE_ANDROID_API "$AndroidAPILevel" 376 | Add-KeyValueIfNew $Defines CMAKE_ANDROID_ARCH_ABI "$AndroidArchABI" 377 | Add-KeyValueIfNew $Defines CMAKE_ANDROID_NDK "$AndroidNDKPath" 378 | 379 | if ($UseASM) { 380 | } 381 | 382 | if ($UseC) { 383 | Add-KeyValueIfNew $Defines CMAKE_C_COMPILER_TARGET $Triple 384 | 385 | $CFLAGS = @("--sysroot=${AndroidSysroot}", "-ffunction-sections", "-fdata-sections") 386 | if ($DebugInfo) { 387 | $CFLAGS += @("-g", "-gsplit-dwarf") 388 | } 389 | Add-FlagsDefine $Defines CMAKE_C_FLAGS $CFLAGS 390 | } 391 | 392 | if ($UseCXX) { 393 | Add-KeyValueIfNew $Defines CMAKE_CXX_COMPILER_TARGET $Triple 394 | 395 | $CXXFLAGS = @("--sysroot=${AndroidSysroot}", "-ffunction-sections", "-fdata-sections") 396 | if ($DebugInfo) { 397 | $CXXFLAGS += @("-g", "-gsplit-dwarf") 398 | } 399 | Add-FlagsDefine $Defines CMAKE_CXX_FLAGS $CXXFLAGS 400 | } 401 | 402 | if ($UseSwift) { 403 | if ($UseBuiltCompilers.Contains("Swift")) { 404 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER_WORKS "YES" 405 | } 406 | 407 | # FIXME(compnerd) remove this once the old runtimes build path is removed. 408 | Add-KeyValueIfNew $Defines SWIFT_ANDROID_NDK_PATH "$AndroidNDKPath" 409 | 410 | $SWIFTC = if ($UseBuiltCompilers.Contains("Swift")) { 411 | "${Env:GITHUB_WORKSPACE}/BinaryCache/Library/Developer/Toolchains/${SwiftVersion}+Asserts/usr/bin/swiftc.exe" 412 | } else { 413 | # The pinned toolchain is already in the path. 414 | "swiftc.exe" 415 | } 416 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER $SWIFTC 417 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER_TARGET $Triple 418 | 419 | # TODO(compnerd) remove this once we have the early swift-driver 420 | Add-KeyValueIfNew $Defines CMAKE_Swift_COMPILER_USE_OLD_DRIVER "YES" 421 | 422 | $SwiftFlags = if ($SwiftSDK) { 423 | @("-sdk", $SwiftSDK, "-sysroot", $AndroidSysroot) 424 | } else { 425 | @() 426 | } 427 | 428 | $SwiftFlags += @( 429 | "-Xclang-linker", "-target", "-Xclang-linker", $Triple, 430 | "-Xclang-linker", "--sysroot", "-Xclang-linker", $AndroidSysroot, 431 | "-Xclang-linker", "-resource-dir", "-Xclang-linker", "${AndroidPrebuiltRoot}\lib\clang\${AndroidClangVersion}" 432 | ) 433 | 434 | $SwiftFlags += if ($DebugInfo) { @("-g") } else { @("-gnone") } 435 | 436 | Add-FlagsDefine $Defines CMAKE_Swift_FLAGS $SwiftFlags 437 | # Workaround CMake 3.26+ enabling `-wmo` by default on release builds 438 | Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELEASE "-O" 439 | Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELWITHDEBINFO "-O" 440 | } 441 | 442 | $UseBuiltASMCompiler = $UseBuiltCompilers.Contains("ASM") 443 | $UseBuiltCCompiler = $UseBuiltCompilers.Contains("C") 444 | $UseBuiltCXXCompiler = $UseBuiltCompilers.Contains("CXX") 445 | 446 | if ($UseBuiltASMCompiler -or $UseBuiltCCompiler -or $UseBuiltCXXCompiler) { 447 | # Use a built lld linker as the Android's NDK linker might be too old 448 | # and not support all required relocations needed by the Swift 449 | # runtime. 450 | $ld = "${Env:GITHUB_WORKSPACE}/BinaryCache/Library/Developer/Toolchains/${SwiftVersion}+Asserts/usr/bin/ld.lld" 451 | Add-FlagsDefine $Defines CMAKE_SHARED_LINKER_FLAGS "--ld-path=$ld" 452 | Add-FlagsDefine $Defines CMAKE_EXE_LINKER_FLAGS "--ld-path=$ld" 453 | } 454 | 455 | # TODO(compnerd) we should understand why CMake does not understand 456 | # that the object file format is ELF when targeting Android on Windows. 457 | # This indication allows it to understand that it can use `chrpath` to 458 | # change the RPATH on the dynamic libraries. 459 | Add-FlagsDefine $Defines CMAKE_EXECUTABLE_FORMAT "ELF" 460 | } 461 | } 462 | 463 | # TODO(steelskin): sccache does not work with "-gsplit-dwarf". 464 | if ($EnableCaching -and $OS -ne "Android") { 465 | if ($UseC) { 466 | Add-KeyValueIfNew $Defines CMAKE_C_COMPILER_LAUNCHER "sccache" 467 | } 468 | 469 | if ($UseCXX) { 470 | Add-KeyValueIfNew $Defines CMAKE_CXX_COMPILER_LAUNCHER "sccache" 471 | } 472 | } 473 | 474 | if ($InstallDir) { 475 | Add-KeyValueIfNew $Defines CMAKE_INSTALL_PREFIX $InstallDir 476 | } 477 | 478 | # Generate the project 479 | $cmakeGenerateArgs = @("-B", $BinDir, "-S", $SrcDir, "-G", "Ninja") 480 | if ($CacheScript) { 481 | $cmakeGenerateArgs += @("-C", $CacheScript) 482 | } 483 | 484 | foreach ($Define in ($Defines.GetEnumerator() | Sort-Object Name)) { 485 | # The quoting gets tricky to support defines containing compiler flags args, 486 | # some of which can contain spaces, for example `-D` `Flags=-flag "C:/Program Files"` 487 | # Avoid backslashes since they are going into CMakeCache.txt, 488 | # where they are interpreted as escapes. 489 | if ($Define.Value -is [string]) { 490 | # Single token value, no need to quote spaces, the splat operator does the right thing. 491 | $Value = $Define.Value.Replace("\", "/") 492 | } else { 493 | # Flags array, multiple tokens, quoting needed for tokens containing spaces 494 | $Value = "" 495 | foreach ($Arg in $Define.Value) { 496 | if ($Value.Length -gt 0) { 497 | $Value += " " 498 | } 499 | 500 | $ArgWithForwardSlashes = $Arg.Replace("\", "/") 501 | if ($ArgWithForwardSlashes.Contains(" ")) { 502 | # Escape the quote so it makes it through. PowerShell 5 and Core 503 | # handle quotes differently, so we need to check the version. 504 | $quote = if ($PSEdition -eq "Core") { '"' } else { '\"' } 505 | $Value += "$quote$ArgWithForwardSlashes$quote" 506 | } else { 507 | $Value += $ArgWithForwardSlashes 508 | } 509 | } 510 | } 511 | 512 | $cmakeGenerateArgs += @("-D", "$($Define.Key)=$Value") 513 | } 514 | 515 | Write-Host "ℹ️ Configuring project ${ProjectName}:" 516 | Write-Host 'cmake `' 517 | for ($i = 0; $i -lt $cmakeGenerateArgs.Length; $i += 1) { 518 | $Arg = $cmakeGenerateArgs[$i] 519 | if ($Arg -match '\s') { 520 | Write-Host " `'$Arg`'" -NoNewline 521 | } else { 522 | Write-Host " $Arg" -NoNewline 523 | } 524 | 525 | if ((-not ($Arg -match '^-')) -and ($i -lt ($cmakeGenerateArgs.Length - 1))) { 526 | # Write a newline for non-option arguments. 527 | Write-Host " ``" 528 | } 529 | } 530 | Write-Host "`n" 531 | 532 | & cmake @cmakeGenerateArgs 533 | if ($LASTEXITCODE -ne 0) { 534 | throw "CMake generation failed for project ${ProjectName} with exit code $LASTEXITCODE." 535 | } 536 | -------------------------------------------------------------------------------- /.github/workflows/build-toolchain.yml: -------------------------------------------------------------------------------- 1 | name: Development Snapshot 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | repo_url: 7 | description: 'Repo Manifest URL' 8 | default: 'https://github.com/compnerd/swift-build' 9 | required: false 10 | type: string 11 | 12 | swift_version: 13 | description: 'Swift Version' 14 | default: '0.0.0' 15 | required: false 16 | type: string 17 | 18 | android_api_level: 19 | description: 'Android API Level' 20 | default: 28 21 | required: false 22 | type: number 23 | 24 | swift_tag: 25 | description: 'Swift Build Tag' 26 | required: false 27 | type: string 28 | 29 | debug_info: 30 | description: 'Emit PDBs (Debug Info)' 31 | default: false 32 | type: boolean 33 | 34 | signed: 35 | description: 'Code Sign' 36 | default: false 37 | type: boolean 38 | # NOTE(speednoisemovement): `create_release`/`create_snapshot` are defaulted to false in workflow_dispatch (usually used for 39 | # testing), but true in workflow_call. This is intentional! 40 | create_release: 41 | description: 'Create Release' 42 | type: boolean 43 | default: false 44 | required: false 45 | 46 | create_snapshot: 47 | description: 'Create Snapshot' 48 | type: boolean 49 | default: false 50 | required: false 51 | 52 | build_android: 53 | description: 'Build Android SDK' 54 | required: false 55 | default: false 56 | type: boolean 57 | 58 | use_host_toolchain: 59 | description: 'Use host toolchain (MSVC) instead of clang-cl/lld-link' 60 | type: boolean 61 | default: true 62 | required: false 63 | 64 | workflow_call: 65 | inputs: 66 | repo_url: 67 | description: 'Repo Manifest URL' 68 | default: 'https://github.com/compnerd/swift-build' 69 | required: false 70 | type: string 71 | 72 | swift_version: 73 | description: 'Swift Version' 74 | default: '0.0.0' 75 | required: false 76 | type: string 77 | 78 | android_api_level: 79 | description: 'Android API Level' 80 | default: 28 81 | required: false 82 | type: number 83 | 84 | swift_tag: 85 | description: 'Swift Build Tag' 86 | required: false 87 | type: string 88 | 89 | debug_info: 90 | description: 'Emit PDBs (Debug Info)' 91 | default: true 92 | type: boolean 93 | 94 | signed: 95 | description: 'Code Sign' 96 | default: false 97 | type: boolean 98 | 99 | # NOTE(speednoisemovement): `create_release`/`create_snapshot` are defaulted to false in workflow_dispatch (usually used for 100 | # testing), but true in workflow_call. This is intentional! 101 | create_release: 102 | description: 'Create Release' 103 | type: boolean 104 | default: true 105 | required: false 106 | 107 | create_snapshot: 108 | description: 'Create Snapshot' 109 | type: boolean 110 | default: true 111 | required: false 112 | 113 | windows_x64_default_runner: 114 | description: 'X64 Build runner' 115 | required: false 116 | type: string 117 | 118 | windows_arm64_default_runner: 119 | description: 'ARM64 Build runner' 120 | required: false 121 | type: string 122 | 123 | windows_x64_compilers_runner: 124 | description: 'X64 Build runner for `compilers` job' 125 | required: false 126 | type: string 127 | 128 | windows_arm64_compilers_runner: 129 | description: 'ARM64 Build runner for `compilers` job' 130 | required: false 131 | type: string 132 | 133 | windows_build_arch: 134 | description: 'Windows build architecture' 135 | required: false 136 | type: string 137 | 138 | build_android: 139 | description: 'Build Android SDK' 140 | required: false 141 | default: false 142 | type: boolean 143 | 144 | use_host_toolchain: 145 | description: 'Use host toolchain (MSVC) instead of clang-cl/lld-link' 146 | type: boolean 147 | default: true 148 | required: false 149 | 150 | secrets: 151 | SYMBOL_SERVER_PAT: 152 | required: true 153 | CERTIFICATE: 154 | required: true 155 | PASSPHRASE: 156 | required: true 157 | R2_ACCOUNT_ID: 158 | required: true 159 | R2_ACCESS_KEY_ID: 160 | required: true 161 | R2_SECRET_ACCESS_KEY: 162 | required: true 163 | AZURE_SP_CREDENTIALS: 164 | required: false 165 | TRUSTED_SIGNING_ACCOUNT: 166 | required: false 167 | TRUSTED_SIGNING_TEST_PROFILE: 168 | required: false 169 | TRUSTED_SIGNING_PROD_PROFILE: 170 | required: false 171 | 172 | jobs: 173 | context: 174 | runs-on: ubuntu-latest 175 | outputs: 176 | brotli_revision: ${{ steps.context.outputs.brotli_revision }} 177 | brotli_version: ${{ steps.context.outputs.brotli_version }} 178 | curl_revision: ${{ steps.context.outputs.curl_revision }} 179 | curl_version: ${{ steps.context.outputs.curl_version }} 180 | ds2_revision: ${{ steps.context.outputs.ds2_revision }} 181 | indexstore_db_revision: ${{ steps.context.outputs.indexstore_db_revision }} 182 | libxml2_revision: ${{ steps.context.outputs.libxml2_revision }} 183 | libxml2_version: ${{ steps.context.outputs.libxml2_version }} 184 | llvm_project_revision: ${{ steps.context.outputs.llvm_project_revision }} 185 | mimalloc_revision: ${{ steps.context.outputs.mimalloc_revision }} 186 | sourcekit_lsp_revision: ${{ steps.context.outputs.sourcekit_lsp_revision }} 187 | swift_argument_parser_revision: ${{ steps.context.outputs.swift_argument_parser_revision }} 188 | swift_asn1_revision: ${{ steps.context.outputs.swift_asn1_revision }} 189 | swift_atomics_revision: ${{ steps.context.outputs.swift_atomics_revision }} 190 | swift_build_revision: ${{ steps.context.outputs.swift_build_revision }} 191 | swift_certificates_revision: ${{ steps.context.outputs.swift_certificates_revision }} 192 | swift_cmark_revision: ${{ steps.context.outputs.swift_cmark_revision }} 193 | swift_cmark_version: ${{ steps.context.outputs.swift_cmark_version }} 194 | swift_collections_revision: ${{ steps.context.outputs.swift_collections_revision }} 195 | swift_corelibs_foundation_revision: ${{ steps.context.outputs.swift_corelibs_foundation_revision }} 196 | swift_corelibs_libdispatch_revision: ${{ steps.context.outputs.swift_corelibs_libdispatch_revision }} 197 | swift_corelibs_xctest_revision: ${{ steps.context.outputs.swift_corelibs_xctest_revision }} 198 | swift_crypto_revision: ${{ steps.context.outputs.swift_crypto_revision }} 199 | swift_docc_render_artifact_revision: ${{ steps.context.outputs.swift_docc_render_artifact_revision }} 200 | swift_docc_revision: ${{ steps.context.outputs.swift_docc_revision }} 201 | swift_docc_symbolkit_revision: ${{ steps.context.outputs.swift_docc_symbolkit_revision }} 202 | swift_driver_revision: ${{ steps.context.outputs.swift_driver_revision }} 203 | swift_experimental_string_processing_revision: ${{ steps.context.outputs.swift_experimental_string_processing_revision }} 204 | swift_format_revision: ${{ steps.context.outputs.swift_format_revision }} 205 | swift_foundation_revision: ${{ steps.context.outputs.swift_foundation_revision }} 206 | swift_foundation_icu_revision: ${{ steps.context.outputs.swift_foundation_icu_revision }} 207 | swift_installer_scripts_revision: ${{ steps.context.outputs.swift_installer_scripts_revision }} 208 | swift_llbuild_revision: ${{ steps.context.outputs.swift_llbuild_revision }} 209 | swift_lmdb_revision: ${{ steps.context.outputs.swift_lmdb_revision }} 210 | swift_markdown_revision: ${{ steps.context.outputs.swift_markdown_revision }} 211 | swift_package_manager_revision: ${{ steps.context.outputs.swift_package_manager_revision }} 212 | swift_revision: ${{ steps.context.outputs.swift_revision }} 213 | swift_subprocess_revision: ${{ steps.context.outputs.swift_subprocess_revision }} 214 | swift_syntax_revision: ${{ steps.context.outputs.swift_syntax_revision }} 215 | swift_system_revision: ${{ steps.context.outputs.swift_system_revision }} 216 | swift_testing_revision: ${{ steps.context.outputs.swift_testing_revision }} 217 | swift_toolchain_sqlite_revision: ${{ steps.context.outputs.swift_toolchain_sqlite_revision }} 218 | swift_toolchain_sqlite_version: ${{ steps.context.outputs.swift_toolchain_sqlite_version }} 219 | swift_tools_protocols_revision: ${{ steps.context.outputs.swift_tools_protocols_revision }} 220 | swift_tools_support_core_revision: ${{ steps.context.outputs.swift_tools_support_core_revision }} 221 | zlib_revision: ${{ steps.context.outputs.zlib_revision }} 222 | zlib_version: ${{ steps.context.outputs.zlib_version }} 223 | ANDROID_API_LEVEL: ${{ steps.context.outputs.ANDROID_API_LEVEL }} 224 | ANDROID_CLANG_VERSION: ${{ steps.context.outputs.ANDROID_CLANG_VERSION }} 225 | ANDROID_NDK_VERSION: ${{ steps.context.outputs.ANDROID_NDK_VERSION }} 226 | debug_info: ${{ steps.context.outputs.debug_info }} 227 | signed: ${{ steps.context.outputs.signed }} 228 | swift_version: ${{ steps.context.outputs.swift_version }} 229 | swift_tag: ${{ steps.context.outputs.swift_tag }} 230 | windows_arm64_build_runner: ${{ steps.context.outputs.windows_arm64_build_runner }} 231 | windows_arm64_compilers_runner: ${{ steps.context.outputs.windows_arm64_compilers_runner }} 232 | windows_build_arch: ${{ steps.context.outputs.windows_build_arch }} 233 | windows_build_cpu: ${{ steps.context.outputs.windows_build_cpu }} 234 | windows_x64_build_runner: ${{ steps.context.outputs.windows_x64_build_runner }} 235 | windows_x64_compilers_runner: ${{ steps.context.outputs.windows_x64_compilers_runner }} 236 | mac_build_runner: ${{ steps.context.outputs.mac_build_runner }} 237 | python_version: ${{ steps.context.outputs.python_version }} 238 | python_download_locations: ${{ steps.context.outputs.python_download_locations }} 239 | windows_arm64_build_matrix: ${{ steps.setup-matrix.outputs.windows_arm64_build_matrix }} 240 | windows_arm64_host_matrix: ${{ steps.setup-matrix.outputs.windows_arm64_host_matrix }} 241 | windows_arm64_compilers_matrix: ${{ steps.setup-matrix.outputs.windows_arm64_compilers_matrix }} 242 | windows_arm64_target_matrix: ${{ steps.setup-matrix.outputs.windows_arm64_target_matrix }} 243 | windows_x64_build_matrix: ${{ steps.setup-matrix.outputs.windows_x64_build_matrix }} 244 | windows_x64_host_matrix: ${{ steps.setup-matrix.outputs.windows_x64_host_matrix }} 245 | windows_x64_compilers_matrix: ${{ steps.setup-matrix.outputs.windows_x64_compilers_matrix }} 246 | windows_x64_target_matrix: ${{ steps.setup-matrix.outputs.windows_x64_target_matrix }} 247 | darwin_host_matrix: ${{ steps.setup-matrix.outputs.darwin_host_matrix }} 248 | darwin_compilers_matrix: ${{ steps.setup-matrix.outputs.darwin_compilers_matrix }} 249 | darwin_build_matrix: ${{ steps.setup-matrix.outputs.darwin_build_matrix }} 250 | darwin_target_matrix: ${{ steps.setup-matrix.outputs.darwin_target_matrix }} 251 | steps: 252 | - id: context 253 | name: Generate Build Context 254 | env: 255 | PYTHON_DOWNLOAD_LOCATIONS: >- 256 | { 257 | "3.9.10": { 258 | "AMD64": { 259 | "URL": "https://www.nuget.org/api/v2/package/python/3.9.10", 260 | "SHA256": "ac43b491e9488ac926ed31c5594f0c9409a21ecbaf99dc7a93f8c7b24cf85867" 261 | }, 262 | "ARM64": { 263 | "URL": "https://www.nuget.org/api/v2/package/pythonarm64/3.9.10", 264 | "SHA256": "429ada77e7f30e4bd8ff22953a1f35f98b2728e84c9b1d006712561785641f69" 265 | } 266 | }, 267 | "3.10.1": { 268 | "AMD64": { 269 | "URL": "https://www.nuget.org/api/v2/package/python/3.10.1", 270 | "SHA256": "987a0e446d68900f58297bc47dc7a235ee4640a49dace58bc9f573797d3a8b33" 271 | }, 272 | "AMD64_Embedded": { 273 | "URL": "https://www.python.org/ftp/python/3.10.1/python-3.10.1-embed-amd64.zip", 274 | "SHA256": "502670dcdff0083847abf6a33f30be666594e7e5201cd6fccd4a523b577403de" 275 | }, 276 | "ARM64": { 277 | "URL": "https://www.nuget.org/api/v2/package/pythonarm64/3.10.1", 278 | "SHA256": "16becfccedf1269ff0b8695a13c64fac2102a524d66cecf69a8f9229a43b10d3" 279 | }, 280 | "ARM64_Embedded": { 281 | "URL": "https://www.python.org/ftp/python/3.10.1/python-3.10.1-embed-arm64.zip", 282 | "SHA256": "1f9e215fe4e8f22a8e8fba1859efb1426437044fb3103ce85794630e3b511bc2" 283 | } 284 | } 285 | } 286 | run: | 287 | # TODO(compnerd) can we make this more silent? 288 | sudo DEBIAN_FRONTEND=noninteractive apt-get -qq update -yq 289 | sudo DEBIAN_FRONTEND=noninteractive apt-get -qq -o Dpkg::Use-Pty=0 install -yq repo libxml2-utils 290 | 291 | # Which branch is this workflow based on 292 | branch_version_string=${{ inputs.swift_version || '0.0.0' }} 293 | if [[ $branch_version_string == *.* ]]; then 294 | branch_name=$(echo ${branch_version_string} | awk -F. '{ ver=$1"."$2; print (ver == "0.0") ? "main" : "release/"ver }') 295 | else 296 | branch_name="release/$branch_version_string" 297 | fi 298 | 299 | repo init --quiet --groups default --depth 1 -u ${{ inputs.repo_url }} -b $branch_name 300 | repo sync --quiet --no-clone-bundle --no-tags --jobs $(nproc --all) 301 | 302 | if [[ "${{ inputs.swift_tag }}" != "" ]] ; then 303 | tee -a "${GITHUB_OUTPUT}" <<-EOF 304 | indexstore_db_revision=refs/tags/${{ inputs.swift_tag }} 305 | llvm_project_revision=refs/tags/${{ inputs.swift_tag }} 306 | mimalloc_revision=refs/tags/v3.0.1 307 | sourcekit_lsp_revision=refs/tags/${{ inputs.swift_tag }} 308 | swift_revision=refs/tags/${{ inputs.swift_tag }} 309 | swift_argument_parser_revision=refs/tags/1.4.0 310 | swift_asn1_revision=refs/tags/1.0.0 311 | swift_atomics_revision=refs/tags/1.2.0 312 | swift_build_revision=refs/heads/main 313 | swift_certificates_revision=refs/tags/1.0.1 314 | swift_cmark_revision=refs/tags/${{ inputs.swift_tag }} 315 | swift_collections_revision=refs/tags/1.1.3 316 | swift_corelibs_foundation_revision=refs/tags/${{ inputs.swift_tag }} 317 | swift_corelibs_libdispatch_revision=refs/tags/${{ inputs.swift_tag }} 318 | swift_corelibs_xctest_revision=refs/tags/${{ inputs.swift_tag }} 319 | swift_crypto_revision=refs/tags/3.12.5 320 | swift_driver_revision=refs/tags/${{ inputs.swift_tag }} 321 | swift_experimental_string_processing_revision=refs/tags/${{ inputs.swift_tag }} 322 | swift_format_revision=refs/heads/main 323 | swift_foundation_revison=refs/heads/main 324 | swift_foundation_icu_revision=refs/heads/main 325 | swift_installer_scripts_revision=refs/heads/main 326 | swift_llbuild_revision=refs/tags/${{ inputs.swift_tag }} 327 | swift_lmdb_revision=refs/heads/main 328 | swift_markdown_revision=refs/tags/${{ inputs.swift_tag }} 329 | swift_package_manager_revision=refs/tags/${{ inputs.swift_tag }} 330 | swift_subprocess_revision=refs/heads/main 331 | swift_syntax_revision=refs/tags/${{ inputs.swift_tag }} 332 | swift_system_revision=refs/tags/1.3.0 333 | swift_testing_revision=refs/heads/main 334 | swift_toolchain_sqlite_revision=refs/tags/1.0.1 335 | swift_tools_protocols_revision=refs/tags/0.0.9 336 | swift_tools_support_core_revision=refs/tags/${{ inputs.swift_tag }} 337 | curl_revision=refs/tags/curl-8_9_1 338 | ds2_revision=refs/tags/nightly-2024-11-07 339 | libxml2_revision=refs/tags/v2.11.5 340 | zlib_revision=refs/tags/v1.3.1 341 | brotli_revision=refs/tags/v1.1.0 342 | EOF 343 | else 344 | repo manifest -r --suppress-upstream-revision --suppress-dest-branch | \ 345 | xmllint --xpath "//project/@name | //project/@revision" - | \ 346 | xargs -n2 | \ 347 | awk -F'[= ]' '{ 348 | split($2, repo, "/"); 349 | gsub(/-/, "_", repo[2]); 350 | print tolower(repo[2]) "_revision=" $4 351 | }' | tee -a "${GITHUB_OUTPUT}" 352 | repo manifest -r --suppress-upstream-revision --suppress-dest-branch -o - | sed -E 's,[[:space:]]+$,,' > stable.xml 353 | fi 354 | 355 | echo libxml2_version=2.11.5 >> ${GITHUB_OUTPUT} 356 | echo curl_version=8.9.1 >> ${GITHUB_OUTPUT} 357 | echo swift_toolchain_sqlite_version=3.46.0 >> ${GITHUB_OUTPUT} 358 | echo swift_cmark_version=0.29.0.gfm.13 >> ${GITHUB_OUTPUT} 359 | echo zlib_version=1.3 >> ${GITHUB_OUTPUT} 360 | echo brotli_version=1.1.0 >> ${GITHUB_OUTPUT} 361 | 362 | # FIXME(z2oh): Remove /D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR when GitHub runner image updates to 20240610.1. 363 | # see: https://github.com/actions/runner-images/issues/10004 364 | if [[ "${{ github.event_name }}" == "schedule" || "${{ inputs.debug_info }}" == "true" ]]; then 365 | echo debug_info=true >> ${GITHUB_OUTPUT} 366 | else 367 | echo debug_info=false >> ${GITHUB_OUTPUT} 368 | fi 369 | 370 | if [[ "${{ github.event_name }}" == "schedule" || "${{ inputs.signed }}" == "true" ]]; then 371 | echo signed=true >> ${GITHUB_OUTPUT} 372 | else 373 | echo signed=false >> ${GITHUB_OUTPUT} 374 | fi 375 | 376 | echo swift_version=${{ inputs.swift_version || '0.0.0' }} | tee -a ${GITHUB_OUTPUT} 377 | if [[ -n "${{ inputs.swift_tag }}" ]] ; then 378 | echo swift_tag=${{ inputs.swift_tag }} | tee -a ${GITHUB_OUTPUT} 379 | else 380 | if [[ "$branch_name" == "main" ]] ; then 381 | echo swift_tag=$(date +%Y%m%d.$(date +%-H/6 | bc)) | tee -a ${GITHUB_OUTPUT} 382 | else 383 | echo swift_tag=swift-"$branch_version_string"-$(date +%Y%m%d.$(date +%-H/6 | bc)) | tee -a ${GITHUB_OUTPUT} 384 | fi 385 | fi 386 | 387 | echo windows_x64_build_runner=${{ inputs.windows_x64_default_runner || vars.WINDOWS_BUILD_RUNNER || 'windows-latest' }} >> ${GITHUB_OUTPUT} 388 | echo windows_x64_compilers_runner=${{ inputs.windows_x64_compilers_runner || inputs.windows_x64_default_runner || vars.WINDOWS_X64_COMPILERS_BUILD_RUNNER || vars.WINDOWS_X64_DEFAULT_BUILD_RUNNER || 'windows-latest' }} >> ${GITHUB_OUTPUT} 389 | echo windows_arm64_build_runner=${{ inputs.windows_arm64_default_runner || vars.WINDOWS_ARM64_DEFAULT_BUILD_RUNNER || 'windows-latest' }} >> ${GITHUB_OUTPUT} 390 | echo windows_arm64_compilers_runner=${{ inputs.windows_arm64_compilers_runner || inputs.windows_arm64_default_runner || vars.WINDOWS_ARM64_COMPILERS_BUILD_RUNNER || vars.WINDOWS_ARM64_DEFAULT_BUILD_RUNNER || 'windows-latest' }} >> ${GITHUB_OUTPUT} 391 | if [[ "${{ inputs.windows_build_arch }}" == "arm64" ]] ; then 392 | echo windows_build_arch=arm64 >> ${GITHUB_OUTPUT} 393 | echo windows_build_cpu=arm64 >> ${GITHUB_OUTPUT} 394 | else 395 | echo windows_build_arch=amd64 >> ${GITHUB_OUTPUT} 396 | echo windows_build_cpu=x64 >> ${GITHUB_OUTPUT} 397 | fi 398 | 399 | # TODO: Make the mac runner configurable. 400 | echo mac_build_runner=macos-latest >> ${GITHUB_OUTPUT} 401 | 402 | echo ANDROID_API_LEVEL=${{ inputs.android_api_level }} >> ${GITHUB_OUTPUT} 403 | echo ANDROID_NDK_VERSION=r27c >> ${GITHUB_OUTPUT} 404 | echo ANDROID_CLANG_VERSION=18 >> ${GITHUB_OUTPUT} 405 | 406 | # Set Python version used in the build 407 | echo python_version=3.10.1 >> ${GITHUB_OUTPUT} 408 | 409 | # Set Python download locations 410 | echo python_download_locations=$(jq -c '.' <<< "${PYTHON_DOWNLOAD_LOCATIONS}") >> ${GITHUB_OUTPUT} 411 | 412 | - uses: actions/upload-artifact@v4 413 | if: inputs.create_snapshot == true 414 | with: 415 | name: stable.xml 416 | path: stable.xml 417 | if-no-files-found: ignore 418 | 419 | - name: Setup matrix 420 | id: setup-matrix 421 | env: 422 | WINDOWS_X64_HOST_MATRIX: >- 423 | { 424 | "include": [ 425 | { 426 | "arch": "amd64", 427 | "cpu": "x86_64", 428 | "os": "Windows", 429 | "triple": "x86_64-unknown-windows-msvc" 430 | }, 431 | { 432 | "arch": "arm64", 433 | "cpu": "aarch64", 434 | "os": "Windows", 435 | "triple": "aarch64-unknown-windows-msvc" 436 | } 437 | ] 438 | } 439 | WINDOWS_ARM64_HOST_MATRIX: >- 440 | { 441 | "include": [ 442 | { 443 | "arch": "arm64", 444 | "cpu": "aarch64", 445 | "os": "Windows", 446 | "triple": "aarch64-unknown-windows-msvc" 447 | } 448 | ] 449 | } 450 | WINDOWS_X64_BUILD_MATRIX: >- 451 | { 452 | "include": [ 453 | { 454 | "arch": "amd64", 455 | "cpu": "x86_64", 456 | "os": "Windows", 457 | "triple": "x86_64-unknown-windows-msvc" 458 | } 459 | ] 460 | } 461 | WINDOWS_ARM64_BUILD_MATRIX: >- 462 | { 463 | "include": [ 464 | { 465 | "arch": "arm64", 466 | "cpu": "aarch64", 467 | "os": "Windows", 468 | "triple": "aarch64-unknown-windows-msvc" 469 | } 470 | ] 471 | } 472 | WINDOWS_X64_TARGET_MATRIX: >- 473 | { 474 | "include": [ 475 | { 476 | "arch": "amd64", 477 | "cpu": "x86_64", 478 | "os": "Windows", 479 | "triple": "x86_64-unknown-windows-msvc" 480 | }, 481 | { 482 | "arch": "arm64", 483 | "cpu": "aarch64", 484 | "os": "Windows", 485 | "triple": "aarch64-unknown-windows-msvc" 486 | }, 487 | { 488 | "arch": "x86", 489 | "cpu": "i686", 490 | "os": "Windows", 491 | "triple": "i686-unknown-windows-msvc" 492 | }, 493 | { 494 | "arch": "arm64", 495 | "cpu": "aarch64", 496 | "os": "Android", 497 | "triple": "aarch64-unknown-linux-android${{ inputs.ANDROID_API_LEVEL }}" 498 | }, 499 | { 500 | "arch": "armv7", 501 | "cpu": "armv7", 502 | "os": "Android", 503 | "triple": "armv7-unknown-linux-androideabi${{ inputs.ANDROID_API_LEVEL }}" 504 | }, 505 | { 506 | "arch": "i686", 507 | "cpu": "i686", 508 | "os": "Android", 509 | "triple": "i686-unknown-linux-android${{ inputs.ANDROID_API_LEVEL }}" 510 | }, 511 | { 512 | "arch": "x86_64", 513 | "cpu": "x86_64", 514 | "os": "Android", 515 | "triple": "x86_64-unknown-linux-android${{ inputs.ANDROID_API_LEVEL }}" 516 | } 517 | ] 518 | } 519 | WINDOWS_ARM64_TARGET_MATRIX: >- 520 | { 521 | "include": [ 522 | { 523 | "arch": "amd64", 524 | "cpu": "x86_64", 525 | "os": "Windows", 526 | "triple": "x86_64-unknown-windows-msvc" 527 | }, 528 | { 529 | "arch": "arm64", 530 | "cpu": "aarch64", 531 | "os": "Windows", 532 | "triple": "aarch64-unknown-windows-msvc" 533 | }, 534 | { 535 | "arch": "x86", 536 | "cpu": "i686", 537 | "os": "Windows", 538 | "triple": "i686-unknown-windows-msvc" 539 | } 540 | ] 541 | } 542 | DARWIN_HOST_MATRIX: >- 543 | { 544 | "include": [ 545 | { 546 | "arch": "x86_64", 547 | "cpu": "x86_64", 548 | "os": "Darwin" 549 | }, 550 | { 551 | "arch": "arm64", 552 | "cpu": "arm64", 553 | "os": "Darwin" 554 | } 555 | ] 556 | } 557 | DARWIN_BUILD_MATRIX: >- 558 | { 559 | "include": [ 560 | { 561 | "arch": "arm64", 562 | "cpu": "arm64", 563 | "os": "Darwin", 564 | "triple": "arm64-apple-macosx15.0" 565 | } 566 | ] 567 | } 568 | DARWIN_TARGET_MATRIX: >- 569 | { 570 | "include": [ 571 | { 572 | "arch": "x86_64", 573 | "cpu": "x86_64", 574 | "os": "Darwin", 575 | "triple": "x86_64-apple-macosx15.0" 576 | }, 577 | { 578 | "arch": "arm64", 579 | "cpu": "arm64", 580 | "os": "Darwin", 581 | "triple": "arm64-apple-macosx15.0" 582 | } 583 | ] 584 | } 585 | run: | 586 | create_compilers_matrix() { 587 | local host_matrix=$1 588 | jq -n --argjson host_matrix "${host_matrix}" ' 589 | { 590 | "include": [ 591 | ($host_matrix.include[] | . + {"variant": "Asserts"}), 592 | ($host_matrix.include[] | . + {"variant": "NoAsserts"}) 593 | ] 594 | } 595 | ' 596 | } 597 | WINDOWS_X64_COMPILERS_MATRIX=$(create_compilers_matrix "${WINDOWS_X64_HOST_MATRIX}") 598 | WINDOWS_ARM64_COMPILERS_MATRIX=$(create_compilers_matrix "${WINDOWS_ARM64_HOST_MATRIX}") 599 | DARWIN_COMPILERS_MATRIX=$(create_compilers_matrix "${DARWIN_HOST_MATRIX}") 600 | 601 | echo "windows_x64_host_matrix=$(jq -r -c '.' <<< ${WINDOWS_X64_HOST_MATRIX})" >> ${GITHUB_OUTPUT} 602 | echo "windows_arm64_host_matrix=$(jq -r -c '.' <<< ${WINDOWS_ARM64_HOST_MATRIX})" >> ${GITHUB_OUTPUT} 603 | echo "windows_x64_compilers_matrix=$(jq -r -c '.' <<< ${WINDOWS_X64_COMPILERS_MATRIX})" >> ${GITHUB_OUTPUT} 604 | echo "windows_arm64_compilers_matrix=$(jq -r -c '.' <<< ${WINDOWS_ARM64_COMPILERS_MATRIX})" >> ${GITHUB_OUTPUT} 605 | echo "windows_x64_build_matrix=$(jq -r -c '.' <<< ${WINDOWS_X64_BUILD_MATRIX})" >> ${GITHUB_OUTPUT} 606 | echo "windows_arm64_build_matrix=$(jq -r -c '.' <<< ${WINDOWS_ARM64_BUILD_MATRIX})" >> ${GITHUB_OUTPUT} 607 | echo "windows_x64_target_matrix=$(jq -r -c '.' <<< ${WINDOWS_X64_TARGET_MATRIX})" >> ${GITHUB_OUTPUT} 608 | echo "windows_arm64_target_matrix=$(jq -r -c '.' <<< ${WINDOWS_ARM64_TARGET_MATRIX})" >> ${GITHUB_OUTPUT} 609 | echo "darwin_host_matrix=$(jq -r -c '.' <<< ${DARWIN_HOST_MATRIX})" >> ${GITHUB_OUTPUT} 610 | echo "darwin_build_matrix=$(jq -r -c '.' <<< ${DARWIN_BUILD_MATRIX})" >> ${GITHUB_OUTPUT} 611 | echo "darwin_compilers_matrix=$(jq -r -c '.' <<< ${DARWIN_COMPILERS_MATRIX})" >> ${GITHUB_OUTPUT} 612 | echo "darwin_target_matrix=$(jq -r -c '.' <<< ${DARWIN_TARGET_MATRIX})" >> ${GITHUB_OUTPUT} 613 | 614 | windows-build: 615 | needs: [context] 616 | name: Windows Swift Toolchains Build 617 | permissions: 618 | contents: read 619 | id-token: write 620 | attestations: write 621 | 622 | uses: ./.github/workflows/swift-toolchain.yml 623 | with: 624 | build_os: Windows 625 | build_arch: ${{ needs.context.outputs.windows_build_arch }} 626 | build_matrix: ${{ needs.context.outputs[format('windows_{0}_build_matrix', needs.context.outputs.windows_build_cpu)] }} 627 | host_matrix: ${{ needs.context.outputs[format('windows_{0}_host_matrix', needs.context.outputs.windows_build_cpu)] }} 628 | target_matrix: ${{ needs.context.outputs[format('windows_{0}_target_matrix', needs.context.outputs.windows_build_cpu)] }} 629 | compilers_matrix: ${{ needs.context.outputs[format('windows_{0}_compilers_matrix', needs.context.outputs.windows_build_cpu)] }} 630 | curl_revision: ${{ needs.context.outputs.curl_revision }} 631 | curl_version: ${{ needs.context.outputs.curl_version }} 632 | ds2_revision: ${{ needs.context.outputs.ds2_revision }} 633 | brotli_revision: ${{ needs.context.outputs.brotli_revision }} 634 | brotli_version: ${{ needs.context.outputs.brotli_version }} 635 | indexstore_db_revision: ${{ needs.context.outputs.indexstore_db_revision }} 636 | libxml2_revision: ${{ needs.context.outputs.libxml2_revision }} 637 | libxml2_version: ${{ needs.context.outputs.libxml2_version }} 638 | llvm_project_revision: ${{ needs.context.outputs.llvm_project_revision }} 639 | mimalloc_revision: ${{ needs.context.outputs.mimalloc_revision }} 640 | sourcekit_lsp_revision: ${{ needs.context.outputs.sourcekit_lsp_revision }} 641 | swift_argument_parser_revision: ${{ needs.context.outputs.swift_argument_parser_revision }} 642 | swift_asn1_revision: ${{ needs.context.outputs.swift_asn1_revision }} 643 | swift_atomics_revision: ${{ needs.context.outputs.swift_atomics_revision }} 644 | swift_build_revision: ${{ needs.context.outputs.swift_build_revision }} 645 | swift_certificates_revision: ${{ needs.context.outputs.swift_certificates_revision }} 646 | swift_cmark_revision: ${{ needs.context.outputs.swift_cmark_revision }} 647 | swift_cmark_version: ${{ needs.context.outputs.swift_cmark_version }} 648 | swift_collections_revision: ${{ needs.context.outputs.swift_collections_revision }} 649 | swift_corelibs_foundation_revision: ${{ needs.context.outputs.swift_corelibs_foundation_revision }} 650 | swift_corelibs_libdispatch_revision: ${{ needs.context.outputs.swift_corelibs_libdispatch_revision }} 651 | swift_corelibs_xctest_revision: ${{ needs.context.outputs.swift_corelibs_xctest_revision }} 652 | swift_crypto_revision: ${{ needs.context.outputs.swift_crypto_revision }} 653 | swift_docc_render_artifact_revision: ${{ needs.context.outputs.swift_docc_render_artifact_revision }} 654 | swift_docc_revision: ${{ needs.context.outputs.swift_docc_revision }} 655 | swift_docc_symbolkit_revision: ${{ needs.context.outputs.swift_docc_symbolkit_revision }} 656 | swift_driver_revision: ${{ needs.context.outputs.swift_driver_revision }} 657 | swift_experimental_string_processing_revision: ${{ needs.context.outputs.swift_experimental_string_processing_revision }} 658 | swift_format_revision: ${{ needs.context.outputs.swift_format_revision }} 659 | swift_foundation_revision: ${{ needs.context.outputs.swift_foundation_revision }} 660 | swift_foundation_icu_revision: ${{ needs.context.outputs.swift_foundation_icu_revision }} 661 | swift_installer_scripts_revision: ${{ needs.context.outputs.swift_installer_scripts_revision }} 662 | swift_llbuild_revision: ${{ needs.context.outputs.swift_llbuild_revision }} 663 | swift_lmdb_revision: ${{ needs.context.outputs.swift_lmdb_revision }} 664 | swift_markdown_revision: ${{ needs.context.outputs.swift_markdown_revision }} 665 | swift_package_manager_revision: ${{ needs.context.outputs.swift_package_manager_revision }} 666 | swift_revision: ${{ needs.context.outputs.swift_revision }} 667 | swift_subprocess_revision: ${{ needs.context.outputs.swift_subprocess_revision }} 668 | swift_syntax_revision: ${{ needs.context.outputs.swift_syntax_revision }} 669 | swift_system_revision: ${{ needs.context.outputs.swift_system_revision }} 670 | swift_testing_revision: ${{ needs.context.outputs.swift_testing_revision }} 671 | swift_toolchain_sqlite_revision: ${{ needs.context.outputs.swift_toolchain_sqlite_revision }} 672 | swift_toolchain_sqlite_version: ${{ needs.context.outputs.swift_toolchain_sqlite_version }} 673 | swift_tools_protocols_revision: ${{ needs.context.outputs.swift_tools_protocols_revision }} 674 | swift_tools_support_core_revision: ${{ needs.context.outputs.swift_tools_support_core_revision }} 675 | zlib_revision: ${{ needs.context.outputs.zlib_revision }} 676 | zlib_version: ${{ needs.context.outputs.zlib_version }} 677 | ANDROID_API_LEVEL: ${{ needs.context.outputs.ANDROID_API_LEVEL }} 678 | ANDROID_CLANG_VERSION: ${{ needs.context.outputs.ANDROID_CLANG_VERSION }} 679 | ANDROID_NDK_VERSION: ${{ needs.context.outputs.ANDROID_NDK_VERSION }} 680 | debug_info: ${{ fromJSON(needs.context.outputs.debug_info) }} 681 | release: ${{ inputs.create_release }} 682 | signed: ${{ fromJSON(needs.context.outputs.signed) }} 683 | swift_version: ${{ needs.context.outputs.swift_version }} 684 | swift_tag: ${{ needs.context.outputs.swift_tag }} 685 | default_build_runner: ${{ needs.context.outputs[format('windows_{0}_build_runner', needs.context.outputs.windows_build_cpu)] }} 686 | compilers_build_runner: ${{ needs.context.outputs[format('windows_{0}_compilers_runner', needs.context.outputs.windows_build_cpu)] }} 687 | build_android: ${{ inputs.build_android }} 688 | python_version: ${{ needs.context.outputs.python_version }} 689 | python_download_locations: ${{ needs.context.outputs.python_download_locations }} 690 | use_host_toolchain: ${{ inputs.use_host_toolchain }} 691 | secrets: 692 | SYMBOL_SERVER_PAT: ${{ secrets.SYMBOL_SERVER_PAT }} 693 | CERTIFICATE: ${{ secrets.CERTIFICATE }} 694 | PASSPHRASE: ${{ secrets.PASSPHRASE }} 695 | R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} 696 | R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} 697 | R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} 698 | AZURE_SP_CREDENTIALS: ${{ secrets.AZURE_SP_CREDENTIALS }} 699 | TRUSTED_SIGNING_ACCOUNT: ${{ secrets.TRUSTED_SIGNING_ACCOUNT }} 700 | TRUSTED_SIGNING_TEST_PROFILE: ${{ secrets.TRUSTED_SIGNING_TEST_PROFILE }} 701 | TRUSTED_SIGNING_PROD_PROFILE: ${{ secrets.TRUSTED_SIGNING_PROD_PROFILE }} 702 | 703 | mac-build: 704 | # TODO: Enable the mac build. 705 | if: false 706 | needs: [context] 707 | name: macOS Swift Toolchains Build 708 | permissions: 709 | contents: read 710 | id-token: write 711 | attestations: write 712 | 713 | uses: ./.github/workflows/swift-toolchain.yml 714 | with: 715 | build_os: Darwin 716 | build_arch: arm64 717 | build_matrix: ${{ needs.context.outputs.darwin_build_matrix }} 718 | host_matrix: ${{ needs.context.outputs.darwin_host_matrix }} 719 | compilers_matrix: ${{ needs.context.outputs.darwin_compilers_matrix }} 720 | target_matrix: ${{ needs.context.outputs.darwin_target_matrix }} 721 | curl_revision: ${{ needs.context.outputs.curl_revision }} 722 | curl_version: ${{ needs.context.outputs.curl_version }} 723 | ds2_revision: ${{ needs.context.outputs.ds2_revision }} 724 | brotli_revision: ${{ needs.context.outputs.brotli_revision }} 725 | brotli_version: ${{ needs.context.outputs.brotli_version }} 726 | indexstore_db_revision: ${{ needs.context.outputs.indexstore_db_revision }} 727 | libxml2_revision: ${{ needs.context.outputs.libxml2_revision }} 728 | libxml2_version: ${{ needs.context.outputs.libxml2_version }} 729 | llvm_project_revision: ${{ needs.context.outputs.llvm_project_revision }} 730 | mimalloc_revision: ${{ needs.context.outputs.mimalloc_revision }} 731 | sourcekit_lsp_revision: ${{ needs.context.outputs.sourcekit_lsp_revision }} 732 | swift_argument_parser_revision: ${{ needs.context.outputs.swift_argument_parser_revision }} 733 | swift_asn1_revision: ${{ needs.context.outputs.swift_asn1_revision }} 734 | swift_atomics_revision: ${{ needs.context.outputs.swift_atomics_revision }} 735 | swift_build_revision: ${{ needs.context.outputs.swift_build_revision }} 736 | swift_certificates_revision: ${{ needs.context.outputs.swift_certificates_revision }} 737 | swift_cmark_revision: ${{ needs.context.outputs.swift_cmark_revision }} 738 | swift_cmark_version: ${{ needs.context.outputs.swift_cmark_version }} 739 | swift_collections_revision: ${{ needs.context.outputs.swift_collections_revision }} 740 | swift_corelibs_foundation_revision: ${{ needs.context.outputs.swift_corelibs_foundation_revision }} 741 | swift_corelibs_libdispatch_revision: ${{ needs.context.outputs.swift_corelibs_libdispatch_revision }} 742 | swift_corelibs_xctest_revision: ${{ needs.context.outputs.swift_corelibs_xctest_revision }} 743 | swift_crypto_revision: ${{ needs.context.outputs.swift_crypto_revision }} 744 | swift_docc_render_artifact_revision: ${{ needs.context.outputs.swift_docc_render_artifact_revision }} 745 | swift_docc_revision: ${{ needs.context.outputs.swift_docc_revision }} 746 | swift_docc_symbolkit_revision: ${{ needs.context.outputs.swift_docc_symbolkit_revision }} 747 | swift_driver_revision: ${{ needs.context.outputs.swift_driver_revision }} 748 | swift_experimental_string_processing_revision: ${{ needs.context.outputs.swift_experimental_string_processing_revision }} 749 | swift_format_revision: ${{ needs.context.outputs.swift_format_revision }} 750 | swift_foundation_revision: ${{ needs.context.outputs.swift_foundation_revision }} 751 | swift_foundation_icu_revision: ${{ needs.context.outputs.swift_foundation_icu_revision }} 752 | swift_installer_scripts_revision: ${{ needs.context.outputs.swift_installer_scripts_revision }} 753 | swift_llbuild_revision: ${{ needs.context.outputs.swift_llbuild_revision }} 754 | swift_lmdb_revision: ${{ needs.context.outputs.swift_lmdb_revision }} 755 | swift_markdown_revision: ${{ needs.context.outputs.swift_markdown_revision }} 756 | swift_package_manager_revision: ${{ needs.context.outputs.swift_package_manager_revision }} 757 | swift_revision: ${{ needs.context.outputs.swift_revision }} 758 | swift_subprocess_revision: ${{ needs.context.outputs.swift_subprocess_revision }} 759 | swift_syntax_revision: ${{ needs.context.outputs.swift_syntax_revision }} 760 | swift_system_revision: ${{ needs.context.outputs.swift_system_revision }} 761 | swift_testing_revision: ${{ needs.context.outputs.swift_testing_revision }} 762 | swift_toolchain_sqlite_revision: ${{ needs.context.outputs.swift_toolchain_sqlite_revision }} 763 | swift_toolchain_sqlite_version: ${{ needs.context.outputs.swift_toolchain_sqlite_version }} 764 | swift_tools_protocols_revision: ${{ needs.context.outputs.swift_tools_protocols_revision }} 765 | swift_tools_support_core_revision: ${{ needs.context.outputs.swift_tools_support_core_revision }} 766 | zlib_revision: ${{ needs.context.outputs.zlib_revision }} 767 | zlib_version: ${{ needs.context.outputs.zlib_version }} 768 | ANDROID_API_LEVEL: ${{ needs.context.outputs.ANDROID_API_LEVEL }} 769 | ANDROID_CLANG_VERSION: ${{ needs.context.outputs.ANDROID_CLANG_VERSION }} 770 | ANDROID_NDK_VERSION: ${{ needs.context.outputs.ANDROID_NDK_VERSION }} 771 | debug_info: ${{ fromJSON(needs.context.outputs.debug_info) }} 772 | release: false 773 | signed: ${{ fromJSON(needs.context.outputs.signed) }} 774 | swift_version: ${{ needs.context.outputs.swift_version }} 775 | swift_tag: ${{ needs.context.outputs.swift_tag }} 776 | default_build_runner: ${{ needs.context.outputs.mac_build_runner }} 777 | compilers_build_runner: ${{ needs.context.outputs.mac_build_runner }} 778 | python_version: ${{ needs.context.outputs.python_version }} 779 | python_download_locations: ${{ needs.context.outputs.python_download_locations }} 780 | secrets: 781 | SYMBOL_SERVER_PAT: ${{ secrets.SYMBOL_SERVER_PAT }} 782 | CERTIFICATE: ${{ secrets.CERTIFICATE }} 783 | PASSPHRASE: ${{ secrets.PASSPHRASE }} 784 | R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} 785 | R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} 786 | R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} 787 | 788 | snapshot: 789 | runs-on: ubuntu-latest 790 | needs: [context, windows-build] 791 | if: inputs.create_snapshot == true && github.event_name == 'schedule' 792 | steps: 793 | - uses: actions/checkout@v4.2.2 794 | with: 795 | ref: refs/heads/main 796 | show-progress: false 797 | 798 | - uses: actions/download-artifact@v4 799 | with: 800 | name: stable.xml 801 | 802 | - run: | 803 | git config --global user.name 'github-action[bot]' 804 | git config --global user.email 'github-actions[bot]@users.noreply.github.com' 805 | if ! git diff --exit-code ; then 806 | git add stable.xml 807 | git commit -m "repo: update stable revision snapshot ${{ needs.context.outputs.swift_tag }}" 808 | git push origin HEAD:main 809 | fi 810 | 811 | release: 812 | runs-on: ubuntu-latest 813 | needs: [context, windows-build] 814 | if: inputs.create_release == true 815 | steps: 816 | - uses: actions/download-artifact@v4 817 | with: 818 | name: Windows-amd64-installer-online 819 | path: ${{ github.workspace }}/tmp/online/amd64 820 | 821 | - uses: actions/download-artifact@v4 822 | with: 823 | name: Windows-arm64-installer-online 824 | path: ${{ github.workspace }}/tmp/online/arm64 825 | 826 | - uses: actions/download-artifact@v4 827 | with: 828 | name: Windows-amd64-installer-offline 829 | path: ${{ github.workspace }}/tmp/offline/amd64 830 | 831 | - uses: actions/download-artifact@v4 832 | with: 833 | name: Windows-arm64-installer-offline 834 | path: ${{ github.workspace }}/tmp/offline/arm64 835 | 836 | - name: Create Release 837 | env: 838 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 839 | run: | 840 | function upload_installer() { 841 | local input_file=$1 842 | local output_name=$2 843 | 844 | mv "${input_file}" "${output_name}" 845 | gh release upload ${{ needs.context.outputs.swift_tag }} "${output_name}" -R ${{ github.repository }} 846 | 847 | shasum -a 256 "${output_name}" > "${output_name}.sha256" 848 | gh release upload ${{ needs.context.outputs.swift_tag }} "${output_name}.sha256" -R ${{ github.repository }} 849 | } 850 | 851 | branch_version_string=${{ inputs.swift_version || '0.0.0' }} 852 | if [[ $branch_version_string == "0.0.0" ]]; then 853 | latest="true" 854 | else 855 | latest="false" 856 | fi 857 | 858 | # Create Release 859 | gh release create ${{ needs.context.outputs.swift_tag }} -R ${{ github.repository }} --latest=${latest} 860 | 861 | # Upload all installer variants 862 | upload_installer "${{ github.workspace }}/tmp/online/amd64/installer.exe" "installer-amd64.exe" 863 | upload_installer "${{ github.workspace }}/tmp/online/arm64/installer.exe" "installer-arm64.exe" 864 | upload_installer "${{ github.workspace }}/tmp/offline/amd64/installer.exe" "installer-offline-amd64.exe" 865 | upload_installer "${{ github.workspace }}/tmp/offline/arm64/installer.exe" "installer-offline-arm64.exe" 866 | --------------------------------------------------------------------------------