11#! /usr/bin/env bash
22# 85_target_cfg_build_flags.sh — L1 platform-conditional config: a normal mcpp.toml
3- # can scope [build] flags to a target predicate via `[target.'cfg(...)'.build]`.
4- # The predicate is evaluated against the RESOLVED TARGET (here: the host build's
5- # own triple), NOT textually — so `cfg(linux)`/`cfg(unix)` flags apply on a Linux
6- # runner and `cfg(windows)` flags do NOT. See
3+ # scopes [build] flags to a target predicate via `[target.'cfg(...)'.build]`. The
4+ # predicate is evaluated against the RESOLVED target (here the host, a native
5+ # build) — NOT textually — so exactly the host's os/arch predicates apply. This
6+ # test is HOST-AWARE: it asserts the correct subset applies on whichever of
7+ # linux/macos/windows + x86_64/aarch64 the runner is, so it validates the
8+ # evaluator on all three CI platforms. See
79# .agents/docs/2026-06-29-manifest-environment-and-platform-design.md (L1).
8- #
9- # requires: linux
1010set -e
1111
1212TMP=$( mktemp -d)
@@ -19,46 +19,49 @@ cat > app/mcpp.toml <<'EOF'
1919name = "app"
2020version = "0.1.0"
2121
22- # Matching predicate (Linux host) → these cxxflags apply.
2322[target.'cfg(linux)'.build]
2423cxxflags = ["-DCOND_LINUX=1"]
25-
26- # Also matches on Linux (unix family alias).
27- [target.'cfg(unix)'.build]
28- cxxflags = ["-DCOND_UNIX=1"]
29-
30- # Non-matching predicate → must NOT apply on a Linux build.
24+ [target.'cfg(macos)'.build]
25+ cxxflags = ["-DCOND_MACOS=1"]
3126[target.'cfg(windows)'.build]
3227cxxflags = ["-DCOND_WIN=1"]
33-
34- # Boolean combinator: linux AND NOT aarch64 (x86_64 runner) → applies.
35- [target.'cfg(all(linux, not(arch = "aarch64")))'.build]
36- cxxflags = ["-DCOND_X64_LINUX=1"]
28+ [target.'cfg(unix)'.build]
29+ cxxflags = ["-DCOND_UNIX=1"]
30+ [target.'cfg(arch = "x86_64")'.build]
31+ cxxflags = ["-DCOND_X64=1"]
32+ [target.'cfg(arch = "aarch64")'.build]
33+ cxxflags = ["-DCOND_ARM64=1"]
34+ # Boolean combinator: any(linux, macos) == unix-family.
35+ [target.'cfg(any(linux, macos))'.build]
36+ cxxflags = ["-DCOND_UNIXLIKE=1"]
3737EOF
3838cat > app/src/main.cpp << 'EOF '
39- // The conditional cxxflags must reach this TU. Missing/!expected → #error .
40- #ifndef COND_LINUX
41- #error "cfg(linux) cxxflag did not apply on a Linux build "
39+ // Exactly one OS predicate must apply (the host's), regardless of platform .
40+ #if (defined( COND_LINUX) + defined(COND_MACOS) + defined(COND_WIN)) != 1
41+ #error "exactly one of cfg(linux)/cfg(macos)/cfg(windows) must apply on any host "
4242#endif
43- #ifndef COND_UNIX
44- #error "cfg(unix) cxxflag did not apply on a Linux build"
43+ // cfg(unix) applies iff not windows.
44+ #if defined(COND_WIN) && defined(COND_UNIX)
45+ #error "cfg(unix) wrongly applied on a windows host"
4546#endif
46- #ifdef COND_WIN
47- #error "cfg(windows) cxxflag wrongly applied on a Linux build "
47+ #if !defined( COND_WIN) && !defined(COND_UNIX)
48+ #error "cfg(unix) should apply on a non-windows host "
4849#endif
49- #ifndef COND_X64_LINUX
50- #error "cfg(all(linux, not(arch=aarch64))) cxxflag did not apply on x86_64 Linux"
50+ // any(linux, macos) must agree with unix on the CI platforms.
51+ #if defined(COND_UNIXLIKE) != defined(COND_UNIX)
52+ #error "cfg(any(linux,macos)) disagreed with cfg(unix)"
5153#endif
54+ // Exactly one arch predicate must apply on the CI runners (x86_64 or aarch64).
55+ #if (defined(COND_X64) + defined(COND_ARM64)) != 1
56+ #error "exactly one of cfg(arch=x86_64)/cfg(arch=aarch64) must apply"
57+ #endif
58+ // Mutual exclusion: the non-host OS predicate must NOT leak in.
5259int main() { return 0; }
5360EOF
5461
5562cd app
56- " $MCPP " build > b.log 2>&1 || { cat b.log; echo " FAIL: build errored (conditional flag mis-applied?)" ; exit 1; }
57-
58- # The matching flag must be on the consumer TU; the non-matching one must not.
59- grep -q ' COND_LINUX=1' compile_commands.json || { echo " FAIL: cfg(linux) flag absent from compile db" ; exit 1; }
60- grep -q ' COND_X64_LINUX=1' compile_commands.json || { echo " FAIL: cfg(all/not) flag absent" ; exit 1; }
61- if grep -q ' COND_WIN=1' compile_commands.json; then
62- echo " FAIL: cfg(windows) flag leaked into a Linux build's compile db" ; exit 1; fi
63+ # The #error guards ARE the assertion: a clean build proves the right conditional
64+ # cxxflags reached the TU and the wrong ones did not.
65+ " $MCPP " build > b.log 2>&1 || { cat b.log; echo " FAIL: conditional cfg flags mis-applied for this host" ; exit 1; }
6366
6467echo " OK"
0 commit comments