[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