summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin.dev@gmail.com>2015-09-28 15:01:59 +0000
committerIgor Kudrin <ikudrin.dev@gmail.com>2015-09-28 15:01:59 +0000
commit1309fc0378919cfeae33c0b5732e122ed97c95dc (patch)
tree1372f8a4a815bafdc2c9cbcefd86919389883fbc
parentba52fcb7d519e6a9a8cefa578c28c867db12260e (diff)
downloadbcm5719-llvm-1309fc0378919cfeae33c0b5732e122ed97c95dc.tar.gz
bcm5719-llvm-1309fc0378919cfeae33c0b5732e122ed97c95dc.zip
[ELF2] Add --sysroot command line switch
Reviewers: rafael, ruiu Subscribers: llvm-commits Projects: #lld Differential Revision: http://reviews.llvm.org/D13209 llvm-svn: 248715
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp26
-rw-r--r--lld/ELF/Options.td3
-rw-r--r--lld/test/elf2/sysroot.s36
4 files changed, 61 insertions, 5 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 0e507a48f78..d4000b54675 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -22,6 +22,7 @@ struct Configuration {
llvm::StringRef DynamicLinker;
std::string RPath;
std::vector<llvm::StringRef> InputSearchPaths;
+ llvm::StringRef Sysroot;
bool Shared = false;
bool DiscardAll = false;
bool DiscardLocals = false;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 6bc3d754bbc..948d4ecd8e7 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -60,6 +60,21 @@ static std::unique_ptr<InputFile> createFile(MemoryBufferRef MB) {
return createELFFile<ObjectFile>(MB);
}
+// Makes a path by concatenating Dir and File.
+// If Dir starts with "=" the result will be preceded by SysRoot,
+// which can be set with --sysroot command line switch.
+static std::string buildSysrootedPath(StringRef Dir, StringRef File) {
+ SmallString<128> Path;
+ if (Dir.startswith("=")) {
+ Path.assign(Config->Sysroot);
+ sys::path::append(Path, Dir.substr(1), File);
+ } else {
+ Path.assign(Dir);
+ sys::path::append(Path, File);
+ }
+ return Path.str().str();
+}
+
// 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) {
@@ -70,13 +85,11 @@ static std::string searchLibrary(StringRef Path) {
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();
+ std::string FullPath = buildSysrootedPath(Dir, Name);
+ if (sys::fs::exists(FullPath))
+ return FullPath;
}
}
error(Twine("Unable to find library -l") + Path);
@@ -96,6 +109,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (auto *Arg = Args.getLastArg(OPT_dynamic_linker))
Config->DynamicLinker = Arg->getValue();
+ if (auto *Arg = Args.getLastArg(OPT_sysroot))
+ Config->Sysroot = Arg->getValue();
+
std::vector<StringRef> RPaths;
for (auto *Arg : Args.filtered(OPT_rpath))
RPaths.push_back(Arg->getValue());
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 9eb363a8872..1a237cb6b1c 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -49,3 +49,6 @@ def l : Joined<["-"], "l">, MetaVarName<"<libName>">,
def alias_l : Joined<["--"], "library=">,
Alias<l>;
+
+def sysroot : Joined<["--"], "sysroot=">,
+ HelpText<"Set the system root">;
diff --git a/lld/test/elf2/sysroot.s b/lld/test/elf2/sysroot.s
new file mode 100644
index 00000000000..845fdfe3500
--- /dev/null
+++ b/lld/test/elf2/sysroot.s
@@ -0,0 +1,36 @@
+// RUN: mkdir -p %t/lib
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t/m.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN: %p/Inputs/libsearch-st.s -o %t/st.o
+// RUN: rm -f %t/lib/libls.a
+// RUN: llvm-ar rcs %t/lib/libls.a %t/st.o
+// REQUIRES: x86
+
+// Should not link because of undefined symbol _bar
+// RUN: not lld -flavor gnu2 -o %t/r %t/m.o 2>&1 \
+// RUN: | FileCheck --check-prefix=UNDEFINED %s
+// UNDEFINED: undefined symbol: _bar
+
+// We need to be sure that there is no suitable library in the /lib directory
+// RUN: not lld -flavor gnu2 -o %t/r %t/m.o -L/lib -l:libls.a 2>&1 \
+// RUN: | FileCheck --check-prefix=NOLIB %s
+// NOLIB: Unable to find library -l:libls.a
+
+// Should just remove the '=' symbol if --sysroot is not specified.
+// Case 1: relative path
+// RUN: cd %t && lld -flavor gnu2 -o %t/r %t/m.o -L=lib -l:libls.a
+// Case 2: absolute path
+// RUN: cd %p && lld -flavor gnu2 -o %t/r %t/m.o -L=%t/lib -l:libls.a
+
+// RUN: cd %p
+
+// Should substitute SysRoot if specified
+// RUN: lld -flavor gnu2 -o %t/r %t/m.o --sysroot=%t -L=lib -l:libls.a
+// RUN: lld -flavor gnu2 -o %t/r %t/m.o --sysroot=%t -L=/lib -l:libls.a
+
+// Should not substitute SysRoot if the directory name does not start with '='
+// RUN: not lld -flavor gnu2 -o %t/r %r/m.o --sysroot=%t -Llib -l:libls.a
+// RUN: not lld -flavor gnu2 -o %t/r %r/m.o --sysroot=%t -L/lib -l:libls.a
+
+.globl _start,_bar;
+_start:
OpenPOWER on IntegriCloud