Only set rpath when linking against shared default libs

This commit is contained in:
Martin 2018-04-20 18:44:49 +02:00
parent 611d32458d
commit 891234bbe4
13 changed files with 93 additions and 39 deletions

View file

@ -289,12 +289,6 @@ cl::opt<std::string>
"'-deps' alone prints module dependencies " "'-deps' alone prints module dependencies "
"(imports/file/version/debug/lib)")); "(imports/file/version/debug/lib)"));
cl::opt<cl::boolOrDefault>
staticFlag("static", llvm::cl::ZeroOrMore,
llvm::cl::desc("Create a statically linked binary, including "
"all system dependencies"),
cl::cat(linkingCategory));
cl::opt<bool> m32bits("m32", cl::desc("32 bit target"), cl::ZeroOrMore); cl::opt<bool> m32bits("m32", cl::desc("32 bit target"), cl::ZeroOrMore);
cl::opt<bool> m64bits("m64", cl::desc("64 bit target"), cl::ZeroOrMore); cl::opt<bool> m64bits("m64", cl::desc("64 bit target"), cl::ZeroOrMore);

View file

@ -68,7 +68,6 @@ extern cl::opt<std::string> moduleDeps;
extern cl::opt<std::string> cacheDir; extern cl::opt<std::string> cacheDir;
extern cl::list<std::string> linkerSwitches; extern cl::list<std::string> linkerSwitches;
extern cl::list<std::string> ccSwitches; extern cl::list<std::string> ccSwitches;
extern cl::opt<cl::boolOrDefault> staticFlag;
extern cl::opt<bool> m32bits; extern cl::opt<bool> m32bits;
extern cl::opt<bool> m64bits; extern cl::opt<bool> m64bits;

View file

@ -35,6 +35,8 @@ static llvm::cl::opt<std::string>
clConf("conf", llvm::cl::desc("Use configuration file <filename>"), clConf("conf", llvm::cl::desc("Use configuration file <filename>"),
llvm::cl::value_desc("filename"), llvm::cl::ZeroOrMore); llvm::cl::value_desc("filename"), llvm::cl::ZeroOrMore);
ConfigFile ConfigFile::instance;
#if _WIN32 #if _WIN32
std::string getUserHomeDirectory() { std::string getUserHomeDirectory() {
char buff[MAX_PATH]; char buff[MAX_PATH];

View file

@ -41,6 +41,16 @@ ArraySetting findArraySetting(GroupSetting section, string name)
return null; return null;
} }
ScalarSetting findScalarSetting(GroupSetting section, string name)
{
if (!section) return null;
foreach (c; section.children)
{
if (c.type == Setting.Type.scalar && c.name == name)
return cast(ScalarSetting) c;
}
return null;
}
string replace(string str, string pattern, string replacement) string replace(string str, string pattern, string replacement)
{ {
@ -95,6 +105,7 @@ private:
const(char)* pathcstr; const(char)* pathcstr;
Array!(const(char)*) switches; Array!(const(char)*) switches;
Array!(const(char)*) postSwitches; Array!(const(char)*) postSwitches;
const(char)* rpathcstr;
bool readConfig(const(char)* cfPath, const(char)* sectionName, const(char)* binDir) bool readConfig(const(char)* cfPath, const(char)* sectionName, const(char)* binDir)
{ {
@ -159,6 +170,18 @@ private:
applyArray(this.switches, switches); applyArray(this.switches, switches);
applyArray(this.postSwitches, postSwitches); applyArray(this.postSwitches, postSwitches);
ScalarSetting findScalar(string name)
{
auto r = findScalarSetting(section, name);
if (!r)
r = findScalarSetting(defaultSection, name);
return r;
}
auto rpath = findScalar("rpath");
if (rpath)
this.rpathcstr = (rpath.val.replace("%%ldcbinarypath%%", dBinDir) ~ '\0').ptr;
return true; return true;
} }
catch (Exception ex) catch (Exception ex)

View file

@ -21,11 +21,14 @@
class ConfigFile { class ConfigFile {
public: public:
static ConfigFile instance;
bool read(const char *explicitConfFile, const char *section); bool read(const char *explicitConfFile, const char *section);
std::string path() { return std::string(pathcstr); } std::string path() { return pathcstr; }
void extendCommandLine(llvm::SmallVectorImpl<const char *> &args); void extendCommandLine(llvm::SmallVectorImpl<const char *> &args);
std::string rpath() { return rpathcstr; }
private: private:
bool locate(std::string &pathstr); bool locate(std::string &pathstr);
@ -36,6 +39,7 @@ private:
const char *pathcstr = nullptr; const char *pathcstr = nullptr;
Array<const char *> switches; Array<const char *> switches;
Array<const char *> postSwitches; Array<const char *> postSwitches;
const char *rpathcstr = nullptr;
}; };
#endif // LDC_DRIVER_CONFIGFILE_H #endif // LDC_DRIVER_CONFIGFILE_H

View file

@ -11,8 +11,10 @@
#include "driver/cl_options.h" #include "driver/cl_options.h"
#include "driver/cl_options_instrumentation.h" #include "driver/cl_options_instrumentation.h"
#include "driver/cl_options_sanitizers.h" #include "driver/cl_options_sanitizers.h"
#include "driver/configfile.h"
#include "driver/exe_path.h" #include "driver/exe_path.h"
#include "driver/ldc-version.h" #include "driver/ldc-version.h"
#include "driver/linker.h"
#include "driver/tool.h" #include "driver/tool.h"
#include "gen/irstate.h" #include "gen/irstate.h"
#include "gen/logger.h" #include "gen/logger.h"
@ -476,11 +478,18 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
addLinker(); addLinker();
addUserSwitches(); addUserSwitches();
// libs added via pragma(lib, libname) // default libs and libs added via pragma(lib, libname)
for (auto ls : global.params.linkswitches) { for (auto ls : global.params.linkswitches) {
args.push_back(ls); args.push_back(ls);
} }
// -rpath if linking against shared default libs
if (willLinkAgainstSharedDefaultLibs()) {
const std::string rpath = ConfigFile::instance.rpath();
if (!rpath.empty())
addLdFlag("-rpath", rpath);
}
if (global.params.targetTriple->getOS() == llvm::Triple::Linux) { if (global.params.targetTriple->getOS() == llvm::Triple::Linux) {
// Make sure we don't do --gc-sections when generating a profile- // Make sure we don't do --gc-sections when generating a profile-
// instrumented binary. The runtime relies on magic sections, which // instrumented binary. The runtime relies on magic sections, which

View file

@ -18,26 +18,38 @@
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SourceMgr.h"
namespace cl = llvm::cl;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#if LDC_WITH_LLD #if LDC_WITH_LLD
static llvm::cl::opt<bool> static cl::opt<bool> useInternalLinker("link-internally", cl::ZeroOrMore,
useInternalLinker("link-internally", llvm::cl::ZeroOrMore, cl::desc("Use internal LLD for linking"),
llvm::cl::desc("Use internal LLD for linking"), cl::cat(opts::linkingCategory));
llvm::cl::cat(opts::linkingCategory));
#else #else
constexpr bool useInternalLinker = false; constexpr bool useInternalLinker = false;
#endif #endif
static cl::opt<cl::boolOrDefault>
staticFlag("static", cl::ZeroOrMore,
cl::desc("Create a statically linked binary, including "
"all system dependencies"),
cl::cat(opts::linkingCategory));
static cl::opt<cl::boolOrDefault> linkDefaultLibShared(
"link-defaultlib-shared", cl::ZeroOrMore,
cl::desc("Link with shared versions of default libraries"),
cl::cat(opts::linkingCategory));
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// linker-gcc.cpp // linker-gcc.cpp
int linkObjToBinaryGcc(llvm::StringRef outputPath, bool useInternalLinker, int linkObjToBinaryGcc(llvm::StringRef outputPath, bool useInternalLinker,
llvm::cl::boolOrDefault fullyStaticFlag); cl::boolOrDefault fullyStaticFlag);
// linker-msvc.cpp // linker-msvc.cpp
int linkObjToBinaryMSVC(llvm::StringRef outputPath, bool useInternalLinker, int linkObjToBinaryMSVC(llvm::StringRef outputPath, bool useInternalLinker,
llvm::cl::boolOrDefault fullyStaticFlag); cl::boolOrDefault fullyStaticFlag);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -87,6 +99,16 @@ static std::string getOutputName() {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
bool willLinkAgainstSharedDefaultLibs() {
// -static enforces static default libs.
// Default to shared default libs for DLLs.
return staticFlag != cl::BOU_TRUE &&
(linkDefaultLibShared == cl::BOU_TRUE ||
(linkDefaultLibShared == cl::BOU_UNSET && global.params.dll));
}
//////////////////////////////////////////////////////////////////////////////
/// Insert an LLVM bitcode file into the module /// Insert an LLVM bitcode file into the module
static void insertBitcodeIntoModule(const char *bcFile, llvm::Module &M, static void insertBitcodeIntoModule(const char *bcFile, llvm::Module &M,
llvm::LLVMContext &Context) { llvm::LLVMContext &Context) {
@ -130,10 +152,10 @@ int linkObjToBinary() {
createDirectoryForFileOrFail(gExePath); createDirectoryForFileOrFail(gExePath);
if (global.params.targetTriple->isWindowsMSVCEnvironment()) { if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
return linkObjToBinaryMSVC(gExePath, useInternalLinker, opts::staticFlag); return linkObjToBinaryMSVC(gExePath, useInternalLinker, staticFlag);
} }
return linkObjToBinaryGcc(gExePath, useInternalLinker, opts::staticFlag); return linkObjToBinaryGcc(gExePath, useInternalLinker, staticFlag);
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View file

@ -22,6 +22,12 @@ class LLVMContext;
template <typename TYPE> struct Array; template <typename TYPE> struct Array;
/**
* Indicates whether the command-line options select shared druntime/Phobos for
* linking.
*/
bool willLinkAgainstSharedDefaultLibs();
/** /**
* Inserts bitcode files passed on the commandline into a module. * Inserts bitcode files passed on the commandline into a module.
*/ */

View file

@ -119,11 +119,6 @@ static cl::alias _linkDebugLib("link-debuglib", cl::Hidden,
cl::desc("Alias for -link-defaultlib-debug"), cl::desc("Alias for -link-defaultlib-debug"),
cl::cat(linkingCategory)); cl::cat(linkingCategory));
static cl::opt<bool> linkDefaultLibShared(
"link-defaultlib-shared", cl::ZeroOrMore,
cl::desc("Link with shared versions of default libraries"),
cl::cat(linkingCategory));
// This function exits the program. // This function exits the program.
void printVersion(llvm::raw_ostream &OS) { void printVersion(llvm::raw_ostream &OS) {
OS << "LDC - the LLVM D compiler (" << global.ldc_version << "):\n"; OS << "LDC - the LLVM D compiler (" << global.ldc_version << "):\n";
@ -325,7 +320,7 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,
expandResponseFiles(allocator, allArguments); expandResponseFiles(allocator, allArguments);
// read config file // read config file
ConfigFile cfg_file; ConfigFile &cfg_file = ConfigFile::instance;
const char *explicitConfFile = tryGetExplicitConfFile(allArguments); const char *explicitConfFile = tryGetExplicitConfFile(allArguments);
const std::string cfg_triple = tryGetExplicitTriple(allArguments).getTriple(); const std::string cfg_triple = tryGetExplicitTriple(allArguments).getTriple();
// just ignore errors for now, they are still printed // just ignore errors for now, they are still printed
@ -502,13 +497,7 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,
} else if (!global.params.betterC) { } else if (!global.params.betterC) {
const bool addDebugSuffix = const bool addDebugSuffix =
(linkDefaultLibDebug && debugLib.getNumOccurrences() == 0); (linkDefaultLibDebug && debugLib.getNumOccurrences() == 0);
const bool addSharedSuffix = willLinkAgainstSharedDefaultLibs();
// -static enforces static default libs.
// Default to shared default libs for DLLs.
const bool addSharedSuffix =
staticFlag != cl::BOU_TRUE &&
(linkDefaultLibShared ||
(linkDefaultLibShared.getNumOccurrences() == 0 && global.params.dll));
// Parse comma-separated default library list. // Parse comma-separated default library list.
std::stringstream libNames( std::stringstream libNames(

View file

@ -7,11 +7,13 @@ default:
// default switches injected before all explicit command-line switches // default switches injected before all explicit command-line switches
switches = [ switches = [
"-I@RUNTIME_DIR@/src", "-I@RUNTIME_DIR@/src",
"-I@JITRT_DIR@/d",@SHARED_LIBS_RPATH@ "-I@JITRT_DIR@/d",
"-defaultlib=druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ "-defaultlib=druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
// default switches appended after all explicit command-line switches // default switches appended after all explicit command-line switches
post-switches = [ post-switches = [
"-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@ "-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@
]; ];
// default rpath when linking against the shared default libs
rpath = "@SHARED_LIBS_RPATH@";
}; };

View file

@ -7,11 +7,13 @@ default:
// default switches injected before all explicit command-line switches // default switches injected before all explicit command-line switches
switches = [ switches = [
"-I@INCLUDE_INSTALL_DIR@/ldc", "-I@INCLUDE_INSTALL_DIR@/ldc",
"-I@INCLUDE_INSTALL_DIR@",@SHARED_LIBS_INSTALL_RPATH@ "-I@INCLUDE_INSTALL_DIR@",
"-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ "-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
// default switches appended after all explicit command-line switches // default switches appended after all explicit command-line switches
post-switches = [ post-switches = [
"-L-L@CMAKE_INSTALL_LIBDIR@",@MULTILIB_ADDITIONAL_INSTALL_PATH@ "-L-L@CMAKE_INSTALL_LIBDIR@",@MULTILIB_ADDITIONAL_INSTALL_PATH@
]; ];
// default rpath when linking against the shared default libs
rpath = "@SHARED_LIBS_INSTALL_RPATH@";
}; };

View file

@ -8,11 +8,13 @@ default:
switches = [ switches = [
"-I@RUNTIME_DIR@/src", "-I@RUNTIME_DIR@/src",
"-I@JITRT_DIR@/d", "-I@JITRT_DIR@/d",
"-I@PHOBOS2_DIR@",@SHARED_LIBS_RPATH@ "-I@PHOBOS2_DIR@",
"-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ "-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
// default switches appended after all explicit command-line switches // default switches appended after all explicit command-line switches
post-switches = [ post-switches = [
"-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@ "-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@
]; ];
// default rpath when linking against the shared default libs
rpath = "@SHARED_LIBS_RPATH@";
}; };

View file

@ -251,14 +251,14 @@ if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE")
set(MULTILIB_ADDITIONAL_INSTALL_PATH "\n \"-L-L${CMAKE_INSTALL_PREFIX}/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\",")
endif() endif()
# Set the -rpath linker option when shared runtime libraries are built. # Default -rpath linker option when linking against shared libraries.
if(NOT ${BUILD_SHARED_LIBS} STREQUAL "OFF") if(SHARED_LIBS_SUPPORTED)
if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE") if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE")
set(SHARED_LIBS_RPATH "\n \"-L-rpath\", \"-L${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}:${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}\",") set(SHARED_LIBS_RPATH "${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}:${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}")
set(SHARED_LIBS_INSTALL_RPATH "\n \"-L-rpath\", \"-L${CMAKE_INSTALL_LIBDIR}:${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX}\",") set(SHARED_LIBS_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}:${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX}")
else() else()
set(SHARED_LIBS_RPATH "\n \"-L-rpath\", \"-L${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}\",") set(SHARED_LIBS_RPATH "${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}")
set(SHARED_LIBS_INSTALL_RPATH "\n \"-L-rpath\", \"-L${CMAKE_INSTALL_LIBDIR}\",") set(SHARED_LIBS_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}")
endif() endif()
endif() endif()