forked from OSchip/llvm-project
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
This commit is contained in:
parent
bd2c88b253
commit
0ccda7c232
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue