Skip to content

Commit

Permalink
Merge pull request #2790 from kinke/libdirs
Browse files Browse the repository at this point in the history
Config file: Add `lib-dirs` array
  • Loading branch information
kinke authored Aug 19, 2018
2 parents 9bd4fb2 + a29d5fd commit 848fc7b
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 82 deletions.
36 changes: 14 additions & 22 deletions dmd/root/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,22 +285,22 @@ struct Array
return *this;
}

size_type size()
size_type size() const
{
return static_cast<size_type>(dim);
}

bool empty()
bool empty() const
{
return dim == 0;
}

TYPE front()
TYPE front() const
{
return data[0];
}

TYPE back()
TYPE back() const
{
return data[dim-1];
}
Expand All @@ -316,27 +316,19 @@ struct Array
}

typedef TYPE *iterator;
typedef const TYPE *const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

iterator begin()
{
return static_cast<iterator>(&data[0]);
}

iterator end()
{
return static_cast<iterator>(&data[dim]);
}
iterator begin() { return static_cast<iterator>(&data[0]); }
iterator end() { return static_cast<iterator>(&data[dim]); }
reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }

reverse_iterator rbegin()
{
return reverse_iterator(end());
}

reverse_iterator rend()
{
return reverse_iterator(begin());
}
const_iterator begin() const { return static_cast<const_iterator>(&data[0]); }
const_iterator end() const { return static_cast<const_iterator>(&data[dim]); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }

iterator erase(iterator pos)
{
Expand Down
4 changes: 4 additions & 0 deletions driver/configfile.d
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ private:
const(char)* pathcstr;
Array!(const(char)*) switches;
Array!(const(char)*) postSwitches;
Array!(const(char)*) _libDirs;
const(char)* rpathcstr;

static bool sectionMatches(const(char)* section, const(char)* triple);
Expand Down Expand Up @@ -161,6 +162,9 @@ private:
applyArray(this.switches, switches);
applyArray(this.postSwitches, postSwitches);

auto libDirs = findArraySetting(sections, "lib-dirs");
applyArray(_libDirs, libDirs);

if (auto rpath = findScalarSetting(sections, "rpath"))
this.rpathcstr = (rpath.val.replace("%%ldcbinarypath%%", dBinDir) ~ '\0').ptr;

Expand Down
5 changes: 4 additions & 1 deletion driver/configfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ class ConfigFile {

void extendCommandLine(llvm::SmallVectorImpl<const char *> &args);

llvm::StringRef rpath() {
const Array<const char *> &libDirs() const { return _libDirs; }

llvm::StringRef rpath() const {
return rpathcstr ? llvm::StringRef(rpathcstr) : llvm::StringRef();
}

Expand All @@ -46,6 +48,7 @@ class ConfigFile {
const char *pathcstr = nullptr;
Array<const char *> switches;
Array<const char *> postSwitches;
Array<const char *> _libDirs;
const char *rpathcstr = nullptr;
};

Expand Down
115 changes: 66 additions & 49 deletions driver/linker-gcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,31 +199,28 @@ llvm::StringRef getCompilerRTArchName(const llvm::Triple &triple) {
return triple.getArchName();
}

// Returns the libname as full path and with arch suffix and extension.
// For example, with name="libldc_rt.fuzzer", the returned string is
// Appends arch suffix and extension.
// E.g., for name="libldc_rt.fuzzer" and sharedLibrary=false, returns
// "libldc_rt.fuzzer_osx.a" on Darwin.
std::string getFullCompilerRTLibPath(const llvm::Triple &triple,
llvm::StringRef name,
bool sharedLibrary = false) {
if (triple.isOSDarwin()) {
return exe_path::prependLibDir(
name + (sharedLibrary ? "_osx_dynamic.dylib" : "_osx.a"));
} else {
return exe_path::prependLibDir(name + "-" + getCompilerRTArchName(triple) +
(sharedLibrary ? ".so" : ".a"));
}
std::string getCompilerRTLibFilename(const llvm::Twine &name,
const llvm::Triple &triple,
bool sharedLibrary) {
return (triple.isOSDarwin()
? name + (sharedLibrary ? "_osx_dynamic.dylib" : "_osx.a")
: name + "-" + getCompilerRTArchName(triple) +
(sharedLibrary ? ".so" : ".a"))
.str();
}

// Clang's RT libs are in a subdir of the lib dir.
// Returns the libname as full path and with arch suffix and extension.
// For example, with name="libclang_rt.asan" and sharedLibrary=true, the
// returned string is
// "clang/6.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib" on Darwin.
// E.g., for name="libclang_rt.asan" and sharedLibrary=true, returns
// "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...
// See clang/lib/Driver/Toolchain.cpp.
std::string getFullClangCompilerRTLibPath(const llvm::Triple &triple,
llvm::StringRef name,
bool sharedLibrary = false) {
std::string getRelativeClangCompilerRTLibPath(const llvm::Twine &name,
const llvm::Triple &triple,
bool sharedLibrary) {
llvm::StringRef OSName =
triple.isOSDarwin()
? "darwin"
Expand All @@ -233,15 +230,41 @@ std::string getFullClangCompilerRTLibPath(const llvm::Triple &triple,
"/lib/" + OSName + "/" + name)
.str();

if (triple.isOSDarwin()) {
return exe_path::prependLibDir(
llvm::Twine(relPath) +
(sharedLibrary ? "_osx_dynamic.dylib" : "_osx.a"));
} else {
return exe_path::prependLibDir(llvm::Twine(relPath) + "-" +
getCompilerRTArchName(triple) +
(sharedLibrary ? ".so" : ".a"));
return getCompilerRTLibFilename(relPath, triple, sharedLibrary);
}

void appendFullLibPathCandidates(std::vector<std::string> &paths,
const llvm::Twine &filename) {
for (const char *dir : ConfigFile::instance.libDirs()) {
llvm::SmallString<128> candidate(dir);
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) {
Expand All @@ -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
// to use the shared library.
bool linkSharedASan = triple.isOSDarwin();
std::string searchPaths[] = {
getFullCompilerRTLibPath(triple, "libldc_rt.asan", linkSharedASan),
getFullCompilerRTLibPath(triple, "libclang_rt.asan", linkSharedASan),
getFullClangCompilerRTLibPath(triple, "libclang_rt.asan", linkSharedASan),
};
const auto searchPaths =
getFullCompilerRTLibPathCandidates("asan", triple, linkSharedASan);

for (const auto &filepath : searchPaths) {
IF_LOG Logger::println("Searching ASan lib: %s", filepath.c_str());
Expand Down Expand Up @@ -293,16 +313,13 @@ void ArgsBuilder::addASanLinkFlags(const llvm::Triple &triple) {
// Adds all required link flags for -fsanitize=fuzzer when libFuzzer library is
// found.
void ArgsBuilder::addFuzzLinkFlags(const llvm::Triple &triple) {
std::string searchPaths[] = {
#if LDC_LLVM_VER >= 600
getFullCompilerRTLibPath(triple, "libldc_rt.fuzzer"),
getFullCompilerRTLibPath(triple, "libclang_rt.fuzzer"),
getFullClangCompilerRTLibPath(triple, "libclang_rt.fuzzer"),
const auto searchPaths = getFullCompilerRTLibPathCandidates("fuzzer", triple);
#else
exe_path::prependLibDir("libFuzzer.a"),
exe_path::prependLibDir("libLLVMFuzzer.a"),
std::vector<std::string> searchPaths;
appendFullLibPathCandidates(searchPaths, "libFuzzer.a");
appendFullLibPathCandidates(searchPaths, "libLLVMFuzzer.a");
#endif
};

for (const auto &filepath : searchPaths) {
IF_LOG Logger::println("Searching libFuzzer: %s", filepath.c_str());
Expand All @@ -323,11 +340,7 @@ void ArgsBuilder::addFuzzLinkFlags(const llvm::Triple &triple) {
// Adds all required link flags for -fxray-instrument when the xray library is
// found.
void ArgsBuilder::addXRayLinkFlags(const llvm::Triple &triple) {
std::string searchPaths[] = {
getFullCompilerRTLibPath(triple, "libldc_rt.xray"),
getFullCompilerRTLibPath(triple, "libclang_rt.xray"),
getFullClangCompilerRTLibPath(triple, "libclang_rt.xray"),
};
const auto searchPaths = getFullCompilerRTLibPathCandidates("xray", triple);

bool linkerDarwin = triple.isOSDarwin();
if (!triple.isOSLinux())
Expand Down Expand Up @@ -377,11 +390,8 @@ void ArgsBuilder::addCppStdlibLinkFlags(const llvm::Triple &triple) {

// Adds all required link flags for PGO.
void ArgsBuilder::addProfileRuntimeLinkFlags(const llvm::Triple &triple) {
std::string searchPaths[] = {
getFullCompilerRTLibPath(triple, "libldc_rt.profile"),
getFullCompilerRTLibPath(triple, "libclang_rt.profile"),
getFullClangCompilerRTLibPath(triple, "libclang_rt.profile"),
};
const auto searchPaths =
getFullCompilerRTLibPathCandidates("profile", triple);

#if LDC_LLVM_VER >= 308
if (global.params.targetTriple->isOSLinux()) {
Expand Down Expand Up @@ -478,6 +488,13 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
addLinker();
addUserSwitches();

// lib dirs
for (const char *dir_c : ConfigFile::instance.libDirs()) {
const llvm::StringRef dir(dir_c);
if (!dir.empty())
args.push_back(("-L" + dir).str());
}

// default libs
for (const auto &name : defaultLibNames) {
args.push_back("-l" + name);
Expand Down
20 changes: 17 additions & 3 deletions driver/linker-msvc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
#include "driver/cl_options.h"
#include "driver/cl_options_instrumentation.h"
#include "driver/cl_options_sanitizers.h"
#include "driver/configfile.h"
#include "driver/exe_path.h"
#include "driver/linker.h"
#include "driver/tool.h"
#include "gen/logger.h"

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"

#if LDC_WITH_LLD
#if LDC_LLVM_VER >= 600
Expand Down Expand Up @@ -59,9 +61,14 @@ void addMscrtLibs(std::vector<std::string> &args) {
}

void addLibIfFound(std::vector<std::string> &args, const llvm::Twine &name) {
std::string candidate = exe_path::prependLibDir(name);
if (llvm::sys::fs::exists(candidate))
args.push_back(std::move(candidate));
for (const char *dir : ConfigFile::instance.libDirs()) {
llvm::SmallString<128> candidate(dir);
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) {
Expand Down Expand Up @@ -169,6 +176,13 @@ int linkObjToBinaryMSVC(llvm::StringRef outputPath,
addSwitch(str);
}

// lib dirs
for (const char *dir_c : ConfigFile::instance.libDirs()) {
const llvm::StringRef dir(dir_c);
if (!dir.empty())
args.push_back(("/LIBPATH:" + dir).str());
}

// default libs
for (const auto &name : defaultLibNames) {
args.push_back(name + ".lib");
Expand Down
5 changes: 4 additions & 1 deletion ldc2.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ default:
post-switches = [
"-I@RUNTIME_DIR@/src",
"-I@JITRT_DIR@/d",
"-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@
];
// default directories to be searched for libraries when linking
lib-dirs = [
"@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@
];
// default rpath when linking against the shared default libs
rpath = "@SHARED_LIBS_RPATH@";
Expand Down
5 changes: 4 additions & 1 deletion ldc2_install.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ default:
post-switches = [
"-I@INCLUDE_INSTALL_DIR@/ldc",
"-I@INCLUDE_INSTALL_DIR@",
"-L-L@CMAKE_INSTALL_LIBDIR@",@MULTILIB_ADDITIONAL_INSTALL_PATH@
];
// default directories to be searched for libraries when linking
lib-dirs = [
"@CMAKE_INSTALL_LIBDIR@",@MULTILIB_ADDITIONAL_INSTALL_PATH@
];
// default rpath when linking against the shared default libs
rpath = "@SHARED_LIBS_INSTALL_RPATH@";
Expand Down
5 changes: 4 additions & 1 deletion ldc2_phobos.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ default:
"-I@RUNTIME_DIR@/src",
"-I@JITRT_DIR@/d",
"-I@PHOBOS2_DIR@",
"-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@
];
// default directories to be searched for libraries when linking
lib-dirs = [
"@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@
];
// default rpath when linking against the shared default libs
rpath = "@SHARED_LIBS_RPATH@";
Expand Down
9 changes: 5 additions & 4 deletions runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,9 @@ endif()
# DMD and GDC do). OS X doesn't need extra configuration due to the use of
# fat binaries. Other Posixen might need to be added here.
if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE")
set(MULTILIB_ADDITIONAL_PATH "\n \"-L-L${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}\",\n \"-L--no-warn-search-mismatch\",")
set(MULTILIB_ADDITIONAL_INSTALL_PATH "\n \"-L-L${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX}\",\n \"-L--no-warn-search-mismatch\",")
set(ADDITIONAL_DEFAULT_LDC_SWITCHES "${ADDITIONAL_DEFAULT_LDC_SWITCHES}\n \"-L--no-warn-search-mismatch\",")
set(MULTILIB_ADDITIONAL_PATH "\n \"${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}\",")
set(MULTILIB_ADDITIONAL_INSTALL_PATH "\n \"${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX}\",")
endif()

# Default -rpath linker option when linking against shared libraries.
Expand All @@ -256,9 +257,9 @@ endif()
# Only have either shared or static libs?
# Then explicitly default to linking against them via default LDC switch.
if(${BUILD_SHARED_LIBS} STREQUAL "ON")
set(ADDITIONAL_DEFAULT_LDC_SWITCHES "\n \"-link-defaultlib-shared\",")
set(ADDITIONAL_DEFAULT_LDC_SWITCHES "${ADDITIONAL_DEFAULT_LDC_SWITCHES}\n \"-link-defaultlib-shared\",")
elseif(${BUILD_SHARED_LIBS} STREQUAL "OFF")
set(ADDITIONAL_DEFAULT_LDC_SWITCHES "\n \"-link-defaultlib-shared=false\",")
set(ADDITIONAL_DEFAULT_LDC_SWITCHES "${ADDITIONAL_DEFAULT_LDC_SWITCHES}\n \"-link-defaultlib-shared=false\",")
endif()

if(LDC_WITH_LLD)
Expand Down

0 comments on commit 848fc7b

Please sign in to comment.