fix(build): close capnp codegen missing-dependency-edge race (bug-1798)
libxce_src listed only gen_srcs[0] (controller.capnp.c) as a source of
the static_library('xce', ...) target, never controller.capnp.h -- which
several library files (utils.c and others) reach only via #include.
Ninja had no build edge forcing the capnp custom_target to finish before
those files compiled, so a from-scratch build could schedule them first,
intermittently failing with "controller.capnp.h: No such file or
directory". This is the same symptom recorded across 5+ prior recurrences
in buglog.json since 2026-07-16, previously worked around by retrying the
build rather than root-caused.
Fix: pass the whole gen_srcs custom_target (not gen_srcs[0]) into
libxce_src -- Meson still compiles only its .c output, but now orders the
entire target's build after both outputs are generated. Verified via two
consecutive from-scratch `xce-build.sh lib debug` builds (no retry
needed), the full lib test suite (313/313), and an incremental controller
asan rebuild (1331/1331, 0 ASAN diagnostics) to confirm no regression.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019jaMf9QEwpugH2W9KAuc7f
This commit is contained in:
parent
38595099b9
commit
654c6e8c75
2 changed files with 38 additions and 1 deletions
|
|
@ -21642,6 +21642,30 @@
|
|||
],
|
||||
"occurrences": 3,
|
||||
"last_seen": "2026-09-09T23:30:00Z"
|
||||
},
|
||||
{
|
||||
"id": "bug-1798",
|
||||
"timestamp": "2026-09-10T06:57:00Z",
|
||||
"error_message": "Fresh (from-scratch) build fails intermittently with `fatal error: controller.capnp.h: No such file or directory` for one or more consumers of utils.h (e.g. utils.c.o), reported live by the user running `./tools/xce-build.sh all debug`. This is the root-cause fix for a class of failures already recorded across many prior recurrences in this buglog (see related_bugs) as an unexplained/unfixed 'ninja-race' -- this entry identifies and fixes the actual missing-dependency-edge cause at the meson.build level.",
|
||||
"file": "src/lib/meson.build",
|
||||
"root_cause": "The capnp code-generation custom_target (`gen_srcs`, line 6) produces TWO outputs, controller.capnp.c and controller.capnp.h, but `libxce_src` (line ~65) only listed `gen_srcs[0]` (the .c output) as a source of the `static_library('xce', ...)` target. controller.capnp.h is never itself listed as a source anywhere -- it is reached only via `#include \"controller.capnp.h\"` from utils.c and several other library files (hook.c, threshold.c, xlist.c, window.c, xceapi.c, wrap.c, zarray.c, htab.c, xstring.c, etc., all also part of libxce_src). Because indexing a multi-output custom_target (`gen_srcs[0]`) extracts only that one output for Meson's dependency-graph purposes, Ninja has no declared build edge requiring the codegen custom_target to finish before compiling those other, unrelated .c files. On an INCREMENTAL build this is invisible (the generated header from a prior build already exists on disk), which is why this session's own extensive controller-only `--incremental` rebuilds throughout the xce-test-cli-ux spec never hit it -- it only manifests on a genuinely from-scratch build (`rm -rf` + fresh `meson setup`, which `xce-build.sh <component> <profile>` does by default without `--incremental`), and even then only when ninja's scheduler happens to pick an unlucky order under parallelism -- explaining the long history of this exact symptom being reported as an intermittent, unfixed 'ninja-race' across at least 5 prior recorded recurrences (2026-07-16 through 2026-07-26) with no meson.build-level fix ever applied, only the workaround 'retry the build once'.",
|
||||
"fix": "FIXED (2026-09-10). Changed `libxce_src`'s first element from `gen_srcs[0]` to the unindexed `gen_srcs` (src/lib/meson.build). Passing the whole custom_target object (both outputs) to a target's `sources:` list is Meson's documented pattern for exactly this case: Meson still compiles only the recognized-source (.c) output, but now correctly orders the ENTIRE `static_library('xce', ...)` target's build (every compile job in it) after BOTH of the custom_target's outputs are generated -- closing the missing-dependency-edge gap with no other code or behavior change. (Tried first: adding a `depends: [gen_srcs]` kwarg directly to the `static_library()` call -- rejected immediately by this project's pinned Meson 1.9.1 with 'Got unknown keyword arguments \"depends\"', that kwarg is not supported on `static_library()`/`build_target()` in this version; reverted before landing on the working fix.) Verified: two consecutive from-scratch `src/tools/xce-build.sh lib debug` builds (the exact race scenario -- clean `rm -rf` + fresh `meson setup`, no `--incremental`) both succeeded on the first invocation with no retry; the full `lib` unit test suite (`xcelib_test`) passed 313/313 with 0 failures; a subsequent incremental `src/tools/xce-build.sh controller asan xce.build --incremental` rebuild (this session's own established validation command) also passed clean, 1331 Tests 0 Failures 0 Ignored, 9/9 meson suites OK, confirming no regression to the controller/xce_test build this session's own xce-test-cli-ux spec work depends on. A single or even double clean-build success does not, by the race's own probabilistic nature, provide 100% certainty the underlying scheduling race can never recur in some other unlucky ninja ordering -- but the fix addresses the actual, previously-undiagnosed structural root cause (a genuinely missing build-graph edge), not just a timing workaround, so it is expected to eliminate the race class entirely rather than merely reduce its likelihood. Does not address the separate, distinct apiserver<-libxce.a CGO-link race noted in one prior recurrence (2026-07-26) -- that is a different meson target (frontend/apiserver's go_build custom_target referencing @BUILD_ROOT@/lib/libxce.a via an env-var string, not this custom_target/static_library relationship) and remains unfixed.",
|
||||
"tags": [
|
||||
"meson",
|
||||
"build-system",
|
||||
"capnp",
|
||||
"controller.capnp.h",
|
||||
"ninja-race",
|
||||
"missing-dependency-edge",
|
||||
"libxce",
|
||||
"src/lib/meson.build",
|
||||
"root-cause-fix"
|
||||
],
|
||||
"related_bugs": [
|
||||
"bug-1439"
|
||||
],
|
||||
"occurrences": 1,
|
||||
"last_seen": "2026-09-10T06:57:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,20 @@ xce_select_parser = custom_target(
|
|||
],
|
||||
build_by_default: true)
|
||||
|
||||
libxce_src = [ gen_srcs[0],
|
||||
libxce_src = [ # bug-1798: pass the whole gen_srcs custom_target (both
|
||||
# controller.capnp.c AND controller.capnp.h), not just
|
||||
# gen_srcs[0] -- several files below (utils.c and others)
|
||||
# reach controller.capnp.h only via #include, which ninja
|
||||
# cannot see. Indexing to gen_srcs[0] dropped that header
|
||||
# from this target's declared outputs entirely, so a
|
||||
# from-scratch build had no dependency edge forcing capnp
|
||||
# codegen to finish before those files compiled,
|
||||
# intermittently failing with "controller.capnp.h: No such
|
||||
# file or directory" (recurring since 2026-07-16). Passing
|
||||
# the full custom_target compiles only its .c output (as
|
||||
# before) while ordering the ENTIRE target's build after
|
||||
# BOTH outputs are generated.
|
||||
gen_srcs,
|
||||
section_parser[0],
|
||||
rusage_parser[0],
|
||||
xce_resreq_parser[0],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue