Repository navigation
fix(build): link when the build files folder's path has a comma - #2137
Conversation
|
Additional Windows validation at I also reproduced the original failure on main These are game-free linker fixtures, not a full |
|
Thanks for running it on Windows: that was the part I could not do here. And yes, #2257 is this fault: its two error lines are the map's path and |
The link map and the link order (hot_order.txt) are in the build files folder, which the player chooses, and nx2/build.py passed them to the linker with -Wl, (directly on Linux, through toolchain.link_opt on Windows). The compiler splits -Wl, at every comma, so a folder named x,y stopped the game's link: "ld.lld: error: cannot open y/sa/build/hookshot.map". linker() passes each of these options after -Xlinker, one argument each (-Xlink= for llvm-mingw, as toolchain.link_opt does): the Linux and the Windows map of the game, of the Vulkan back end and of --dll, and the link order on both. tests/test_link_path_comma.py checks that no -Wl, option in build.py carries anything but a constant, what linker() and HOT_ORDER() give for Linux, the MSVC target and llvm-mingw, and, with clang and LLVM's lld installed, a link into a folder named "Games, Zelda" through ld.lld, lld-link and the MinGW driver. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Rebased onto main |
0d240b3 to
5f72b92
Compare
hckrman101
left a comment
There was a problem hiding this comment.
Looks good. The cause is right: clang splits -Wl, at every comma, and the map and hot_order.txt paths sit in the user-chosen build files folder. I checked every option in the diff that carries a path and each now goes through -Xlinker as its own argv entry. The comma is the only character that clang's own -Wl, splitting treats specially, so spaces and non-ASCII (UTF-8) paths are fine, since this is a list-form subprocess.run, not a shell string. The @rsp files are not touched by this change. The remaining -Wl, options are constants (--gc-sections, -Bsymbolic, --export-dynamic-symbol=hos_posix_*), and the test guards that with the AST check.
The llvm-mingw route (-Xlinker -Xlink=/map:...) matches what toolchain.link_opt already emitted, minus the -Wl, wrapper. Arkex-ai's Windows run with llvm-mingw clang 23 and lld, including the real links, confirms it. That was the one thing I could not check from here. The test is game-free, needs no dump, and skips the real links when lld is absent.
CI: the two red jobs look unrelated to this change. tests/test_native_astc_texture_count.py on windows-2022 fails with 'scanf' is deprecated (-Werror) in its own fixture, and appimage fails in its System packages step on network timeouts. Both are in files this PR does not touch, but check that main's latest run shows the same. The Conventional Commit title check was still pending when I looked.
Nit, not blocking: the linker() docstring is long for a three-line helper. It is fine to keep as is.
Joey-Magnus
left a comment
There was a problem hiding this comment.
Paths go to the linker through -Xlinker (and -Xlink= for llvm-mingw) instead of -Wl,, which splits on commas. In the merged result I found no other -Wl, or link_opt carrying a path. The red checks are main's old ASTC test failure (#2397) and a Launchpad PPA timeout on appimage, neither from this PR.
A build stops at the link, after the whole compile, when the folder chosen for the build files has a comma in its path
(for example
D:\Games, Zeldapicked in the builder, or--work): the compiler splits the linker options that name thelink map and the link order at that comma. A failed link also makes the next build translate and compile everything
again (
make_game.py), and it fails the same way.Fixes #2257.
What changed
nx2/build.py:linker()passes linker options each after-Xlinker, as one argument (with llvm-mingw as-Xlink=<option>, astoolchain.link_optdoes). It is used for the options that name a file in the build filesfolder, which went through
-Wl,(directly on Linux, throughtoolchain.link_opton Windows):-Map=on Linux,/map:on Windows), of the Vulkan back end, and of--dll;hot_order.txtin that folder (--symbol-ordering-file=on Linux,/order:@on Windows).The other linker options are constants and stay as they are.
tests/test_link_path_comma.py(new, game-free):-Wl,option inbuild.pycarries anything but a constant, andtoolchain.link_optis given only constants;linker()andHOT_ORDER()give for Linux, the MSVC target and llvm-mingw, with a build files folder namedGames, Zelda;lld-link and the MinGW driver, writes its map there. Without lld that part skips itself (CI's Ubuntu has clang but
perhaps not lld); the first two parts need nothing.
How it was tested
Linux (Arch, clang and lld 23.1.3), no GPU involved:
nx2/build.py --standalonewithOOT_WORKset to a folder namedx,y(a copy of a full build's files from main, soonly the files changed since were compiled). On main (fab8cb3) the link stops:
With this change both links pass and write
hookshot.mapandhookshot_vk.so.mapinx,y. All 3682 functions of thelink order are in the new map at the same addresses as in main's own build (built in a folder with no comma), and in
the list's order: the order still takes effect through
-Xlinker.The Windows options, linked from Linux with the same clang for both Windows targets: a small program linked into a
folder named
a,bwith the old options fails (lld-link: error: could not open 'b/hookshot.map'; llvm-mingw's ld.lldgives
ld.lld: error: could not open 'b/hookshot.map';/order:@the same withb/hot_order.txt). With-Xlinkeritlinks and writes the map.
The compile options that also carry paths in the build files folder (
-I,-include,-fprofile-instr-use=) are notsplit at commas: a small compile with a profile in
a,bpasses.The new test passes; run against main's
build.py(--build-script) it fails 8 times, and names the 7 optionsthat carried a path (build.py lines 136, 137, 1073, 1092, 1142, 1147, 1161 on main).
python -I -B tests/run_all.py: 362 passed, 2 failed, 10 skipped. The same 2 fail on main here, forreasons of this machine (
tests/test_updater_asset_digest.py: dotnet cannot restore its packages offline;tests/test_wayland_libdecor_hint.py: clang 23's new-Wunused-but-set-globalon its harness). Every other checkhas the same result as on main; the new one passes.
After a rebase onto current
main(e0578ed) the new test was run again and passes (6 tests, with the three reallinks); the full set above was run on fab8cb3, before the rebase.
Not tested
from Linux with clang 23's lld-link and ld.lld (MinGW).
2026-11-11: @Arkex-ai ran the new test's six cases on Windows with llvm-mingw's clang 23 and LLVM's lld, with the
three real links, at
0d240b30(see the comments). Still not run: a full Builder build on Windows.make_game.pybuild into a folder with a comma: the lift and the full compile were not run there, onlybuild.py's compile of the changed files and its two links.-Wl,-map,<path>would have the same fault).Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com