Skip to content

Commit 622ab61

Browse files
committed
refactor(build): include-dir[-after] directives converge on the typed #249 channel
Review pass over the merged P0+P1 branch. Two spellings of the same decision survived the parallel tracks: - dep loop: after-dirs were spelled as raw private '-idirafter <dir>' flag pairs (written before #249 landed privateBuild.includeDirsAfter); the raw spelling bypasses the typed channel's per-dialect degradations (cl.exe /I, NASM -I). Now appendUniquePath into the typed slot. - root: after-dirs reached only the fingerprint mirror (manifest.buildConfig), never privateBuild — scanned units read privateBuild.includeDirsAfter, so 'mcpp:include-dir-after=' on the root was inert on compile edges. Both channels now mirrored for both kinds, matching the flag mirrors above. e2e 144 upgraded from 'directive accepted' to asserting -idirafter reaches build.ninja.
1 parent f0d2f19 commit 622ab61

2 files changed

Lines changed: 27 additions & 16 deletions

File tree

src/build/prepare.cppm

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3086,18 +3086,13 @@ prepare_build(bool print_fingerprint,
30863086
for (auto it = bcDep.includeDirs.begin() + incN;
30873087
it != bcDep.includeDirs.end(); ++it)
30883088
appendUniquePath(pkg.privateBuild.includeDirs, *it);
3089-
// No privateBuild slot exists for after-dirs (the -idirafter
3090-
// emission chain is #249's); spell them as private compile flags
3091-
// (two argv tokens, matching host_base_flags) so a dep gets the
3092-
// semantics today.
3089+
// After-dirs ride the same typed #249 channel
3090+
// (privateBuild.includeDirsAfter → per-unit -idirafter), which
3091+
// owns the per-dialect degradations (cl.exe /I, NASM -I) a raw
3092+
// flag spelling would bypass.
30933093
for (auto it = bcDep.includeDirsAfter.begin() + incAfterN;
3094-
it != bcDep.includeDirsAfter.end(); ++it) {
3095-
for (auto* dst : { &pkg.privateBuild.cflags,
3096-
&pkg.privateBuild.cxxflags }) {
3097-
dst->push_back("-idirafter");
3098-
dst->push_back(*it);
3099-
}
3100-
}
3094+
it != bcDep.includeDirsAfter.end(); ++it)
3095+
appendUniquePath(pkg.privateBuild.includeDirsAfter, *it);
31013096
}
31023097

31033098
// apply() may have added interface defines to packages' publicUsage
@@ -3243,11 +3238,20 @@ prepare_build(bool print_fingerprint,
32433238
pkg0.manifest.buildConfig.ldflags.insert(
32443239
pkg0.manifest.buildConfig.ldflags.end(),
32453240
bcRoot.ldflags.begin() + rldN, bcRoot.ldflags.end());
3246-
// include-dir directives: PRIVATE (already absolute from parse_line) —
3247-
// privateBuild only, never publicUsage (see the dep loop's rationale).
3241+
// include-dir[/-after] directives: PRIVATE (already absolute from
3242+
// parse_line) — privateBuild only, never publicUsage (see the dep
3243+
// loop's rationale). privateBuild is what scanned units read
3244+
// (scanner → localIncludeDirs[After]); the manifest mirror keeps the
3245+
// fingerprint metadata equivalent, same as the flag mirrors above.
32483246
for (auto it = bcRoot.includeDirs.begin() + rincN;
32493247
it != bcRoot.includeDirs.end(); ++it)
32503248
appendUniquePath(pkg0.privateBuild.includeDirs, *it);
3249+
pkg0.manifest.buildConfig.includeDirs.insert(
3250+
pkg0.manifest.buildConfig.includeDirs.end(),
3251+
bcRoot.includeDirs.begin() + rincN, bcRoot.includeDirs.end());
3252+
for (auto it = bcRoot.includeDirsAfter.begin() + rincAfterN;
3253+
it != bcRoot.includeDirsAfter.end(); ++it)
3254+
appendUniquePath(pkg0.privateBuild.includeDirsAfter, *it);
32513255
pkg0.manifest.buildConfig.includeDirsAfter.insert(
32523256
pkg0.manifest.buildConfig.includeDirsAfter.end(),
32533257
bcRoot.includeDirsAfter.begin() + rincAfterN,

tests/e2e/144_build_mcpp_include_dir.sh

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
# (`mcpp:cxxflag=-I…` + `mcpp:cflag=-I…`, unnormalized). Scenario: build.mcpp
66
# writes a header under MCPP_OUT_DIR and points include-dir at it (absolute);
77
# a source #includes it; the build succeeds with NO -I flag emitted manually.
8-
# Also: `mcpp:include-dir-after=` is accepted (no unknown-directive warning)
9-
# and both round-trip the directive cache. Its -idirafter ninja emission for
10-
# the root lands with #249; this test pins the directive+cache surface.
8+
# Also: `mcpp:include-dir-after=` rides the typed #249 channel end-to-end —
9+
# the emitted build.ninja must carry -idirafter for the directive dir — and
10+
# both directives round-trip the directive cache.
1111
set -e
1212

1313
TMP=$(mktemp -d)
@@ -64,6 +64,13 @@ grep -q "ignoring unknown directive" build1.log && {
6464
out="$("$MCPP" run 2>&1 | grep '^ANSWER=' | tail -1)"
6565
[[ "$out" == "ANSWER=42" ]] || { echo "FAIL: include dir not on the -I chain: $out"; exit 1; }
6666

67+
# include-dir-after reaches the compile edges as -idirafter (typed #249
68+
# channel: privateBuild.includeDirsAfter → localIncludeDirsAfter).
69+
ninja_file=$(find target -name build.ninja | head -1)
70+
grep -q -- "-idirafter.*vendor/sysinc" "$ninja_file" || {
71+
echo "FAIL: include-dir-after not emitted as -idirafter in build.ninja";
72+
grep -n "local_includes" "$ninja_file" | head; exit 1; }
73+
6774
# Cache round-trip: touch a source (defeats the whole-build fast path, keeps
6875
# build.mcpp inputs unchanged) → the cached include-dir record must reapply
6976
# without a re-run, and the header must still resolve.

0 commit comments

Comments
 (0)