[pkg-d-commits] [ldc] 34/211: Don't reverse order of object file names

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:36:07 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.1.0
in repository ldc.

commit b1a6315ee47eb694b8da5e64681622a7aa901c7c
Author: Martin <noone at nowhere.com>
Date:   Sat Sep 17 22:42:50 2016 +0200

    Don't reverse order of object file names
    
    Make sure the overall order corresponds to the user's command-line order
    of object and source files. The only exception being singleObj builds,
    for which the single object file for all source files is always the first
    entry in the object files list (which is forwarded to the linker in that
    order). This is done so that we can easily get hold of the name when
    emitting the single object file later in the `ldc::CodeGenerator` dtor.
    It should also clearly define the linking order (affecting comdat
    selections etc.) for special singleObj builds.
    
    Also reuse some more code (wrt. output filenames) from DMD's main().
---
 ddmd/mars.d                         | 81 ++++++++++++++++++++++++++-----------
 driver/codegenerator.cpp            | 21 ++--------
 driver/codegenerator.h              |  1 -
 driver/linker.cpp                   | 27 +++++--------
 driver/main.cpp                     | 43 +++-----------------
 tests/codegen/inferred_outputname.d | 19 +++++++++
 tests/codegen/inputs/foo.d          |  1 +
 7 files changed, 96 insertions(+), 97 deletions(-)

diff --git a/ddmd/mars.d b/ddmd/mars.d
index 07e813d..005fc50 100644
--- a/ddmd/mars.d
+++ b/ddmd/mars.d
@@ -154,6 +154,7 @@ version(IN_LLVM)
 
     void genCmain(Scope* sc);
     // in driver/main.cpp
+    void addDefaultVersionIdentifiers();
     void codegenModules(ref Modules modules);
     // in driver/linker.cpp
     int linkObjToBinary();
@@ -1102,6 +1103,14 @@ Language changes listed by -transition=id:
         global.params.useAssert = true;
     if (!global.params.obj || global.params.lib)
         global.params.link = false;
+
+    return mars_mainBody(files, libmodules);
+}
+
+} // !IN_LLVM
+
+extern (C++) int mars_mainBody(ref Strings files, ref Strings libmodules)
+{
     if (global.params.link)
     {
         global.params.exefile = global.params.objname;
@@ -1131,9 +1140,12 @@ Language changes listed by -transition=id:
     {
         global.params.libname = global.params.objname;
         global.params.objname = null;
+      version (IN_LLVM) {} else
+      {
         // Haven't investigated handling these options with multiobj
         if (!global.params.cov && !global.params.trace)
             global.params.multiobj = true;
+      }
     }
     else
     {
@@ -1147,17 +1159,13 @@ Language changes listed by -transition=id:
 
     // Predefined version identifiers
     addDefaultVersionIdentifiers();
+  version (IN_LLVM) {} else
+  {
     objc_tryMain_dObjc();
 
     setDefaultLibrary();
+  }
 
-    return mars_mainBody(files, libmodules);
-}
-
-} // !IN_LLVM
-
-extern (C++) int mars_mainBody(ref Strings files, ref Strings libmodules)
-{
     // Initialization
     Type._init();
     Id.initialize();
@@ -1214,7 +1222,14 @@ extern (C++) int mars_mainBody(ref Strings files, ref Strings libmodules)
     // Create Modules
     Modules modules;
     modules.reserve(files.dim);
+  version (IN_LLVM)
+  {
+    size_t firstModuleObjectFileIndex = size_t.max;
+  }
+  else
+  {
     bool firstmodule = true;
+  }
     for (size_t i = 0; i < files.dim; i++)
     {
         const(char)* name;
@@ -1337,7 +1352,23 @@ extern (C++) int mars_mainBody(ref Strings files, ref Strings libmodules)
         auto id = Identifier.idPool(name, strlen(name));
         auto m = new Module(files[i], id, global.params.doDocComments, global.params.doHdrGeneration);
         modules.push(m);
-      version (IN_LLVM) {} else
+      version (IN_LLVM)
+      {
+        // If `-run` is passed, the obj file is temporary and is removed after execution.
+        // Make sure the name does not collide with other files from other processes by
+        // creating a unique filename.
+        if (global.params.run)
+            m.makeObjectFilenameUnique();
+
+        if (!global.params.oneobj || firstModuleObjectFileIndex == size_t.max)
+        {
+            global.params.objfiles.push(m.objfile.name.str);
+            m.checkAndAddOutputFile(m.objfile);
+            if (firstModuleObjectFileIndex == size_t.max)
+                firstModuleObjectFileIndex = global.params.objfiles.dim - 1;
+        }
+      }
+      else
       {
         if (firstmodule)
         {
@@ -1346,6 +1377,19 @@ extern (C++) int mars_mainBody(ref Strings files, ref Strings libmodules)
         }
       }
     }
+  version (IN_LLVM)
+  {
+    if (global.params.oneobj && modules.dim < 2)
+        global.params.oneobj = false;
+    // global.params.oneobj => move object file for first source file to
+    // beginning of object files list
+    if (global.params.oneobj && firstModuleObjectFileIndex != 0)
+    {
+        auto fn = (*global.params.objfiles)[firstModuleObjectFileIndex];
+        global.params.objfiles.remove(firstModuleObjectFileIndex);
+        global.params.objfiles.insert(0, fn);
+    }
+  }
     // Read files
     /* Start by "reading" the dummy main.d file
      */
@@ -1612,22 +1656,6 @@ extern (C++) int mars_mainBody(ref Strings files, ref Strings libmodules)
     }
   version (IN_LLVM)
   {
-    for (size_t i = 0; i < modules.dim; i++)
-    {
-        Module m = modules[i];
-        if (!m.objfile)
-            continue;
-
-        // If `-run` is passed, the obj file is temporary and is removed after execution.
-        // Make sure the name does not collide with other files from other processes by
-        // creating a unique filename.
-        if (global.params.run)
-            m.makeObjectFilenameUnique();
-
-        if (!global.params.oneobj || i == 0)
-            m.checkAndAddOutputFile(m.objfile);
-    }
-
     codegenModules(modules);
   }
   else
@@ -1959,6 +1987,9 @@ extern (C++) Expressions* Expressions_create()
     return new Expressions();
 }
 
