Skip to content

[lld][ELF] --relocatable library search prefers shared objects over archives leading to errors #94958

@paparodeo

Description

@paparodeo

on linux with llvm-17 (tho source looks the same in main)

$ lld -r test.o -o test -L./libs -ltest
lld: error: attempted static link of dynamic object ./libs/libtest.so

fails when both libtest.a and libtest.so exist

the following patch aligns the search path behavior to that of GNU ld:

diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index ac7460440..77214aa36 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -234,7 +234,7 @@ std::optional<std::string> elf::findFromSearchPaths(StringRef path) {
 // search paths.
 std::optional<std::string> elf::searchLibraryBaseName(StringRef name) {
   for (StringRef dir : config->searchPaths) {
-    if (!config->isStatic)
+    if (!(config->isStatic || config->relocatable))
       if (std::optional<std::string> s = findFile(dir, "lib" + name + ".so"))
         return s;
     if (std::optional<std::string> s = findFile(dir, "lib" + name + ".a"))
diff --git a/lld/test/ELF/libsearch.s b/lld/test/ELF/libsearch.s
index 417953491..eb644abb6 100644
--- a/lld/test/ELF/libsearch.s
+++ b/lld/test/ELF/libsearch.s
@@ -49,6 +49,12 @@
 // RUN: ld.lld -o %t3 %t.o -L%t.dir -lls
 // RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
 
+// Should use static when dynamic exists in search path
+// RUN: ld.lld --relocatable -o %t3 %t.o -L%t.dir -lls
+// RUN: llvm-readelf -s -h %t3 | FileCheck --check-prefix=RELOCATABLE %s
+// RELOCATABLE: Type: REL (Relocatable file)
+// RELOCATABLE: [[#]] _static
+
 // Check for library search order
 // RUN: mkdir -p %t.dir2
 // RUN: cp %t.dir/libls.a %t.dir2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions