forked from OSchip/llvm-project
Add support for -L and -l command line switches.
Patch by Igor Kudrin! llvm-svn: 248708
This commit is contained in:
parent
83af95d927
commit
abb7b28686
|
@ -19,6 +19,7 @@ struct Configuration {
|
|||
llvm::StringRef OutputFile;
|
||||
llvm::StringRef DynamicLinker;
|
||||
std::string RPath;
|
||||
std::vector<llvm::StringRef> InputSearchPaths;
|
||||
bool Shared = false;
|
||||
bool DiscardAll = false;
|
||||
bool DiscardLocals = false;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -59,6 +60,28 @@ static std::unique_ptr<InputFile> createFile(MemoryBufferRef MB) {
|
|||
return createELFFile<ObjectFile>(MB);
|
||||
}
|
||||
|
||||
// Searches a given library from input search paths, which are filled
|
||||
// from -L command line switches. Returns a path to an existent library file.
|
||||
static std::string searchLibrary(StringRef Path) {
|
||||
std::vector<std::string> Names;
|
||||
if (Path[0] == ':') {
|
||||
Names.push_back(Path.drop_front().str());
|
||||
} else {
|
||||
Names.push_back((Twine("lib") + Path + ".so").str());
|
||||
Names.push_back((Twine("lib") + Path + ".a").str());
|
||||
}
|
||||
SmallString<128> FullPath;
|
||||
for (StringRef Dir : Config->InputSearchPaths) {
|
||||
for (const std::string &Name : Names) {
|
||||
FullPath = Dir;
|
||||
sys::path::append(FullPath, Name);
|
||||
if (sys::fs::exists(FullPath.str()))
|
||||
return FullPath.str().str();
|
||||
}
|
||||
}
|
||||
error(Twine("Unable to find library -l") + Path);
|
||||
}
|
||||
|
||||
void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
// Parse command line options.
|
||||
opt::InputArgList Args = Parser.parse(ArgsArr);
|
||||
|
@ -79,6 +102,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
|||
if (!RPaths.empty())
|
||||
Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":");
|
||||
|
||||
for (auto *Arg : Args.filtered(OPT_L))
|
||||
Config->InputSearchPaths.push_back(Arg->getValue());
|
||||
|
||||
if (Args.hasArg(OPT_shared))
|
||||
Config->Shared = true;
|
||||
|
||||
|
@ -100,8 +126,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
|||
// Create a list of input files.
|
||||
std::vector<MemoryBufferRef> Inputs;
|
||||
|
||||
for (auto *Arg : Args.filtered(OPT_INPUT)) {
|
||||
for (auto *Arg : Args.filtered(OPT_l, OPT_INPUT)) {
|
||||
StringRef Path = Arg->getValue();
|
||||
if (Arg->getOption().getID() == OPT_l) {
|
||||
Inputs.push_back(openFile(searchLibrary(Path)));
|
||||
continue;
|
||||
}
|
||||
Inputs.push_back(openFile(Path));
|
||||
}
|
||||
|
||||
|
|
|
@ -37,3 +37,15 @@ def discard_none : Flag<["-"], "discard-none">,
|
|||
|
||||
def export_dynamic : Flag<["--"], "export-dynamic">,
|
||||
HelpText<"Put symbols in the dynamic symbol table">;
|
||||
|
||||
def L : Joined<["-"], "L">, MetaVarName<"<dir>">,
|
||||
HelpText<"Directory to search for libraries">;
|
||||
|
||||
def alias_L : Joined<["--"], "library-path=">,
|
||||
Alias<L>;
|
||||
|
||||
def l : Joined<["-"], "l">, MetaVarName<"<libName>">,
|
||||
HelpText<"Root name of library to use">;
|
||||
|
||||
def alias_l : Joined<["--"], "library=">,
|
||||
Alias<l>;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.globl _bar,_dynamic;
|
||||
_bar:
|
||||
_dynamic:
|
|
@ -0,0 +1,3 @@
|
|||
.globl _bar,_static;
|
||||
_bar:
|
||||
_static:
|
|
@ -0,0 +1,46 @@
|
|||
// 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: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
|
||||
// RUN: %p/Inputs/libsearch-st.s -o %tst.o
|
||||
// RUN: lld -flavor gnu2 -shared %tdyn.o -o %T/libls.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
|
||||
// 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
|
||||
// NOLIB: Unable to find library -lls
|
||||
|
||||
// Should use explicitly specified static library
|
||||
// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -l:libls.a
|
||||
// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
|
||||
// STATIC: Symbols [
|
||||
// STATIC: Name: _static
|
||||
// STATIC: ]
|
||||
|
||||
// Should use explicitly specified dynamic library
|
||||
// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -l:libls.so
|
||||
// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
|
||||
// DYNAMIC: Symbols [
|
||||
// DYNAMIC-NOT: Name: _static
|
||||
// DYNAMIC: ]
|
||||
|
||||
// Should prefer dynamic to static
|
||||
// RUN: lld -flavor gnu2 -o %t3 %t.o -L%T -lls
|
||||
// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
|
||||
|
||||
// -L can be placed after -l
|
||||
// RUN: lld -flavor gnu2 -o %t3 %t.o -lls -L%T
|
||||
|
||||
// Check long forms as well
|
||||
// RUN: lld -flavor gnu2 -o %t3 %t.o --library-path=%T --library=ls
|
||||
|
||||
.globl _start,_bar;
|
||||
_start:
|
Loading…
Reference in New Issue