link: fix ambiguous names in linker scripts
Currently zig fails to build while linking the system LLVM/C++ libraries on my Chimera Linux system due to the fact that libc++.so is a linker script with the following contents: INPUT(libc++.so.1 -lc++abi -lunwind) Prior to this commit, zig would try to convert "ambiguous names" in linker scripts such as libc++.so.1 in this example into -lfoo style flags. This fails in this case due to the so version number as zig checks for exactly the .so suffix. Furthermore, I do not think that this conversion is semantically correct since converting libfoo.so to -lfoo could theoretically end up resulting in libfoo.a getting linked which seems wrong when a different file is specified in the linker script. With this patch, this attempted conversion is removed. Instead, zig always first checks if the exact file/path in the linker script exists relative to the current working directory. If the file is classified as a library (including versioned shared objects such as libfoo.so.1), zig then falls back to checking if the exact file/path in the linker script exists relative to each directory in the library search path, selecting the first match or erroring out if none is found. This behavior fixes the regression that prevents building zig while linking the system LLVM/C++ libraries on Chimera Linux.
This commit is contained in:
@@ -2123,24 +2123,35 @@ fn testLinkOrder(b: *Build, opts: Options) *Step {
|
||||
fn testLdScript(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "ld-script", opts);
|
||||
|
||||
const dso = addSharedLibrary(b, opts, .{ .name = "bar" });
|
||||
addCSourceBytes(dso, "int foo() { return 42; }", &.{});
|
||||
const bar = addSharedLibrary(b, opts, .{ .name = "bar" });
|
||||
addCSourceBytes(bar, "int bar() { return 42; }", &.{});
|
||||
|
||||
const baz = addSharedLibrary(b, opts, .{ .name = "baz" });
|
||||
addCSourceBytes(baz, "int baz() { return 42; }", &.{});
|
||||
|
||||
const scripts = WriteFile.create(b);
|
||||
_ = scripts.add("liba.so", "INPUT(libfoo.so)");
|
||||
_ = scripts.add("liba.so", "INPUT(libfoo.so libfoo2.so.1)");
|
||||
_ = scripts.add("libfoo.so", "GROUP(AS_NEEDED(-lbar))");
|
||||
|
||||
// Check finding a versioned .so file that is elsewhere in the library search paths.
|
||||
const scripts2 = WriteFile.create(b);
|
||||
_ = scripts2.add("libfoo2.so.1", "GROUP(AS_NEEDED(-lbaz))");
|
||||
|
||||
const exe = addExecutable(b, opts, .{ .name = "main" });
|
||||
addCSourceBytes(exe,
|
||||
\\int foo();
|
||||
\\int bar();
|
||||
\\int baz();
|
||||
\\int main() {
|
||||
\\ return foo() - 42;
|
||||
\\ return bar() - baz();
|
||||
\\}
|
||||
, &.{});
|
||||
exe.linkSystemLibrary2("a", .{});
|
||||
exe.addLibraryPath(scripts.getDirectory());
|
||||
exe.addLibraryPath(dso.getEmittedBinDirectory());
|
||||
exe.addRPath(dso.getEmittedBinDirectory());
|
||||
exe.addLibraryPath(scripts2.getDirectory());
|
||||
exe.addLibraryPath(bar.getEmittedBinDirectory());
|
||||
exe.addLibraryPath(baz.getEmittedBinDirectory());
|
||||
exe.addRPath(bar.getEmittedBinDirectory());
|
||||
exe.addRPath(baz.getEmittedBinDirectory());
|
||||
exe.linkLibC();
|
||||
exe.allow_so_scripts = true;
|
||||
|
||||
@@ -2167,7 +2178,7 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step {
|
||||
// TODO: A future enhancement could make this error message also mention
|
||||
// the file that references the missing library.
|
||||
expectLinkErrors(exe, test_step, .{
|
||||
.stderr_contains = "error: unable to find dynamic system library 'foo' using strategy 'no_fallback'. searched paths:",
|
||||
.stderr_contains = "error: libfoo.so: file listed in linker script not found",
|
||||
});
|
||||
|
||||
return test_step;
|
||||
|
||||
Reference in New Issue
Block a user