[lld] 0ccda7c - MachO: support `-syslibroot`
Saleem Abdulrasool via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 5 08:42:32 PDT 2020
Author: Saleem Abdulrasool
Date: 2020-08-05T08:41:24-07:00
New Revision: 0ccda7c2326e1dc4e0d5d601dcc06c4b576acb0e
URL: https://github.com/llvm/llvm-project/commit/0ccda7c2326e1dc4e0d5d601dcc06c4b576acb0e
DIFF: https://github.com/llvm/llvm-project/commit/0ccda7c2326e1dc4e0d5d601dcc06c4b576acb0e.diff
LOG: MachO: support `-syslibroot`
This adds support for the `-syslibroot` option. This is required to
make the library search order actually function. With this, it is now
possible to link a test Darwin x86_64 program with lld on Darwin.
Differential Revision: https://reviews.llvm.org/D82252
Reviewed By: Jez Ng
Added:
lld/test/MachO/syslibroot.test
Modified:
lld/MachO/Driver.cpp
lld/test/MachO/search-paths.test
Removed:
################################################################################
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 6b25cd55ccfc7..93dfb15e3e1a9 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -152,28 +152,49 @@ static bool isDirectory(StringRef option, StringRef path) {
static void getSearchPaths(std::vector<StringRef> &paths, unsigned optionCode,
opt::InputArgList &args,
+ const std::vector<StringRef> &roots,
const SmallVector<StringRef, 2> &systemPaths) {
StringRef optionLetter{(optionCode == OPT_F ? "F" : "L")};
for (auto const &path : args::getStrings(args, optionCode)) {
- if (isDirectory(optionLetter, path))
- paths.push_back(path);
- }
- if (!args.hasArg(OPT_Z) && Triple(sys::getProcessTriple()).isOSDarwin()) {
- for (auto const &path : systemPaths) {
+ // NOTE: only absolute paths are re-rooted to syslibroot(s)
+ if (llvm::sys::path::is_absolute(path, llvm::sys::path::Style::posix)) {
+ for (StringRef root : roots) {
+ SmallString<261> buffer(root);
+ llvm::sys::path::append(buffer, path);
+ // Do not warn about paths that are computed via the syslib roots
+ if (llvm::sys::fs::is_directory(buffer))
+ paths.push_back(saver.save(buffer.str()));
+ }
+ } else {
if (isDirectory(optionLetter, path))
paths.push_back(path);
}
}
+
+ // `-Z` suppresses the standard "system" search paths.
+ if (args.hasArg(OPT_Z))
+ return;
+
+ for (auto const &path : systemPaths) {
+ for (auto root : roots) {
+ SmallString<261> buffer(root);
+ llvm::sys::path::append(buffer, path);
+ if (isDirectory(optionLetter, buffer))
+ paths.push_back(saver.save(buffer.str()));
+ }
+ }
}
-static void getLibrarySearchPaths(std::vector<StringRef> &paths,
- opt::InputArgList &args) {
- getSearchPaths(paths, OPT_L, args, {"/usr/lib", "/usr/local/lib"});
+static void getLibrarySearchPaths(opt::InputArgList &args,
+ const std::vector<StringRef> &roots,
+ std::vector<StringRef> &paths) {
+ getSearchPaths(paths, OPT_L, args, roots, {"/usr/lib", "/usr/local/lib"});
}
-static void getFrameworkSearchPaths(std::vector<StringRef> &paths,
- opt::InputArgList &args) {
- getSearchPaths(paths, OPT_F, args,
+static void getFrameworkSearchPaths(opt::InputArgList &args,
+ const std::vector<StringRef> &roots,
+ std::vector<StringRef> &paths) {
+ getSearchPaths(paths, OPT_F, args, roots,
{"/Library/Frameworks", "/System/Library/Frameworks"});
}
@@ -397,10 +418,22 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
config->installName =
args.getLastArgValue(OPT_install_name, config->outputFile);
config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);
- getLibrarySearchPaths(config->librarySearchPaths, args);
- getFrameworkSearchPaths(config->frameworkSearchPaths, args);
config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
+ std::vector<StringRef> roots;
+ for (const Arg *arg : args.filtered(OPT_syslibroot))
+ roots.push_back(arg->getValue());
+ // NOTE: the final `-syslibroot` being `/` will ignore all roots
+ if (roots.size() && roots.back() == "/")
+ roots.clear();
+ // NOTE: roots can never be empty - add an empty root to simplify the library
+ // and framework search path computation.
+ if (roots.empty())
+ roots.emplace_back("");
+
+ getLibrarySearchPaths(args, roots, config->librarySearchPaths);
+ getFrameworkSearchPaths(args, roots, config->frameworkSearchPaths);
+
if (args.hasArg(OPT_v)) {
message(getLLDVersion());
message(StringRef("Library search paths:") +
@@ -455,6 +488,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
case OPT_install_name:
case OPT_Z:
case OPT_arch:
+ case OPT_syslibroot:
// handled elsewhere
break;
default:
diff --git a/lld/test/MachO/search-paths.test b/lld/test/MachO/search-paths.test
index 124a2a080b6de..8249f2779db9f 100644
--- a/lld/test/MachO/search-paths.test
+++ b/lld/test/MachO/search-paths.test
@@ -2,13 +2,13 @@ UNSUPPORTED: darwin
RUN: mkdir -p %t1 %t2
-RUN: lld -flavor darwinnew -v -L%t1 -F%t2 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 %s
+RUN: lld -flavor darwinnew -Z -v -L%t1 -F%t2 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 %s
CHECK: Library search paths:
CHECK-NEXT: [[LDIR]]
CHECK-NEXT: Framework search paths:
CHECK-NEXT: [[FDIR]]
-RUN: lld -flavor darwinnew -v -L%t1 -F%t2 -Z 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 --check-prefix=CHECK_Z %s
+RUN: lld -flavor darwinnew -Z -v -L%t1 -F%t2 -Z 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 --check-prefix=CHECK_Z %s
CHECK_Z: Library search paths:
CHECK_Z-NEXT: [[LDIR]]
CHECK_Z-NEXT: Framework search paths:
diff --git a/lld/test/MachO/syslibroot.test b/lld/test/MachO/syslibroot.test
new file mode 100644
index 0000000000000..e9d87abd0cc11
--- /dev/null
+++ b/lld/test/MachO/syslibroot.test
@@ -0,0 +1,55 @@
+# Ensure that a nonexistent path is ignored with a syslibroot
+
+RUN: lld -flavor darwinnew -v -syslibroot /var/empty | FileCheck %s -check-prefix CHECK-NONEXISTENT-SYSLIBROOT
+
+CHECK-NONEXISTENT-SYSLIBROOT: Library search paths:
+CHECK-NONEXISTENT-SYSLIBROOT-NEXT: Framework search paths:
+
+RUN: mkdir -p %t/usr/lib
+RUN: lld -flavor darwinnew -v -syslibroot %t | FileCheck %s -check-prefix CHECK-SYSLIBROOT -DROOT=%t
+
+CHECK-SYSLIBROOT: Library search paths:
+CHECK-SYSLIBROOT-NEXT: [[ROOT]]/usr/lib
+
+RUN: mkdir -p %t/Library/libxml2-development
+RUN: lld -flavor darwinnew -v -syslibroot %t -L /Library/libxml2-development | FileCheck %s -check-prefix CHECK-ABSOLUTE-PATH-REROOTED -DROOT=%t
+
+CHECK-ABSOLUTE-PATH-REROOTED: Library search paths:
+CHECK-ABSOLUTE-PATH-REROOTED: [[ROOT]]/Library/libxml2-development
+CHECK-ABSOLUTE-PATH-REROOTED: [[ROOT]]/usr/lib
+
+# NOTE: the match here is fuzzy because the default search paths exist on Linux
+# and macOS, but not on Windows (that is we ignore `/var/empty`). This allows
+# us to run the test uniformly on all the platforms.
+RUN: lld -flavor darwinnew -v -syslibroot /var/empty -syslibroot / 2>&1 | FileCheck %s -check-prefix CHECK-SYSLIBROOT-IGNORED
+
+CHECK-SYSLIBROOT-IGNORED: /usr/lib
+CHECK-SYSLIBROOT-IGNORED: /usr/local/lib
+
+RUN: mkdir -p %t.2/usr/lib
+RUN: lld -flavor darwinnew -v -syslibroot %t -syslibroot %t.2 | FileCheck %s -check-prefix CHECK-SYSLIBROOT-MATRIX -DROOT=%t
+
+CHECK-SYSLIBROOT-MATRIX: Library search paths:
+CHECK-SYSLIBROOT-MATRIX: [[ROOT]]/usr/lib
+CHECK-SYSLIBROOT-MATRIX: [[ROOT]].2/usr/lib
+
+RUN: mkdir -p %t/System/Library/Frameworks
+RUN: lld -flavor darwinnew -v -syslibroot %t | FileCheck %s -check-prefix CHECK-SYSLIBROOT-FRAMEWORK -DROOT=%t
+
+CHECK-SYSLIBROOT-FRAMEWORK: Framework search paths:
+CHECK-SYSLIBROOT-FRAMEWORK: [[ROOT]]/System/Library/Frameworks
+
+# NOTE: the match here is fuzzy because the default search paths exist on Linux
+# and macOS, but not on Windows (that is we ignore `/var/empty`). This allows
+# us to run the test uniformly on all the platforms.
+RUN: lld -flavor darwinnew -v -syslibroot /var/empty -syslibroot / 2>&1 | FileCheck %s -check-prefix CHECK-SYSLIBROOT-FRAMEWORK-IGNORED
+
+CHECK-SYSLIBROOT-FRAMEWORK-IGNORED: /System/Library/Framework
+
+RUN: mkdir -p %t/Library/Frameworks
+RUN: mkdir -p %t.2/Library/Frameworks
+RUN: lld -flavor darwinnew -v -syslibroot %t -syslibroot %t.2 -F /Library/Frameworks | FileCheck %s -check-prefix CHECK-SYSLIBROOT-FRAMEWORK-MATRIX -DROOT=%t
+
+CHECK-SYSLIBROOT-FRAMEWORK-MATRIX: Framework search paths:
+CHECK-SYSLIBROOT-FRAMEWORK-MATRIX: [[ROOT]]/Library/Frameworks
+CHECK-SYSLIBROOT-FRAMEWORK-MATRIX: [[ROOT]].2/Library/Frameworks
More information about the llvm-commits
mailing list