[pkg-d-commits] [ldc] 27/74: Add switch '-Xcc <ccflag>'. Fix #2093. (#2104)
Matthias Klumpp
mak at moszumanska.debian.org
Thu Jul 13 20:54:16 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.3.0-beta2
in repository ldc.
commit aafd6541c7e3ee99d0bf4924ba3a5c18eafd5fd5
Author: Adrian Matoga <adrian at matoga.info>
Date: Tue May 16 20:23:02 2017 +0200
Add switch '-Xcc <ccflag>'. Fix #2093. (#2104)
---
driver/cl_options.cpp | 12 ++++----
driver/cl_options.h | 2 ++
driver/linker.cpp | 61 ++++++++++++++++++++++++++++++-----------
tests/linking/linker_switches.d | 13 +++++++++
4 files changed, 67 insertions(+), 21 deletions(-)
diff --git a/driver/cl_options.cpp b/driver/cl_options.cpp
index 9cac488..c13ede3 100644
--- a/driver/cl_options.cpp
+++ b/driver/cl_options.cpp
@@ -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",
diff --git a/driver/cl_options.h b/driver/cl_options.h
index aa76b0b..03683b6 100644
--- a/driver/cl_options.h
+++ b/driver/cl_options.h
@@ -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;
diff --git a/driver/linker.cpp b/driver/linker.cpp
index 5b6ae27..fcb7d0c 100644
--- a/driver/linker.cpp
+++ b/driver/linker.cpp
@@ -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
diff --git a/tests/linking/linker_switches.d b/tests/linking/linker_switches.d
new file mode 100644
index 0000000..ee3c1ce
--- /dev/null
+++ b/tests/linking/linker_switches.d
@@ -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()
+{
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git
More information about the pkg-d-commits
mailing list