Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config file: Add lib-dirs array #2790

Merged
merged 2 commits into from
Aug 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()

# Only generate the config files if this CMake project is embedded in the LDC CMake project.
Expand Down