+version (IN_LLVM) {} else
+{
+
 /**
  * Set the default and debug libraries to link against, if not already set
  *
@@ -2110,3 +2141,5 @@ private void addDefaultVersionIdentifiers()
         VersionCondition.addPredefinedGlobalIdent("D_NoBoundsChecks");
     VersionCondition.addPredefinedGlobalIdent("D_HardFloat");
 }
+
+} // !IN_LLVM
diff --git a/driver/codegenerator.cpp b/driver/codegenerator.cpp
index 55602f3..2ee78a4 100644
--- a/driver/codegenerator.cpp
+++ b/driver/codegenerator.cpp
@@ -77,8 +77,7 @@ void emitLinkerOptions(IRState &irs, llvm::Module &M, llvm::LLVMContext &ctx) {
 
 namespace ldc {
 CodeGenerator::CodeGenerator(llvm::LLVMContext &context, bool singleObj)
-    : context_(context), moduleCount_(0), singleObj_(singleObj), ir_(nullptr),
-      firstModuleObjfileName_(nullptr) {
+    : context_(context), moduleCount_(0), singleObj_(singleObj), ir_(nullptr) {
   if (!ClassDeclaration::object) {
     error(Loc(), "declaration for class Object not found; druntime not "
                  "configured properly");
@@ -95,17 +94,9 @@ CodeGenerator::CodeGenerator(llvm::LLVMContext &context, bool singleObj)
 
 CodeGenerator::~CodeGenerator() {
   if (singleObj_) {
-    const char *oname;
-    const char *filename;
-    if ((oname = global.params.exefile) || (oname = global.params.objname)) {
-      filename = FileName::forceExt(oname, global.obj_ext);
-      if (global.params.objdir) {
-        filename =
-            FileName::combine(global.params.objdir, FileName::name(filename));
-      }
-    } else {
-      filename = firstModuleObjfileName_;
-    }
+    // For singleObj builds, the first object file name is the one for the first
+    // source file (e.g., `b.o` for `ldc2 a.o b.d c.d`).
+    const char *filename = (*global.params.objfiles)[0];
 
     // If there are bitcode files passed on the cmdline, add them after all
     // other source files have been added to the (singleobj) module.
@@ -117,9 +108,6 @@ CodeGenerator::~CodeGenerator() {
 }
 
 void CodeGenerator::prepareLLModule(Module *m) {
-  if (!firstModuleObjfileName_) {
-    firstModuleObjfileName_ = m->objfile->name->str;
-  }
   ++moduleCount_;
 
   if (singleObj_ && ir_) {
@@ -181,7 +169,6 @@ void CodeGenerator::writeAndFreeLLModule(const char *filename) {
   IdentMetadata->addOperand(llvm::MDNode::get(ir_->context(), IdentNode));
 
   writeModule(&ir_->module, filename);
-  global.params.objfiles->push(const_cast<char *>(filename));
   delete ir_;
   ir_ = nullptr;
 }
diff --git a/driver/codegenerator.h b/driver/codegenerator.h
index c24248e..6871a12 100644
--- a/driver/codegenerator.h
+++ b/driver/codegenerator.h
@@ -39,7 +39,6 @@ private:
   int moduleCount_;
   bool const singleObj_;
   IRState *ir_;
-  const char *firstModuleObjfileName_;
 };
 }
 
diff --git a/driver/linker.cpp b/driver/linker.cpp
index 576545a..14e6f30 100644
--- a/driver/linker.cpp
+++ b/driver/linker.cpp
@@ -149,10 +149,8 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
   std::vector<std::string> args;
 
   // object files
-  for (unsigned i = 0; i < global.params.objfiles->dim; i++) {
-    const char *p = static_cast<const char *>(global.params.objfiles->data[i]);
-    args.push_back(p);
-  }
+  for (unsigned i = 0; i < global.params.objfiles->dim; i++)
+    args.push_back((*global.params.objfiles)[i]);
 
   // Link with profile-rt library when generating an instrumented binary.
   // profile-rt uses Phobos (MD5 hashing) and therefore must be passed on the
@@ -170,10 +168,8 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
   }
 
   // user libs
-  for (unsigned i = 0; i < global.params.libfiles->dim; i++) {
-    const char *p = static_cast<const char *>(global.params.libfiles->data[i]);
-    args.push_back(p);
-  }
+  for (unsigned i = 0; i < global.params.libfiles->dim; i++)
+    args.push_back((*global.params.libfiles)[i]);
 
   // output filename
   std::string output = getOutputName(sharedLib);
@@ -211,8 +207,7 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
 
   // additional linker switches
   for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
-    const char *p =
-        static_cast<const char *>(global.params.linkswitches->data[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.
@@ -598,10 +593,8 @@ static int linkObjToBinaryWin(bool sharedLib) {
   args.push_back("/OUT:" + output);
 
   // object files
-  for (unsigned i = 0; i < global.params.objfiles->dim; i++) {
-    const char *p = static_cast<const char *>(global.params.objfiles->data[i]);
-    args.push_back(p);
-  }
+  for (unsigned i = 0; i < global.params.objfiles->dim; i++)
+    args.push_back((*global.params.objfiles)[i]);
 
   // Link with profile-rt library when generating an instrumented binary
   // profile-rt depends on Phobos (MD5 hashing).
@@ -612,10 +605,8 @@ static int linkObjToBinaryWin(bool sharedLib) {
   }
 
   // user libs
-  for (unsigned i = 0; i < global.params.libfiles->dim; i++) {
-    const char *p = static_cast<const char *>(global.params.libfiles->data[i]);
-    args.push_back(p);
-  }
+  for (unsigned i = 0; i < global.params.libfiles->dim; i++)
+    args.push_back((*global.params.libfiles)[i]);
 
   // set the global gExePath
   gExePath = output;
diff --git a/driver/main.cpp b/driver/main.cpp
index 73e5300..595f8e5 100644
--- a/driver/main.cpp
+++ b/driver/main.cpp
@@ -658,37 +658,6 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,
     mRelocModel = llvm::Reloc::PIC_;
   }
 
-  if (global.params.link) {
-    global.params.exefile = global.params.objname;
-    global.params.oneobj = true;
-    if (global.params.objname) {
-      /* Use this to name the one object file with the same
-       * name as the exe file.
-       */
-      global.params.objname =
-          FileName::forceExt(global.params.objname, global.obj_ext);
-      /* If output directory is given, use that path rather than
-       * the exe file path.
-       */
-      if (global.params.objdir) {
-        const char *name = FileName::name(global.params.objname);
-        global.params.objname = FileName::combine(global.params.objdir, name);
-      }
-    }
-  } else if (global.params.run) {
-    error(Loc(), "flags conflict with -run");
-    fatal();
-  } else if (global.params.lib) {
-    global.params.libname = global.params.objname;
-    global.params.objname = nullptr;
-  } else {
-    if (global.params.objname && sourceFiles.dim > 1) {
-      global.params.oneobj = true;
-      // error("multiple source files, but only one .obj name");
-      // fatal();
-    }
-  }
-
   if (soname.getNumOccurrences() > 0 && !global.params.dll) {
     error(Loc(), "-soname can be used only when building a shared library");
   }
@@ -1130,14 +1099,9 @@ int cppmain(int argc, char **argv) {
   // allocate the target abi
   gABI = TargetABI::getTarget();
 
-  // Set predefined version identifiers.
-  registerPredefinedVersions();
-  dumpPredefinedVersions();
-
   if (global.params.targetTriple->isOSWindows()) {
     global.dll_ext = "dll";
-    global.lib_ext =
-        (global.params.targetTriple->isWindowsMSVCEnvironment() ? "lib" : "a");
+    global.lib_ext = (global.params.mscoff ? "lib" : "a");
   } else {
     global.dll_ext = "so";
     global.lib_ext = "a";
@@ -1147,6 +1111,11 @@ int cppmain(int argc, char **argv) {
   return mars_mainBody(files, libmodules);
 }
 
+void addDefaultVersionIdentifiers() {
+  registerPredefinedVersions();
+  dumpPredefinedVersions();
+}
+
 void codegenModules(Modules &modules) {
   // Generate one or more object/IR/bitcode files.
   if (global.params.obj && !modules.empty()) {
diff --git a/tests/codegen/inferred_outputname.d b/tests/codegen/inferred_outputname.d
new file mode 100644
index 0000000..ded24a4
--- /dev/null
+++ b/tests/codegen/inferred_outputname.d
@@ -0,0 +1,19 @@
+// Make sure the inferred output filename is based on the first (source or
+// object) file, and independent from its module declaration.
+
+// If it works on Windows, it will work on other platforms too, and it
+// simplifies things a bit.
+// REQUIRES: Windows
+
+// 1) 2 object files compiled separately:
+// RUN: %ldc -c %S/inputs/foo.d -of=%T/foo%obj
+// RUN: %ldc %s %T/foo%obj -vv | FileCheck %s
+// 2) singleObj build with external object file and 2 source files:
+// RUN: %ldc %T/foo%obj %s %S/inputs/attr_weak_input.d -vv | FileCheck %s
+
+// CHECK: Linking with:
+// CHECK-NEXT: '/OUT:inferred_outputname.exe'
+
+module modulename;
+
+void main() {}
diff --git a/tests/codegen/inputs/foo.d b/tests/codegen/inputs/foo.d
new file mode 100644
index 0000000..e425999
--- /dev/null
+++ b/tests/codegen/inputs/foo.d
@@ -0,0 +1 @@
+void bar() {}

-- 
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