Use config file's lib-dirs when searching for compiler-rt libs

In addition (and preferred over) the previous searched-for lib dir
(`<bin dir>/../lib<LIB_SUFFIX CMake var>`). [Incl. searching in some of
their subdirs, e.g., `clang/x.y.z/lib/<OS>`.]

I skipped that backwards-compatibility thingy for the builtins lib on
Windows (not crucial, only linked (if found) on Windows etc.).
This commit is contained in:
Martin Kinkelin 2018-07-25 00:29:00 +02:00
parent ac070a386d
commit a29d5fd53e
2 changed files with 68 additions and 52 deletions

View file

@ -199,31 +199,28 @@ llvm::StringRef getCompilerRTArchName(const llvm::Triple &triple) {
return triple.getArchName(); return triple.getArchName();
} }
// Returns the libname as full path and with arch suffix and extension. // Appends arch suffix and extension.
// For example, with name="libldc_rt.fuzzer", the returned string is // E.g., for name="libldc_rt.fuzzer" and sharedLibrary=false, returns
// "libldc_rt.fuzzer_osx.a" on Darwin. // "libldc_rt.fuzzer_osx.a" on Darwin.
std::string getFullCompilerRTLibPath(const llvm::Triple &triple, std::string getCompilerRTLibFilename(const llvm::Twine &name,
llvm::StringRef name, const llvm::Triple &triple,
bool sharedLibrary = false) { bool sharedLibrary) {
if (triple.isOSDarwin()) { return (triple.isOSDarwin()
return exe_path::prependLibDir( ? name + (sharedLibrary ? "_osx_dynamic.dylib" : "_osx.a")
name + (sharedLibrary ? "_osx_dynamic.dylib" : "_osx.a")); : name + "-" + getCompilerRTArchName(triple) +
} else { (sharedLibrary ? ".so" : ".a"))
return exe_path::prependLibDir(name + "-" + getCompilerRTArchName(triple) + .str();
(sharedLibrary ? ".so" : ".a"));
}
} }
// Clang's RT libs are in a subdir of the lib dir. // Clang's RT libs are in a subdir of the lib dir.
// Returns the libname as full path and with arch suffix and extension. // E.g., for name="libclang_rt.asan" and sharedLibrary=true, returns
// For example, with name="libclang_rt.asan" and sharedLibrary=true, the // "clang/6.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib" on
// returned string is // Darwin.
// "clang/6.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib" on Darwin.
// This function is "best effort", the path may not be what Clang does... // This function is "best effort", the path may not be what Clang does...
// See clang/lib/Driver/Toolchain.cpp. // See clang/lib/Driver/Toolchain.cpp.
std::string getFullClangCompilerRTLibPath(const llvm::Triple &triple, std::string getRelativeClangCompilerRTLibPath(const llvm::Twine &name,
llvm::StringRef name, const llvm::Triple &triple,
bool sharedLibrary = false) { bool sharedLibrary) {
llvm::StringRef OSName = llvm::StringRef OSName =
triple.isOSDarwin() triple.isOSDarwin()
? "darwin" ? "darwin"
@ -233,15 +230,41 @@ std::string getFullClangCompilerRTLibPath(const llvm::Triple &triple,
"/lib/" + OSName + "/" + name) "/lib/" + OSName + "/" + name)
.str(); .str();
if (triple.isOSDarwin()) { return getCompilerRTLibFilename(relPath, triple, sharedLibrary);
return exe_path::prependLibDir( }
llvm::Twine(relPath) +
(sharedLibrary ? "_osx_dynamic.dylib" : "_osx.a")); void appendFullLibPathCandidates(std::vector<std::string> &paths,
} else { const llvm::Twine &filename) {
return exe_path::prependLibDir(llvm::Twine(relPath) + "-" + for (const char *dir : ConfigFile::instance.libDirs()) {
getCompilerRTArchName(triple) + llvm::SmallString<128> candidate(dir);
(sharedLibrary ? ".so" : ".a")); llvm::sys::path::append(candidate, filename);
paths.push_back(candidate.str());
} }
// for backwards compatibility
paths.push_back(exe_path::prependLibDir(filename));
}
// Returns candidates of full paths to a compiler-rt lib.
// E.g., for baseName="asan" and sharedLibrary=false, returns something like
// [ "<libDir>/libldc_rt.asan_osx.a",
// "<libDir>/libclang_rt.asan_osx.a",
// "<libDir>/clang/6.0.0/lib/darwin/libclang_rt.asan_osx.a" ].
std::vector<std::string>
getFullCompilerRTLibPathCandidates(llvm::StringRef baseName,
const llvm::Triple &triple,
bool sharedLibrary = false) {
std::vector<std::string> r;
const auto ldcRT =
getCompilerRTLibFilename("libldc_rt." + baseName, triple, sharedLibrary);
appendFullLibPathCandidates(r, ldcRT);
const auto clangRT = getCompilerRTLibFilename("libclang_rt." + baseName,
triple, sharedLibrary);
appendFullLibPathCandidates(r, clangRT);
const auto fullClangRT = getRelativeClangCompilerRTLibPath(
"libclang_rt." + baseName, triple, sharedLibrary);
appendFullLibPathCandidates(r, fullClangRT);
return r;
} }
void ArgsBuilder::addASanLinkFlags(const llvm::Triple &triple) { void ArgsBuilder::addASanLinkFlags(const llvm::Triple &triple) {
@ -253,11 +276,8 @@ void ArgsBuilder::addASanLinkFlags(const llvm::Triple &triple) {
// libclang_rt.asan-preinit-<arch>.a on Linux. On Darwin, the only option is // libclang_rt.asan-preinit-<arch>.a on Linux. On Darwin, the only option is
// to use the shared library. // to use the shared library.
bool linkSharedASan = triple.isOSDarwin(); bool linkSharedASan = triple.isOSDarwin();
std::string searchPaths[] = { const auto searchPaths =
getFullCompilerRTLibPath(triple, "libldc_rt.asan", linkSharedASan), getFullCompilerRTLibPathCandidates("asan", triple, linkSharedASan);
getFullCompilerRTLibPath(triple, "libclang_rt.asan", linkSharedASan),
getFullClangCompilerRTLibPath(triple, "libclang_rt.asan", linkSharedASan),
};
for (const auto &filepath : searchPaths) { for (const auto &filepath : searchPaths) {
IF_LOG Logger::println("Searching ASan lib: %s", filepath.c_str()); IF_LOG Logger::println("Searching ASan lib: %s", filepath.c_str());
@ -293,16 +313,13 @@ void ArgsBuilder::addASanLinkFlags(const llvm::Triple &triple) {
// Adds all required link flags for -fsanitize=fuzzer when libFuzzer library is // Adds all required link flags for -fsanitize=fuzzer when libFuzzer library is
// found. // found.
void ArgsBuilder::addFuzzLinkFlags(const llvm::Triple &triple) { void ArgsBuilder::addFuzzLinkFlags(const llvm::Triple &triple) {
std::string searchPaths[] = {
#if LDC_LLVM_VER >= 600 #if LDC_LLVM_VER >= 600
getFullCompilerRTLibPath(triple, "libldc_rt.fuzzer"), const auto searchPaths = getFullCompilerRTLibPathCandidates("fuzzer", triple);
getFullCompilerRTLibPath(triple, "libclang_rt.fuzzer"),
getFullClangCompilerRTLibPath(triple, "libclang_rt.fuzzer"),
#else #else
exe_path::prependLibDir("libFuzzer.a"), std::vector<std::string> searchPaths;
exe_path::prependLibDir("libLLVMFuzzer.a"), appendFullLibPathCandidates(searchPaths, "libFuzzer.a");
appendFullLibPathCandidates(searchPaths, "libLLVMFuzzer.a");
#endif #endif
};
for (const auto &filepath : searchPaths) { for (const auto &filepath : searchPaths) {
IF_LOG Logger::println("Searching libFuzzer: %s", filepath.c_str()); IF_LOG Logger::println("Searching libFuzzer: %s", filepath.c_str());
@ -323,11 +340,7 @@ void ArgsBuilder::addFuzzLinkFlags(const llvm::Triple &triple) {
// Adds all required link flags for -fxray-instrument when the xray library is // Adds all required link flags for -fxray-instrument when the xray library is
// found. // found.
void ArgsBuilder::addXRayLinkFlags(const llvm::Triple &triple) { void ArgsBuilder::addXRayLinkFlags(const llvm::Triple &triple) {
std::string searchPaths[] = { const auto searchPaths = getFullCompilerRTLibPathCandidates("xray", triple);
getFullCompilerRTLibPath(triple, "libldc_rt.xray"),
getFullCompilerRTLibPath(triple, "libclang_rt.xray"),
getFullClangCompilerRTLibPath(triple, "libclang_rt.xray"),
};
bool linkerDarwin = triple.isOSDarwin(); bool linkerDarwin = triple.isOSDarwin();
if (!triple.isOSLinux()) if (!triple.isOSLinux())
@ -377,11 +390,8 @@ void ArgsBuilder::addCppStdlibLinkFlags(const llvm::Triple &triple) {
// Adds all required link flags for PGO. // Adds all required link flags for PGO.
void ArgsBuilder::addProfileRuntimeLinkFlags(const llvm::Triple &triple) { void ArgsBuilder::addProfileRuntimeLinkFlags(const llvm::Triple &triple) {
std::string searchPaths[] = { const auto searchPaths =
getFullCompilerRTLibPath(triple, "libldc_rt.profile"), getFullCompilerRTLibPathCandidates("profile", triple);
getFullCompilerRTLibPath(triple, "libclang_rt.profile"),
getFullClangCompilerRTLibPath(triple, "libclang_rt.profile"),
};
#if LDC_LLVM_VER >= 308 #if LDC_LLVM_VER >= 308
if (global.params.targetTriple->isOSLinux()) { if (global.params.targetTriple->isOSLinux()) {

View file

@ -18,6 +18,7 @@
#include "gen/logger.h" #include "gen/logger.h"
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#if LDC_WITH_LLD #if LDC_WITH_LLD
#if LDC_LLVM_VER >= 600 #if LDC_LLVM_VER >= 600
@ -60,9 +61,14 @@ void addMscrtLibs(std::vector<std::string> &args) {
} }
void addLibIfFound(std::vector<std::string> &args, const llvm::Twine &name) { void addLibIfFound(std::vector<std::string> &args, const llvm::Twine &name) {
std::string candidate = exe_path::prependLibDir(name); for (const char *dir : ConfigFile::instance.libDirs()) {
if (llvm::sys::fs::exists(candidate)) llvm::SmallString<128> candidate(dir);
args.push_back(std::move(candidate)); llvm::sys::path::append(candidate, name);
if (llvm::sys::fs::exists(candidate)) {
args.push_back(candidate.str());
return;
}
}
} }
void addSanitizerLibs(std::vector<std::string> &args) { void addSanitizerLibs(std::vector<std::string> &args) {