Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -20,6 +20,7 @@ llvm::StringRef DynamicLinker; std::string RPath; std::vector InputSearchPaths; + llvm::StringRef SysRoot; bool Shared = false; bool DiscardAll = false; bool DiscardLocals = false; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -60,6 +60,20 @@ return createELFFile(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 void buildSysRootedPath(SmallString<128> &Path, StringRef Dir, + StringRef File) { + if (Dir.startswith("=")) { + Path.assign(Config->SysRoot); + sys::path::append(Path, Dir.substr(1), File); + } else { + Path.assign(Dir); + sys::path::append(Path, File); + } +} + // 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) { @@ -73,8 +87,7 @@ SmallString<128> FullPath; for (StringRef Dir : Config->InputSearchPaths) { for (const std::string &Name : Names) { - FullPath = Dir; - sys::path::append(FullPath, Name); + buildSysRootedPath(FullPath, Dir, Name); if (sys::fs::exists(FullPath.str())) return FullPath.str().str(); } @@ -96,6 +109,9 @@ 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 RPaths; for (auto *Arg : Args.filtered(OPT_rpath)) RPaths.push_back(Arg->getValue()); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -49,3 +49,6 @@ def alias_l : Joined<["--"], "library=">, Alias; + +def sysroot : Joined<["--"], "sysroot=">, + HelpText<"Set the system root">; Index: test/elf2/sysroot.s =================================================================== --- /dev/null +++ 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: