Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -31,6 +31,7 @@ bool ExportDynamic; bool NoInhibitExec; bool Shared; + bool Static = false; }; extern Configuration *Config; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -53,7 +53,8 @@ if (Path[0] == ':') { Names.push_back(Path.drop_front().str()); } else { - Names.push_back((Twine("lib") + Path + ".so").str()); + if (!Config->Static) + Names.push_back((Twine("lib") + Path + ".so").str()); Names.push_back((Twine("lib") + Path + ".a").str()); } for (StringRef Dir : Config->InputSearchPaths) { @@ -124,12 +125,22 @@ Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec); Config->Shared = Args.hasArg(OPT_shared); - for (auto *Arg : Args.filtered(OPT_l, OPT_INPUT)) { - StringRef Path = Arg->getValue(); - if (Arg->getOption().getID() == OPT_l) { - addFile(searchLibrary(Path)); - } else { - addFile(Path); + for (auto *Arg : Args) { + switch (Arg->getOption().getID()) { + case OPT_l: + addFile(searchLibrary(Arg->getValue())); + break; + case OPT_INPUT: + addFile(Arg->getValue()); + break; + case OPT_Bstatic: + Config->Static = true; + break; + case OPT_Bdynamic: + Config->Static = false; + break; + default: + break; } } Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -1,5 +1,11 @@ include "llvm/Option/OptParser.td" +def Bdynamic: Flag<["-"], "Bdynamic">, + HelpText<"Link against shared libraries">; + +def Bstatic: Flag<["-"], "Bstatic">, + HelpText<"Do not link against shared libraries">; + def L : Joined<["-"], "L">, MetaVarName<"">, HelpText<"Directory to search for libraries">; @@ -43,6 +49,11 @@ HelpText<"Set the system root">; // Aliases +def alias_Bdynamic_call_shared: Flag<["-"], "call_shared">, Alias; +def alias_Bdynamic_dy: Flag<["-"], "dy">, Alias; +def alias_Bstatic_dn: Flag<["-"], "dn">, Alias; +def alias_Bstatic_non_shared: Flag<["-"], "non_shared">, Alias; +def alias_Bstatic_static: Flag<["-"], "static">, Alias; def alias_L : Joined<["--"], "library-path=">, Alias; def alias_discard_all: Flag<["-"], "x">, Alias; def alias_discard_locals: Flag<["-"], "X">, Alias; Index: test/elf2/libsearch.s =================================================================== --- test/elf2/libsearch.s +++ test/elf2/libsearch.s @@ -1,21 +1,22 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -// RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o +// RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -// RUN: %p/Inputs/libsearch-st.s -o %tst.o +// RUN: %p/Inputs/libsearch-st.s -o %tst.o // RUN: lld -flavor gnu2 -shared %tdyn.o -o %T/libls.so +// RUN: cp -f %T/libls.so %T/libls2.so // RUN: rm -f %T/libls.a // RUN: llvm-ar rcs %T/libls.a %tst.o // REQUIRES: x86 // Should not link because of undefined symbol _bar // RUN: not lld -flavor gnu2 -o %t3 %t.o 2>&1 \ -// RUN: | FileCheck --check-prefix=UNDEFINED %s +// RUN: | FileCheck --check-prefix=UNDEFINED %s // UNDEFINED: undefined symbol: _bar // Should fail if cannot find specified library (without -L switch) // RUN: not lld -flavor gnu2 -o %t3 %t.o -lls 2>&1 \ -// RUN: | FileCheck --check-prefix=NOLIB %s +// RUN: | FileCheck --check-prefix=NOLIB %s // NOLIB: Unable to find library -lls // Should use explicitly specified static library @@ -42,5 +43,34 @@ // Check long forms as well // RUN: lld -flavor gnu2 -o %t3 %t.o --library-path=%T --library=ls +// Should not search for dynamic libraries if -Bstatic is specified +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -Bstatic -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s +// RUN: not lld -flavor gnu2 -o %t3 %t.o -L%T -Bstatic -lls2 2>&1 \ +// RUN: | FileCheck --check-prefix=NOLIB2 %s +// NOLIB2: Unable to find library -lls2 + +// -Bdynamic should restore default behaviour +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -Bstatic -Bdynamic -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s + +// -Bstatic and -Bdynamic should affect only libraries which follow them +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -lls -Bstatic -Bdynamic +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -Bstatic -lls -Bdynamic +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s + +// Check aliases as well +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -dn -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -non_shared -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -static -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -Bstatic -dy -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s +// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -Bstatic -call_shared -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s + .globl _start,_bar; _start: