From 8e18097b7bff38314ae3bcdefd7679f74bc85ee8 Mon Sep 17 00:00:00 2001 From: chrg6 Date: Tue, 10 Nov 2026 23:12:30 -0500 Subject: [PATCH] Pass the link map's path to the linker with -Xlinker, so a comma in the game folder's path no longer fails the link. make_game.py passed the map as -Wl,--Map=/build-cache/ocarina.map, and -Wl, cuts its argument at every comma: with a comma in the folder's path the part after it reached the linker as an input file and an update ended with "the link failed" (issue #470). -Xlinker hands the path over as one argument. build_game.py already did so on Windows and now does on Linux too. With MSYS2's clang and ld here, a link into a folder named "a, b" fails with the -Wl, form ("cannot find b/t.map") and writes the map with -Xlinker. Co-Authored-By: Claude Fable 5.2 --- tools/build_game.py | 3 ++- tools/make_game.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/build_game.py b/tools/build_game.py index 7323de3e..3dd76eb4 100644 --- a/tools/build_game.py +++ b/tools/build_game.py @@ -151,8 +151,9 @@ if WIN: else: # -no-pie: the lifted modules' function tables (hundreds of thousands of pointers) need no load-time relocation. # $ORIGIN: a libSDL3.so.0 next to nx2navi comes before the system's (the release's portable folder). + # -Xlinker for the map path, as on Windows above: -Wl, would split it at any comma in the build dir path. LINK_FLAGS = ['-fuse-ld=lld', '-no-pie', '-Wl,-z,noexecstack', "'-Wl,-rpath,$$ORIGIN'", - '"-Wl,-Map=$builddir/nx2navi.map"'] + '-Xlinker', '"-Map=$builddir/nx2navi.map"'] LINK_LIBS = ['-lvulkan', '-lSDL3', '-lopus', '-ldav1d', '-lvpx', '-lzstd', '-l:libstdc++.a', '-lm', '-lpthread', '-ldl'] VMA_INCLUDE = Path('/usr/include') # vk_mem_alloc.h; Arch (AUR) vulkan-memory-allocator, Debian libvulkan-memory-allocator-dev # Without a system vk_mem_alloc.h, the header the Windows release pins (tools/make_release.py, VMA 3.4.0) is fetched once diff --git a/tools/make_game.py b/tools/make_game.py index 93ff692b..bb4e304c 100644 --- a/tools/make_game.py +++ b/tools/make_game.py @@ -1701,8 +1701,9 @@ def step_compile(out, cache_dir, msys, jobs, romfs_job=None, update=False): ld = (['-fuse-ld=lld'] if (msys / 'bin' / 'ld.lld.exe').is_file() else []) + ['-Wl,--stack,16777216'] else: # tools/build_game.py's Linux flags; the main thread's stack is the process's (ulimit -s), not the linker's ld = (['-fuse-ld=lld'] if shutil.which('ld.lld') else []) + ['-no-pie', '-Wl,-z,noexecstack', '-Wl,-rpath,$ORIGIN'] - # the link map feeds tools/prof_report.py (symbols for an NX2NAVI_PROFILE sampling profile); both linkers write one - ld.append('-Wl,--Map=' + (cache_dir / 'ocarina.map').as_posix()) + # the link map feeds tools/prof_report.py (symbols for an NX2NAVI_PROFILE sampling profile); both linkers write one. + # -Xlinker passes the path as one argument; -Wl, would cut it at every comma of the game folder's path (issue #470) + ld += ['-Xlinker', '--Map=' + (cache_dir / 'ocarina.map').as_posix()] lib = ['-Wl,--whole-archive', str(prebuilt[0]), '-Wl,--no-whole-archive'] if prebuilt else [] stamp = [[o.name, o.stat().st_size, o.stat().st_mtime_ns] for o in objs] if prebuilt: