Skip to content

Commit 1b4c117

Browse files
committed
fix: rpath only dependency runtime dirs; update first-run default test
R2 precision: baking ALL of plan.runtimeLibraryDirs into -L/-rpath pulled the glibc payload dir into musl/static links (undefined _DYNAMIC; broke e2e 28/30). Split out plan.depRuntimeLibraryDirs (dependency [runtime] library_dirs only, e.g. compat.glx-runtime) and emit toolchain.linkRuntimeDirs + dep dirs, as before plus the dep closure. e2e 29 updated for the intentional glibc first-run default (musl-static is opt-in via --target).
1 parent eade49e commit 1b4c117

3 files changed

Lines changed: 28 additions & 18 deletions

File tree

src/build/flags.cppm

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,16 @@ CompileFlags compute_flags(const BuildPlan& plan) {
262262
std::string static_stdlib = (f.staticStdlib && !isClang && !mcpp::platform::is_windows) ? " -static-libstdc++" : "";
263263
std::string runtime_dirs;
264264
if constexpr (mcpp::platform::supports_rpath) {
265-
// Bake ALL resolved runtime library dirs into the binary's RUNPATH —
266-
// not just the toolchain's. plan.runtimeLibraryDirs is the union of
267-
// dependency packages' [runtime] library_dirs (e.g. compat.glx-runtime's
268-
// host-GL passthrough dir) plus the toolchain/payload dirs. Using only
269-
// toolchain.linkRuntimeDirs here dropped dependency runtime dirs, so
270-
// dlopen()'d host libs (libGL/libGLX) were unreachable at run time.
271-
for (auto& dir : plan.runtimeLibraryDirs) {
265+
// Toolchain runtime dirs (glibc/gcc) as before...
266+
for (auto& dir : plan.toolchain.linkRuntimeDirs) {
267+
runtime_dirs += " -L" + escape_path(dir);
268+
runtime_dirs += " -Wl,-rpath," + escape_path(dir);
269+
}
270+
// ...plus dependency packages' [runtime] library_dirs (e.g.
271+
// compat.glx-runtime's host-GL passthrough), so dlopen()'d host libs
272+
// (libGL/libGLX) are reachable at run time. Only the dep dirs — NOT the
273+
// glibc payload dir — so static/musl links stay clean.
274+
for (auto& dir : plan.depRuntimeLibraryDirs) {
272275
runtime_dirs += " -L" + escape_path(dir);
273276
runtime_dirs += " -Wl,-rpath," + escape_path(dir);
274277
}

src/build/plan.cppm

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ struct BuildPlan {
5656
std::vector<CompileUnit> compileUnits; // topologically sorted
5757
std::vector<LinkUnit> linkUnits;
5858
std::vector<std::filesystem::path> runtimeLibraryDirs;
59+
// ONLY the dependency packages' [runtime] library_dirs (not toolchain/
60+
// payload dirs). These are the dirs that must be baked into the produced
61+
// binary's RUNPATH (e.g. compat.glx-runtime). Kept separate so static/musl
62+
// links don't pull the glibc payload dir.
63+
std::vector<std::filesystem::path> depRuntimeLibraryDirs;
5964
// Aggregated host-runtime requirements from dependency packages'
6065
// [runtime] metadata. Capability/provider-driven — no platform special-casing
6166
// in mcpp: providers (e.g. compat.glx-runtime) declare these per platform.
@@ -225,8 +230,9 @@ BuildPlan make_plan(const mcpp::manifest::Manifest& manifest,
225230

226231
for (auto const& package : packages) {
227232
for (auto const& dir : package.manifest.runtimeConfig.libraryDirs) {
228-
append_unique_path(plan.runtimeLibraryDirs,
229-
dir.is_absolute() ? dir : package.root / dir);
233+
auto abs = dir.is_absolute() ? dir : package.root / dir;
234+
append_unique_path(plan.runtimeLibraryDirs, abs);
235+
append_unique_path(plan.depRuntimeLibraryDirs, abs);
230236
}
231237
for (auto const& lib : package.manifest.runtimeConfig.dlopenLibs) {
232238
if (std::ranges::find(plan.runtimeDlopenLibs, lib) == plan.runtimeDlopenLibs.end())

tests/e2e/29_toolchain_partial_versions.sh

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ grep -q 'gcc@16.1.0' "$TMP/def2.log" || {
5252
# ─── Section 2: first-run auto-install ──────────────────────────────────
5353
# Brand-new MCPP_HOME with no config/default state, brand-new package with no
5454
# [toolchain] declared — `mcpp build` should auto-install the canonical
55-
# default (musl-gcc 15.1 for portable static binaries) + use it. We still
56-
# inherit payloads so CI does not download the same large archives into a
57-
# throw-away home.
55+
# default (platform-native glibc gcc — musl-static is opt-in via --target) +
56+
# use it. We still inherit payloads so CI does not download the same large
57+
# archives into a throw-away home.
5858
export MCPP_HOME="$TMP/h2"
5959
inherit_payloads_only
6060
configure_e2e_mirror
@@ -75,20 +75,21 @@ fi
7575
# Must show the friendly first-run banner AND the build must succeed.
7676
grep -q 'First run' "$TMP/firstrun.log" || {
7777
cat "$TMP/firstrun.log"; echo "missing First-run banner"; exit 1; }
78-
grep -q 'gcc@15.1.0-musl' "$TMP/firstrun.log" || {
79-
cat "$TMP/firstrun.log"; echo "first run didn't pick gcc@15.1.0-musl as default"; exit 1; }
78+
grep -q 'gcc@16.1.0' "$TMP/firstrun.log" || {
79+
cat "$TMP/firstrun.log"; echo "first run didn't pick glibc gcc@16.1.0 as default"; exit 1; }
8080
grep -q 'Finished' "$TMP/firstrun.log" || {
8181
cat "$TMP/firstrun.log"; echo "build did not finish"; exit 1; }
8282

83-
# Built binary must exist, run, AND be statically linked (because the
84-
# default toolchain is musl, mcpp infers `linkage = static` automatically).
83+
# Built binary must exist and run. The default toolchain is now platform-native
84+
# glibc gcc (musl-static is opt-in via --target), so it is dynamically linked.
8585
binary=$(find target -name hello -type f | head -1)
8686
[[ -n "$binary" && -x "$binary" ]] || { echo "no hello binary produced"; exit 1; }
87-
file "$binary" | grep -q 'statically linked' || {
87+
file "$binary" | grep -q 'statically linked' && {
8888
file "$binary"
89-
echo "first-run build is not statically linked; musl default not propagated"
89+
echo "first-run default unexpectedly produced a static binary (glibc default expected)"
9090
exit 1
9191
}
92+
"$binary" >/dev/null 2>&1 || { echo "first-run binary did not run"; exit 1; }
9293

9394
# Second build should be silent on toolchain — no re-install banner.
9495
"$MCPP" build > "$TMP/secondrun.log" 2>&1 || {

0 commit comments

Comments
 (0)