mirror of
https://github.com/libretro/fuse-libretro.git
synced 2026-11-07 10:36:03 -10:00
The six build-static jobs (ctr, ngc, wii, wiiu, psp, vita) all fail the same way: 38 "multiple definition" errors, every one of them between libretro_<platform>.a(file_path.o) and RetroArch's own libretro-common/file/file_path.o. Root cause is not the 38 symbols. In a static build RetroArch's libretro-common objects are on the link line and the core is an archive, so an archive member is only extracted when it satisfies a symbol that is still undefined. Every symbol the core's file_path.o defines is already defined by RetroArch's, with exactly one exception: fill_pathname_join_special RetroArch turned that identifier into a macro alias of fill_pathname_join(); this vendored copy still had it as a real function. src/compat/file.c and deps/libretro-common/vfs/ vfs_implementation.c call it, RetroArch no longer defines it, so ld pulls file_path.o out of the archive to resolve it and the other 38 symbols in that member collide on the way in. One divergent symbol drags in a whole translation unit. Sync the vendored copy with upstream: the header gets the macro alias, the definition goes. The core's file_path.o now exports a strict subset of RetroArch's, nothing forces its extraction, and the callers resolve to fill_pathname_join() in both build modes. The two implementations differed only in fill_pathname_join()'s `if (s != dir)` guard, which skips the leading copy when the output aliases the directory. Every call site here passes distinct buffers, so the guard is never taken and the substitution is a no-op that also makes the aliasing case safe. A/B oracle over 2640 (dir, path, len) combinations - empty, relative, absolute, trailing- and leading-slash, mixed separators, truncating lengths - shows byte-identical output buffers and identical return values. Verified by rebuilding the archive against upstream RetroArch's libretro-common: before, 38 multiple-definition errors matching the CI log symbol for symbol; after, a clean link. The shared build is unaffected.