Skip to content

Commit 33456a7

Browse files
CI scripts for Windows
1 parent d94f1af commit 33456a7

File tree

6 files changed

+819
-1
lines changed

6 files changed

+819
-1
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
run: make format-check PYTHON_RUN="uv run --group=format"
1919

2020
build-matrix:
21-
name: Build & Test
21+
name: Build & Test (Linux)
2222
runs-on: ubuntu-latest
2323
strategy:
2424
fail-fast: false
@@ -93,3 +93,17 @@ jobs:
9393
bash tools/earthly.sh -a +test/results.xml results.xml \
9494
--env=${{matrix.env}} \
9595
--${{matrix.vcpkg_arg}}
96+
97+
build-windows:
98+
name: Build & Test (Windows, VS 2022)
99+
strategy:
100+
matrix:
101+
arch: [x86, amd64, arm64]
102+
runs-on: windows-2022
103+
steps:
104+
- *checkout
105+
- name: Build & Test
106+
shell: pwsh
107+
# 17.* select VS 2022
108+
run: |
109+
tools/ci.ps1 -VSVersion 17.* -TargetArch "${{matrix.arch}}" -UseVcpkg

tools/ci.ps1

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
[CmdletBinding(PositionalBinding = $false)]
2+
param(
3+
# The MSVS version to be loaded
4+
[Parameter(Mandatory)]
5+
[string]$VSVersion,
6+
# The target architecture
7+
[Parameter(Mandatory)]
8+
[string]$TargetArch,
9+
# The configurations to be built
10+
[string[]]$Configs = @("Debug"; "RelWithDebInfo"),
11+
[int]$Jobs,
12+
[switch]$Fresh,
13+
[switch]$Clean,
14+
[switch]$UseVcpkg,
15+
[switch]$BuildTesting,
16+
[switch]$WarningsAsErrors,
17+
[switch]$Test
18+
)
19+
20+
$ErrorActionPreference = "Stop"
21+
22+
Import-Module $PSScriptRoot/vsutil -Force
23+
Import-Module $PSScriptRoot/uv -Force
24+
Import-Module $PSScriptRoot/cmake -Force
25+
26+
$this_dir = $PSScriptRoot
27+
28+
$root = Split-Path -Parent $this_dir
29+
30+
Write-Verbose "Loading uv environment..."
31+
$uv_env = Get-UvEnvironment -ArgumentList "--group=build"
32+
Write-Verbose "Loading MSVS environment..."
33+
$vs_env = Invoke-WithEnvironment $uv_env {
34+
Get-VsEnvironment -Version:$VSVersion -TargetArch:$TargetArch
35+
}
36+
# Set the CC and CXX env vars to point to MSVC to prevent Ninja generation from
37+
# attempting to use MinGW GCC instead, even if its available on the path
38+
$vs_env["CC"] = "cl.exe"
39+
$vs_env["CXX"] = "cl.exe"
40+
41+
Invoke-WithEnvironment $vs_env {
42+
$settings = @{
43+
AMONGOC_USE_PMM = $UseVcpkg;
44+
BUILD_TESTING = $Test;
45+
AMONGOC_COMPILE_WARNING_AS_ERROR = $WarningsAsErrors;
46+
CMAKE_CROSS_CONFIGS = $Configs -join ';';
47+
CMAKE_DEFAULT_CONFIGS = "all";
48+
}
49+
Build-CMakeProject -SourceDir $root -BuildDir $root/_build `
50+
-Settings $settings `
51+
-Generator "Ninja Multi-Config" `
52+
-Fresh:$Fresh -Clean:$Clean `
53+
-Jobs:$Jobs -Debug:$DebugPreference -Verbose:$VerbosePreference
54+
if ($Test) {
55+
Test-CMakeProject -BuildDir $root/_build -Configuration $Configs[0] -Progress -Jobs:$Jobs
56+
}
57+
}

tools/cmake.psm1

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
Import-Module $PSScriptRoot/util -Force
2+
3+
<#
4+
.SYNOPSIS
5+
Configure and/or build a CMake project
6+
.DESCRIPTION
7+
This command will configure, build, and optionally install a CMake project
8+
#>
9+
function Build-CMakeProject {
10+
[CmdletBinding(PositionalBinding = $false, DefaultParameterSetName = "configure-and-build")]
11+
param(
12+
# If set, only configure the project without building
13+
[Parameter(ParameterSetName = "configure")]
14+
[switch]
15+
$OnlyConfigure,
16+
# If set, only build without configuring
17+
[Parameter(ParameterSetName = "build")]
18+
[switch]
19+
$OnlyBuild,
20+
# The build directory for the project
21+
[Parameter(Mandatory)]
22+
[string]
23+
$BuildDir,
24+
# The source directory for the project
25+
[Parameter(ParameterSetName = "configure", Mandatory)]
26+
[Parameter(ParameterSetName = "configure-and-build", Mandatory)]
27+
[string]
28+
$SourceDir,
29+
# The CMake generator to use
30+
[Parameter(ParameterSetName = "configure")]
31+
[Parameter(ParameterSetName = "configure-and-build")]
32+
[string]
33+
$Generator,
34+
# If set, then CMake will perform a fresh configure
35+
[Parameter(ParameterSetName = "configure")]
36+
[Parameter(ParameterSetName = "configure-and-build")]
37+
[switch]
38+
$Fresh,
39+
# If set, the project will be installed to the given prefix
40+
[Parameter(ParameterSetName = "build")]
41+
[Parameter(ParameterSetName = "configure-and-build")]
42+
[string]
43+
$InstallPath,
44+
# A mapping of CMake settings that will be used during configuration
45+
[Parameter(ParameterSetName = "configure")]
46+
[Parameter(ParameterSetName = "configure-and-build")]
47+
[hashtable]
48+
$Settings = @{},
49+
# If set, clean before building
50+
[Parameter(ParameterSetName = "build")]
51+
[Parameter(ParameterSetName = "configure-and-build")]
52+
[switch]
53+
$Clean,
54+
# Number of parallel jobs to run
55+
[Parameter(ParameterSetName = "build")]
56+
[Parameter(ParameterSetName = "configure-and-build")]
57+
[int]
58+
$Jobs,
59+
# The CMake executable to be used
60+
[string]
61+
$CMakeExecutable = "cmake"
62+
)
63+
$ErrorActionPreference = "stop"
64+
65+
if ([string]::IsNullOrEmpty($BuildDir)) {
66+
$BuildDir = Join-Path $PWD "_build"
67+
}
68+
69+
if (-not $OnlyBuild) {
70+
$command = @($CMakeExecutable)
71+
if (-not [string]::IsNullOrEmpty($SourceDir)) {
72+
$command += "-S$SourceDir"
73+
}
74+
$command += "-B$BuildDir"
75+
if (-not [string]::IsNullOrEmpty($Generator)) {
76+
$command += "-G$Generator"
77+
}
78+
if ($Fresh) {
79+
$command += "--fresh"
80+
}
81+
foreach ($key in $Settings.Keys) {
82+
$command += "-D$key=$(Format-CMakeValue $Settings[$key])"
83+
}
84+
Join-CommandLineArgv $command | Invoke-Expression
85+
if ($LASTEXITCODE) {
86+
throw "CMake configuration failed [$LASTEXITCODE]"
87+
}
88+
}
89+
90+
if (-not $OnlyConfigure) {
91+
$command = @($CMakeExecutable)
92+
$command += "--build", $BuildDir
93+
if ($Clean) {
94+
$command += "--clean-first"
95+
}
96+
if ($Jobs) {
97+
$command += "--parallel", "$Jobs"
98+
}
99+
Write-Debug "Executing CMake command: $command"
100+
Join-CommandLineArgv $command | Invoke-Expression
101+
if ($LASTEXITCODE) {
102+
throw "CMake build failed [$LASTEXITCODE]"
103+
}
104+
}
105+
}
106+
107+
function Test-CMakeProject {
108+
[CmdletBinding(PositionalBinding = $false)]
109+
param(
110+
# The directory containing the build results of the project
111+
[Parameter(Mandatory)]
112+
[string]
113+
$BuildDir,
114+
# Number of parallel jobs to run for the test
115+
[int]$Jobs,
116+
# The CTest configuration to run
117+
[string]$Configuration,
118+
# The CTest executable to use
119+
[string]$CTestExecutable = "ctest",
120+
# Stop immediately on the first test failure
121+
[switch]
122+
$StopOnFailure,
123+
# Print test output on failure
124+
[switch]
125+
$OutputOnFailure,
126+
# Use concise progress reporting
127+
[switch]
128+
$Progress,
129+
# Only execute tests matching the given regular expression
130+
[switch]
131+
$OnlyMatching,
132+
# Remaining arguments that are forwarded to CTest directly
133+
[Parameter(ValueFromRemainingArguments)]
134+
[string[]]
135+
$ArgumentList = @()
136+
)
137+
$ErrorActionPreference = "stop"
138+
139+
$ctest_command = @($CTestExecutable)
140+
if (-not [string]::IsNullOrEmpty($Configuration)) {
141+
$ctest_command += "--build-config", $Configuration
142+
}
143+
if ($Verbose) {
144+
$ctest_command += "--verbose"
145+
}
146+
if ($StopOnFailure) {
147+
$ctest_command += "--stop-on-failure"
148+
}
149+
if ($Jobs) {
150+
$ctest_command += "--parallel", "$Jobs"
151+
}
152+
if ($OutputOnFailure) {
153+
$ctest_command += "--output-on-failure"
154+
}
155+
if ($Progress) {
156+
$ctest_command += "--progress"
157+
}
158+
if ($OnlyMatching) {
159+
$ctest_command += "--tests-regex", $OnlyMatching
160+
}
161+
$ctest_command += $ArgumentList
162+
163+
try {
164+
[void](Push-Location $BuildDir)
165+
Join-CommandLineArgv $ctest_command | Invoke-Expression
166+
if ($LASTEXITCODE) {
167+
throw "CTest test execution failed [$LASTEXITCODE]"
168+
}
169+
}
170+
finally {
171+
[void](Pop-Location)
172+
}
173+
}
174+
175+
function Format-CMakeValue($Value) {
176+
if ($Value -is [System.Boolean]) {
177+
if ($Value) { "TRUE" } else { "FALSE" }
178+
}
179+
elseif ($Value -is [array]) {
180+
return $Value | ForEach-Object { Format-CMakeValue $_ } | Join-String -Separator ';'
181+
}
182+
else {
183+
return "$Value"
184+
}
185+
}

0 commit comments

Comments
 (0)