Follow-up to the native-path guidance in #492 — thanks for v2026.8.26.2 and
openkal-llvm-runtime; the single-package flow works as documented (static
ELF, no PT_INTERP, qemu-verified). Scaling it to a 7-member C++23 modules
workspace surfaced two engine-side gaps. Verified on mcpp v2026.8.26.2,
llvm@22.1.8, x86_64-linux-musl, openkal-llvm-runtime@0.1.3.
A. Dependency-package module units don't get the openkal include set
With --target x86_64-linux-musl and openkal in the graph:
- Workspace-member units correctly receive the full openkal
-I set
(libcxx/libcxxabi/libunwind includes, musl arch/generated dirs, port
includes — 18 dirs).
- Dependency-package module units (e.g.
nlohmann.json's generated
module unit) receive none of it. They fall back to the clang driver's
default C++ headers — the toolchain's own libc++, configured for glibc.
Result: the std module BMI is openkal-flavored (correct — mcpp builds it
from openkal's llvm-generated/std.cppm), while dependency BMIs are
xim/glibc-flavored. Any TU importing both flavors fails on the first
template instantiation that touches declarations present in both header
sets:
.../include/c++/v1/istream:1245:26: error: reference to 'space' is ambiguous
note: candidate ... xim-x-llvm/22.1.8/include/c++/v1/__locale:321
note: candidate ... openkal-llvm-runtime-0.1.3/llvm/libcxx/include/__locale:302
Reproduces with: member A import std; + import nlohmann.json; +
stream >> token;.
Things that do not change this (tried): [target.<triple>].cxxflags
(doesn't propagate to dependency units), mcpp toolchain default llvm@22.1.8,
--cache local.
A second wrinkle: when other mcpp homes exist on the machine (~/.mcpp, a
project-local legacy home), dependency-unit configuration picks up their
host toolchain include set (xim libc++ + glibc + linux-headers -isystem
rows appear verbatim in compile_commands.json) even though MCPP_HOME
points elsewhere and the build is --target musl. With those homes removed
the units fall back to driver defaults as described above. The chosen
flavor also sticks in target/<triple>/*/resolution.json across runs.
Workaround we ship with (works, full workspace compiles + links
statically): a per-triple clang config file
$MCPP_HOME/registry/data/xpkgs/xim-x-llvm/22.1.8/bin/x86_64-unknown-linux-musl-clang++.cfg
containing the same 18 -I lines members get. Members re-receiving them is
a harmless dedup. Note it must be the -clang++.cfg name only — a bare
<triple>.cfg also applies to C compiles and breaks them (musl's internal
src/include headers use the hidden macro and must not be visible to
plain C dependency builds like mbedtls).
Suggested fix: pass the same target C++-ABI include set to dependency
package units that member units already get (and scope home discovery to
MCPP_HOME).
B. Global build-cache key omits the target axis
build-cache/v1/pkg/<ns>/<pkg>@<ver>/<hash> hits the same entry for host
and musl builds of the same dependency. Both directions observed:
- musl build reuses a host-flavored
nlohmann.json BMI → the ambiguity
above, even with the config-file workaround in place (the poisoned BMI
is simply reused, never recompiled).
- After a musl build populated the cache, a plain host
mcpp build
reused the musl/openkal-flavored BMI → same ambiguity mirrored on host.
- Worst form: two host builds with a changed configuration axis
(dependency graph edited; glibc headers resolved from a different home,
2.39 vs 2.44) still hit the same cache entry — the mixed BMIs then
crash the clang frontend outright (SIGSEGV in
ASTReader::FindExternalVisibleDeclsByName during deserialization)
instead of producing a readable diagnostic.
Workaround: purge the C++ dependency entries under build-cache/v1/pkg/
(and build-cache/v1/std) when switching targets or editing the
dependency graph. Suggested fix: include the target/C++-ABI/header-set
axis in the cache key.
Happy to provide full logs / compile_commands diffs.
Follow-up to the native-path guidance in #492 — thanks for v2026.8.26.2 and
openkal-llvm-runtime; the single-package flow works as documented (staticELF, no PT_INTERP, qemu-verified). Scaling it to a 7-member C++23 modules
workspace surfaced two engine-side gaps. Verified on mcpp v2026.8.26.2,
llvm@22.1.8, x86_64-linux-musl, openkal-llvm-runtime@0.1.3.
A. Dependency-package module units don't get the openkal include set
With
--target x86_64-linux-musland openkal in the graph:-Iset(libcxx/libcxxabi/libunwind includes, musl arch/generated dirs, port
includes — 18 dirs).
nlohmann.json's generatedmodule unit) receive none of it. They fall back to the clang driver's
default C++ headers — the toolchain's own libc++, configured for glibc.
Result: the
stdmodule BMI is openkal-flavored (correct — mcpp builds itfrom openkal's
llvm-generated/std.cppm), while dependency BMIs arexim/glibc-flavored. Any TU importing both flavors fails on the first
template instantiation that touches declarations present in both header
sets:
Reproduces with: member A
import std;+import nlohmann.json;+stream >> token;.Things that do not change this (tried):
[target.<triple>].cxxflags(doesn't propagate to dependency units),
mcpp toolchain default llvm@22.1.8,--cache local.A second wrinkle: when other mcpp homes exist on the machine (
~/.mcpp, aproject-local legacy home), dependency-unit configuration picks up their
host toolchain include set (xim libc++ + glibc + linux-headers
-isystemrows appear verbatim in
compile_commands.json) even thoughMCPP_HOMEpoints elsewhere and the build is
--target musl. With those homes removedthe units fall back to driver defaults as described above. The chosen
flavor also sticks in
target/<triple>/*/resolution.jsonacross runs.Workaround we ship with (works, full workspace compiles + links
statically): a per-triple clang config file
$MCPP_HOME/registry/data/xpkgs/xim-x-llvm/22.1.8/bin/x86_64-unknown-linux-musl-clang++.cfgcontaining the same 18
-Ilines members get. Members re-receiving them isa harmless dedup. Note it must be the
-clang++.cfgname only — a bare<triple>.cfgalso applies to C compiles and breaks them (musl's internalsrc/includeheaders use thehiddenmacro and must not be visible toplain C dependency builds like mbedtls).
Suggested fix: pass the same target C++-ABI include set to dependency
package units that member units already get (and scope home discovery to
MCPP_HOME).B. Global build-cache key omits the target axis
build-cache/v1/pkg/<ns>/<pkg>@<ver>/<hash>hits the same entry for hostand musl builds of the same dependency. Both directions observed:
nlohmann.jsonBMI → the ambiguityabove, even with the config-file workaround in place (the poisoned BMI
is simply reused, never recompiled).
mcpp buildreused the musl/openkal-flavored BMI → same ambiguity mirrored on host.
(dependency graph edited; glibc headers resolved from a different home,
2.39 vs 2.44) still hit the same cache entry — the mixed BMIs then
crash the clang frontend outright (SIGSEGV in
ASTReader::FindExternalVisibleDeclsByNameduring deserialization)instead of producing a readable diagnostic.
Workaround: purge the C++ dependency entries under
build-cache/v1/pkg/(and
build-cache/v1/std) when switching targets or editing thedependency graph. Suggested fix: include the target/C++-ABI/header-set
axis in the cache key.
Happy to provide full logs / compile_commands diffs.