Skip to content

Commit aab241c

Browse files
committed
Align CI with CMake standards: dedicated build modes and matrix fixes (#186)
Key changes: - Dedicate a single superproject-cmake matrix entry (GCC latest) for CMake superproject build and both integration tests, moving sparse checkout disable behind the superproject-cmake flag - Run standalone CMake from library root (corosio-root) instead of boost-root, building all targets without a build-target filter - Add clang-tidy as standalone configure-only step against corosio-root with version-parametric binary and include/src file filtering - Add FlameGraph compile-time profiling for Clang time-trace variant - Gate B2 on !coverage && !time-trace && !superproject-cmake && !clang-tidy - Gate standalone CMake on build-cmake || coverage - Add is_earliest to GCC 12, Clang 17, MSVC 14.34, Apple-Clang macos-14 so oldest compilers also run standalone CMake builds - Fix generate-matrix.py to emit generator-toolset (hyphen) matching ci.yml references, and read shared/vcpkg_triplet from compiler specs - Skip ASAN+UBSAN variant for MinGW (limited sanitizer support) - Restore zip/unzip/tar packages needed by vcpkg in container builds - Update cmake_test version range to 3.13...3.31
1 parent 504d294 commit aab241c

5 files changed

Lines changed: 174 additions & 112 deletions

File tree

.github/compilers.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"container": "ubuntu:22.04",
99
"cxx": "g++-12",
1010
"cc": "gcc-12",
11-
"b2_toolset": "gcc"
11+
"b2_toolset": "gcc",
12+
"is_earliest": true
1213
},
1314
{
1415
"version": "13",
@@ -52,7 +53,8 @@
5253
"cxx": "clang++-17",
5354
"cc": "clang-17",
5455
"b2_toolset": "clang",
55-
"arm": true
56+
"arm": true,
57+
"is_earliest": true
5658
},
5759
{
5860
"version": "18",
@@ -95,7 +97,8 @@
9597
"latest_cxxstd": "20",
9698
"runs_on": "windows-2022",
9799
"b2_toolset": "msvc-14.3",
98-
"generator": "Visual Studio 17 2022"
100+
"generator": "Visual Studio 17 2022",
101+
"is_earliest": true
99102
},
100103
{
101104
"version": "14.42",
@@ -130,7 +133,8 @@
130133
"runs_on": "macos-14",
131134
"cxx": "clang++",
132135
"cc": "clang",
133-
"b2_toolset": "clang"
136+
"b2_toolset": "clang",
137+
"is_earliest": true
134138
},
135139
{
136140
"version": "*",

.github/generate-matrix.py

Lines changed: 73 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def load_compilers(path=None):
3232

3333

3434
def platform_for_family(compiler_family):
35-
"""Return the platform boolean name for a compiler family."""
35+
"""Return the platform name for a compiler family."""
3636
if compiler_family in ("msvc", "clang-cl", "mingw"):
3737
return "windows"
3838
elif compiler_family == "apple-clang":
@@ -51,12 +51,9 @@ def make_entry(compiler_family, spec, **overrides):
5151
"b2-toolset": spec["b2_toolset"],
5252
"shared": True,
5353
"build-type": "Release",
54-
"build-cmake": True,
54+
platform_for_family(compiler_family): True,
5555
}
5656

57-
# Platform boolean
58-
entry[platform_for_family(compiler_family)] = True
59-
6057
if spec.get("container"):
6158
entry["container"] = spec["container"]
6259
if spec.get("cxx"):
@@ -71,40 +68,33 @@ def make_entry(compiler_family, spec, **overrides):
7168
entry["is-latest"] = True
7269
if spec.get("is_earliest"):
7370
entry["is-earliest"] = True
71+
if "shared" in spec:
72+
entry["shared"] = spec["shared"]
73+
if spec.get("vcpkg_triplet"):
74+
entry["vcpkg-triplet"] = spec["vcpkg_triplet"]
75+
76+
# CMake builds only on earliest/latest compilers, unless explicitly disabled
7477
if spec.get("build_cmake") is False:
7578
entry["build-cmake"] = False
79+
elif spec.get("is_latest") or spec.get("is_earliest"):
80+
entry["build-cmake"] = True
7681
if spec.get("cmake_cxxstd"):
7782
entry["cmake-cxxstd"] = spec["cmake_cxxstd"]
7883
if spec.get("cxxflags"):
7984
entry["cxxflags"] = spec["cxxflags"]
80-
if "shared" in spec:
81-
entry["shared"] = spec["shared"]
82-
if spec.get("vcpkg_triplet"):
83-
entry["vcpkg-triplet"] = spec["vcpkg_triplet"]
8485

8586
entry.update(overrides)
8687
entry["name"] = generate_name(compiler_family, entry)
8788
return entry
8889

8990

90-
def apply_clang_tidy(entry, spec):
91-
"""Add clang-tidy flag and install package to an entry (base entries only)."""
92-
entry["clang-tidy"] = True
93-
version = spec["version"]
94-
existing_install = entry.get("install", "")
95-
tidy_pkg = f"clang-tidy-{version}"
96-
entry["install"] = f"{existing_install} {tidy_pkg}".strip()
97-
entry["name"] = generate_name(entry["compiler"], entry)
98-
return entry
99-
100-
10191
def generate_name(compiler_family, entry):
10292
"""Generate a human-readable job name from entry fields."""
10393
name_map = {
10494
"gcc": "GCC",
10595
"clang": "Clang",
10696
"msvc": "MSVC",
107-
"mingw": "MinGW",
97+
"mingw": "MinGW Clang",
10898
"clang-cl": "Clang-CL",
10999
"apple-clang": "Apple-Clang",
110100
}
@@ -123,6 +113,7 @@ def generate_name(compiler_family, entry):
123113
if "arm" in runner:
124114
modifiers.append("arm64")
125115
elif compiler_family == "apple-clang":
116+
# Extract macOS version from runner name
126117
macos_ver = runner.replace("macos-", "macOS ")
127118
modifiers.append(macos_ver)
128119

@@ -138,11 +129,17 @@ def generate_name(compiler_family, entry):
138129
if entry.get("coverage"):
139130
modifiers.append("coverage")
140131

132+
if entry.get("x86"):
133+
modifiers.append("x86")
134+
141135
if entry.get("clang-tidy"):
142136
modifiers.append("clang-tidy")
143137

144-
if entry.get("x86"):
145-
modifiers.append("x86")
138+
if entry.get("time-trace"):
139+
modifiers.append("time-trace")
140+
141+
if entry.get("superproject-cmake"):
142+
modifiers.append("superproject CMake")
146143

147144
if entry.get("shared") is False:
148145
modifiers.append("static")
@@ -154,7 +151,7 @@ def generate_name(compiler_family, entry):
154151
def generate_sanitizer_variant(compiler_family, spec):
155152
"""Generate ASAN+UBSAN variant for the latest compiler in a family.
156153
157-
MSVC and Clang-CL only support ASAN, not UBSAN.
154+
MSVC does not support UBSAN; only ASAN is enabled for MSVC.
158155
"""
159156
overrides = {
160157
"asan": True,
@@ -163,6 +160,7 @@ def generate_sanitizer_variant(compiler_family, spec):
163160
"build-cmake": False,
164161
}
165162

163+
# MSVC and Clang-CL only support ASAN, not UBSAN
166164
if compiler_family not in ("msvc", "clang-cl"):
167165
overrides["ubsan"] = True
168166

@@ -188,39 +186,35 @@ def generate_tsan_variant(compiler_family, spec):
188186

189187

190188
def generate_coverage_variant(compiler_family, spec):
191-
"""Generate coverage variant.
189+
"""Generate coverage variant with platform-specific flags.
192190
193-
Corosio has three coverage builds:
194-
- Linux (GCC): lcov with full profiling flags
195-
- macOS (Apple-Clang): --coverage only, gcovr with llvm-cov
196-
- Windows (MinGW): gcovr with full profiling flags
191+
Linux/Windows: full gcov flags with atomic profile updates.
192+
macOS: --coverage only (Apple-Clang uses llvm-cov).
197193
"""
198194
platform = platform_for_family(compiler_family)
199195

200196
if platform == "macos":
201-
flags = "--coverage"
197+
cov_flags = "--coverage"
202198
else:
203-
flags = "--coverage -fprofile-arcs -ftest-coverage -fprofile-update=atomic"
199+
cov_flags = ("--coverage -fprofile-arcs -ftest-coverage"
200+
" -fprofile-update=atomic")
204201

205202
overrides = {
206203
"coverage": True,
207204
"coverage-flag": platform,
208205
"shared": False,
209206
"build-type": "Debug",
210-
"cxxflags": flags,
211-
"ccflags": flags,
207+
"build-cmake": False,
208+
"cxxflags": cov_flags,
209+
"ccflags": cov_flags,
212210
}
213211

214212
if platform == "linux":
215213
overrides["install"] = "lcov wget unzip"
216214

217215
entry = make_entry(compiler_family, spec, **overrides)
218-
# Coverage variants should not trigger integration tests; they get CMake
219-
# through the matrix.coverage condition in ci.yml
220216
entry.pop("is-latest", None)
221217
entry.pop("is-earliest", None)
222-
entry["build-cmake"] = False
223-
entry["name"] = generate_name(compiler_family, entry)
224218
return entry
225219

226220

@@ -235,12 +229,44 @@ def generate_x86_variant(compiler_family, spec):
235229
def generate_arm_entry(compiler_family, spec):
236230
"""Generate ARM64 variant for a compiler spec."""
237231
arm_runner = spec["runs_on"].replace("ubuntu-24.04", "ubuntu-24.04-arm")
238-
# ARM runners don't support containers
232+
# ARM runners don't support containers — build a spec copy without container
239233
arm_spec = {k: v for k, v in spec.items() if k != "container"}
240234
arm_spec["runs_on"] = arm_runner
241235
return make_entry(compiler_family, arm_spec)
242236

243237

238+
def generate_time_trace_variant(compiler_family, spec):
239+
"""Generate time-trace variant for compile-time profiling (Clang only)."""
240+
return make_entry(compiler_family, spec, **{
241+
"time-trace": True,
242+
"build-cmake": True,
243+
"cxxflags": "-ftime-trace",
244+
})
245+
246+
247+
def generate_superproject_cmake_variant(compiler_family, spec):
248+
"""Generate a single superproject CMake build to verify integration."""
249+
entry = make_entry(compiler_family, spec, **{
250+
"superproject-cmake": True,
251+
"build-cmake": False,
252+
})
253+
entry.pop("is-latest", None)
254+
entry.pop("is-earliest", None)
255+
return entry
256+
257+
258+
def apply_clang_tidy(entry, spec):
259+
"""Add clang-tidy flag and install package to an entry."""
260+
entry["clang-tidy"] = True
261+
entry["build-cmake"] = False
262+
version = spec["version"]
263+
existing_install = entry.get("install", "")
264+
tidy_pkg = f"clang-tidy-{version}"
265+
entry["install"] = f"{existing_install} {tidy_pkg}".strip()
266+
entry["name"] = generate_name(entry["compiler"], entry)
267+
return entry
268+
269+
244270
def main():
245271
compilers = load_compilers()
246272
matrix = []
@@ -259,20 +285,23 @@ def main():
259285

260286
# Variants for the latest compiler in each family
261287
if spec.get("is_latest"):
262-
# MinGW has limited ASAN support; skip sanitizer variant
263288
if family != "mingw":
264289
matrix.append(generate_sanitizer_variant(family, spec))
265290

266-
# TSan is incompatible with ASan; separate variant for GCC, Clang, and Apple-Clang
291+
# TSan is incompatible with ASan; separate variant for Linux
267292
if family in ("gcc", "clang", "apple-clang"):
268293
matrix.append(generate_tsan_variant(family, spec))
269294

295+
# GCC always gets coverage; other families opt in via spec flag
296+
if family == "gcc" or spec.get("coverage"):
297+
matrix.append(generate_coverage_variant(family, spec))
298+
299+
if family == "gcc":
300+
matrix.append(generate_superproject_cmake_variant(family, spec))
301+
270302
if family == "clang":
271303
matrix.append(generate_x86_variant(family, spec))
272-
273-
# Coverage variant (driven by spec flag, not is_latest)
274-
if spec.get("coverage"):
275-
matrix.append(generate_coverage_variant(family, spec))
304+
matrix.append(generate_time_trace_variant(family, spec))
276305

277306
json.dump(matrix, sys.stdout)
278307

0 commit comments

Comments
 (0)