[lld] r207727 - [PECOFF] Add a test for lib.exe subcommand.

Rui Ueyama ruiu at google.com
Wed Apr 30 17:06:56 PDT 2014


Author: ruiu
Date: Wed Apr 30 19:06:56 2014
New Revision: 207727

URL: http://llvm.org/viewvc/llvm-project?rev=207727&view=rev
Log:
[PECOFF] Add a test for lib.exe subcommand.

Previously the input file for the lib.exe command would be removed
as soon as the command exits, so we couldn't write a test to check
the file contents are correct.

This patch adds /lldmoduledeffile: option to retain a copy of the
temporary file at the given file path, so that you can see the file
if you want.

Added:
    lld/trunk/test/pecoff/exportlib2.test
Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/Driver/WinLinkOptions.td
    lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=207727&r1=207726&r2=207727&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Wed Apr 30 19:06:56 2014
@@ -272,6 +272,13 @@ public:
   void setLibraryGroup(Group *group) { _libraryGroup = group; }
   Group *getLibraryGroup() const { return _libraryGroup; }
 
+  void setModuleDefinitionFile(const std::string val) {
+    _moduleDefinitionFile = val;
+  }
+  std::string getModuleDefinitionFile() const {
+    return _moduleDefinitionFile;
+  }
+
   std::recursive_mutex &getMutex() { return _mutex; }
 
 protected:
@@ -369,6 +376,10 @@ private:
 
   // The PECOFFGroup that contains all the .lib files.
   Group *_libraryGroup;
+
+  // Name of the temporary file for lib.exe subcommand. For debugging
+  // only.
+  std::string _moduleDefinitionFile;
 };
 
 } // end namespace lld

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=207727&r1=207726&r2=207727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Wed Apr 30 19:06:56 2014
@@ -1173,6 +1173,10 @@ bool WinLinkDriver::parse(int argc, cons
       inputFiles.push_back(ctx.allocate(inputArg->getValue()));
       break;
 
+    case OPT_lldmoduledeffile:
+      ctx.setModuleDefinitionFile(inputArg->getValue());
+      break;
+
 #define DEFINE_BOOLEAN_FLAG(name, setter)       \
     case OPT_##name:                            \
       ctx.setter(true);                         \

Modified: lld/trunk/lib/Driver/WinLinkOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkOptions.td?rev=207727&r1=207726&r2=207727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkOptions.td (original)
+++ lld/trunk/lib/Driver/WinLinkOptions.td Wed Apr 30 19:06:56 2014
@@ -83,6 +83,9 @@ def help_q : Flag<["/?", "-?"], "">, Ali
 
 def DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>;
 
+// Flag for debug
+def lldmoduledeffile : Joined<["/", "-"], "lldmoduledeffile:">;
+
 //==============================================================================
 // The flags below do nothing. They are defined only for link.exe compatibility.
 //==============================================================================

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp?rev=207727&r1=207726&r2=207727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp Wed Apr 30 19:06:56 2014
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lld/ReaderWriter/PECOFFLinkingContext.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
@@ -22,16 +23,9 @@ namespace pecoff {
 
 /// Creates a .def file containing the list of exported symbols.
 static std::string
-createModuleDefinitionFile(const PECOFFLinkingContext &ctx,
-                           llvm::FileRemover &fileRemover) {
-  SmallString<128> defFile;
-  int fd;
-  if (llvm::sys::fs::createTemporaryFile("tmp", "def", fd, defFile)) {
-    llvm::errs() << "Failed to create temporary file\n";
-    return "";
-  }
-
-  llvm::raw_fd_ostream os(fd, /*shouldClose*/ true);
+createModuleDefinitionFile(const PECOFFLinkingContext &ctx) {
+  std::string ret;
+  llvm::raw_string_ostream os(ret);
   os << "LIBRARY \"" << llvm::sys::path::filename(ctx.outputPath()) << "\"\n"
      << "EXPORTS\n";
 
@@ -43,21 +37,43 @@ createModuleDefinitionFile(const PECOFFL
       os << " DATA";
     os << "\n";
   }
-  return defFile.str();
+  os.flush();
+  return ret;
+}
+
+static std::string writeToTempFile(StringRef contents) {
+  SmallString<128> path;
+  int fd;
+  if (llvm::sys::fs::createTemporaryFile("tmp", "def", fd, path)) {
+    llvm::errs() << "Failed to create temporary file\n";
+    return "";
+  }
+  llvm::raw_fd_ostream os(fd, /*shouldClose*/ true);
+  os << contents;
+  return path.str();
+}
+
+static void writeTo(StringRef path, StringRef contents) {
+  int fd;
+  if (llvm::sys::fs::openFileForWrite(path, fd, llvm::sys::fs::F_Text)) {
+    llvm::errs() << "Failed to open " << path << "\n";
+    return;
+  }
+  llvm::raw_fd_ostream os(fd, /*shouldClose*/ true);
+  os << contents;
 }
 
 /// Creates a .def file and runs lib.exe on it to create an import library.
 void writeImportLibrary(const PECOFFLinkingContext &ctx) {
   std::string program = "lib.exe";
   std::string programPath = llvm::sys::FindProgramByName(program);
-  if (programPath.empty()) {
-    llvm::errs() << "Unable to find " << program << " in PATH\n";
-    return;
-  }
 
-  llvm::FileRemover tmpFile;
+  std::string fileContents = createModuleDefinitionFile(ctx);
+  std::string defPath = writeToTempFile(fileContents);
+  llvm::FileRemover tmpFile(defPath);
+
   std::string defArg = "/def:";
-  defArg.append(createModuleDefinitionFile(ctx, tmpFile));
+  defArg.append(defPath);
   std::string outputArg = "/out:";
   outputArg.append(ctx.getOutputImportLibraryPath());
 
@@ -68,8 +84,17 @@ void writeImportLibrary(const PECOFFLink
   args.push_back(defArg.c_str());
   args.push_back(outputArg.c_str());
   args.push_back(nullptr);
-  if (llvm::sys::ExecuteAndWait(programPath.c_str(), &args[0]) != 0)
+
+  if (programPath.empty()) {
+    llvm::errs() << "Unable to find " << program << " in PATH\n";
+  } else if (llvm::sys::ExecuteAndWait(programPath.c_str(), &args[0]) != 0) {
     llvm::errs() << program << " failed\n";
+  }
+
+  // If /lldmoduledeffile:<filename> is given, make a copy of the
+  // temporary module definition file. This feature is for unit tests.
+  if (!ctx.getModuleDefinitionFile().empty())
+    writeTo(ctx.getModuleDefinitionFile(), fileContents);
 }
 
 } // end namespace pecoff

Added: lld/trunk/test/pecoff/exportlib2.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/exportlib2.test?rev=207727&view=auto
==============================================================================
--- lld/trunk/test/pecoff/exportlib2.test (added)
+++ lld/trunk/test/pecoff/exportlib2.test Wed Apr 30 19:06:56 2014
@@ -0,0 +1,10 @@
+# RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj
+#
+# RUN: lld -flavor link /out:%t.dll /dll /entry:init \
+# RUN:   /export:exportfn1 /export:exportfn2 /lldmoduledeffile:%t.def -- %t.obj
+# RUN: FileCheck %s < %t.def
+
+CHECK: LIBRARY "exportlib2.test.tmp.dll"
+CHECK: EXPORTS
+CHECK:   exportfn1 @1
+CHECK:   exportfn2 @2





More information about the llvm-commits mailing list