mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-09 04:15:58 +03:00
parent
3d7e4c0036
commit
aafd6541c7
4 changed files with 67 additions and 21 deletions
|
@ -284,11 +284,13 @@ cl::list<std::string> transitions(
|
|||
"Help with language change identified by <idents>, use ? for list"),
|
||||
cl::value_desc("idents"), cl::CommaSeparated);
|
||||
|
||||
static StringsAdapter linkSwitchStore("L", global.params.linkswitches);
|
||||
static cl::list<std::string, StringsAdapter>
|
||||
linkerSwitches("L", cl::desc("Pass <linkerflag> to the linker"),
|
||||
cl::value_desc("linkerflag"), cl::location(linkSwitchStore),
|
||||
cl::Prefix);
|
||||
cl::list<std::string> linkerSwitches("L",
|
||||
cl::desc("Pass <linkerflag> to the linker"),
|
||||
cl::value_desc("linkerflag"), cl::Prefix);
|
||||
|
||||
cl::list<std::string> ccSwitches("Xcc", cl::CommaSeparated,
|
||||
cl::desc("Pass <ccflag> to GCC/Clang for linking"),
|
||||
cl::value_desc("ccflag"));
|
||||
|
||||
cl::opt<std::string>
|
||||
moduleDeps("deps",
|
||||
|
|
|
@ -66,6 +66,8 @@ extern cl::list<std::string> versions;
|
|||
extern cl::list<std::string> transitions;
|
||||
extern cl::opt<std::string> moduleDeps;
|
||||
extern cl::opt<std::string> cacheDir;
|
||||
extern cl::list<std::string> linkerSwitches;
|
||||
extern cl::list<std::string> ccSwitches;
|
||||
|
||||
extern cl::opt<std::string> mArch;
|
||||
extern cl::opt<bool> m32bits;
|
||||
|
|
|
@ -355,21 +355,38 @@ static int linkObjToBinaryGcc(bool sharedLib) {
|
|||
if (opts::isUsingLTO())
|
||||
addLTOLinkFlags(args);
|
||||
|
||||
// additional linker switches
|
||||
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
|
||||
const char *p = (*global.params.linkswitches)[i];
|
||||
// Don't push -l and -L switches using -Xlinker, but pass them indirectly
|
||||
// via GCC. This makes sure user-defined paths take precedence over
|
||||
// GCC's builtin LIBRARY_PATHs.
|
||||
// Options starting with `-Wl,`, -shared or -static are not handled by
|
||||
// the linker and must be passed to the driver.
|
||||
auto str = llvm::StringRef(p);
|
||||
if (!(str.startswith("-l") || str.startswith("-L") ||
|
||||
str.startswith("-Wl,") ||
|
||||
str.startswith("-shared") || str.startswith("-static"))) {
|
||||
args.push_back("-Xlinker");
|
||||
// additional linker and cc switches (preserve order across both lists)
|
||||
for (unsigned ilink = 0, icc = 0;;) {
|
||||
unsigned linkpos = ilink < opts::linkerSwitches.size()
|
||||
? opts::linkerSwitches.getPosition(ilink)
|
||||
: std::numeric_limits<unsigned>::max();
|
||||
unsigned ccpos = icc < opts::ccSwitches.size()
|
||||
? opts::ccSwitches.getPosition(icc)
|
||||
: std::numeric_limits<unsigned>::max();
|
||||
if (linkpos < ccpos) {
|
||||
const std::string& p = opts::linkerSwitches[ilink++];
|
||||
// Don't push -l and -L switches using -Xlinker, but pass them indirectly
|
||||
// via GCC. This makes sure user-defined paths take precedence over
|
||||
// GCC's builtin LIBRARY_PATHs.
|
||||
// Options starting with `-Wl,`, -shared or -static are not handled by
|
||||
// the linker and must be passed to the driver.
|
||||
auto str = llvm::StringRef(p);
|
||||
if (!(str.startswith("-l") || str.startswith("-L") ||
|
||||
str.startswith("-Wl,") ||
|
||||
str.startswith("-shared") || str.startswith("-static"))) {
|
||||
args.push_back("-Xlinker");
|
||||
}
|
||||
args.push_back(p);
|
||||
} else if (ccpos < linkpos) {
|
||||
args.push_back(opts::ccSwitches[icc++]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
args.push_back(p);
|
||||
}
|
||||
|
||||
// libs added via pragma(lib, libname)
|
||||
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
|
||||
args.push_back((*global.params.linkswitches)[i]);
|
||||
}
|
||||
|
||||
// default libs
|
||||
|
@ -518,6 +535,11 @@ static void addMscrtLibs(std::vector<std::string> &args) {
|
|||
static int linkObjToBinaryMSVC(bool sharedLib) {
|
||||
Logger::println("*** Linking executable ***");
|
||||
|
||||
if (!opts::ccSwitches.empty()) {
|
||||
error(Loc(), "-Xcc is not supported for MSVC");
|
||||
fatal();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
windows::setupMsvcEnvironment();
|
||||
#endif
|
||||
|
@ -584,8 +606,7 @@ static int linkObjToBinaryMSVC(bool sharedLib) {
|
|||
CreateDirectoryOnDisk(gExePath);
|
||||
|
||||
// additional linker switches
|
||||
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
|
||||
std::string str = global.params.linkswitches->data[i];
|
||||
auto addSwitch = [&](std::string str) {
|
||||
if (str.length() > 2) {
|
||||
// rewrite common -L and -l switches
|
||||
if (str[0] == '-' && str[1] == 'L') {
|
||||
|
@ -595,6 +616,14 @@ static int linkObjToBinaryMSVC(bool sharedLib) {
|
|||
}
|
||||
}
|
||||
args.push_back(str);
|
||||
};
|
||||
|
||||
for (const auto& str : opts::linkerSwitches) {
|
||||
addSwitch(str);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
|
||||
addSwitch(global.params.linkswitches->data[i]);
|
||||
}
|
||||
|
||||
// default libs
|
||||
|
|
13
tests/linking/linker_switches.d
Normal file
13
tests/linking/linker_switches.d
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Test if global order of flags passed with -Xcc, -L and pragma(lib) is preserved
|
||||
|
||||
// UNSUPPORTED: Windows
|
||||
|
||||
// RUN: /bin/sh -c '%ldc %s -of=%t -Xcc -DOPT1,-DOPT2 -L-L/usr/lib -L--defsym -Lfoo=5 -Xcc -DOPT3 -v 2>/dev/null || true' | FileCheck %s
|
||||
|
||||
// CHECK: -DOPT1 -DOPT2 -L/usr/lib -Xlinker --defsym -Xlinker foo=5 -DOPT3 {{.*}}-lpthread
|
||||
|
||||
pragma(lib, "pthread");
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue