[lld] r323164 - [COFF] don't replace import library if contents are unchanged

Bob Haarman via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 22 16:36:42 PST 2018


Author: inglorion
Date: Mon Jan 22 16:36:42 2018
New Revision: 323164

URL: http://llvm.org/viewvc/llvm-project?rev=323164&view=rev
Log:
[COFF] don't replace import library if contents are unchanged

Summary:
This detects when an import library is about to be overwritten with a
newly built one with the same contents, and keeps the old library
instead. The use case for this is to avoid needlessly rebuilding
targets that depend on the import library in build systems that rely
on timestamps to determine whether a target requires rebuilding.

This feature was requested in PR35917.

Reviewers: rnk, ruiu, zturner, pcc

Reviewed By: ruiu

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D42326

Added:
    lld/trunk/test/COFF/unchanged-importlib.test
Modified:
    lld/trunk/COFF/Driver.cpp

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=323164&r1=323163&r2=323164&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Mon Jan 22 16:36:42 2018
@@ -539,10 +539,39 @@ static void createImportLibrary(bool AsL
     Exports.push_back(E2);
   }
 
-  auto E = writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports,
-                              Config->Machine, false, Config->MinGW);
-  handleAllErrors(std::move(E),
-                  [&](ErrorInfoBase &EIB) { error(EIB.message()); });
+  auto HandleError = [](Error &&E) {
+    handleAllErrors(std::move(E),
+                    [](ErrorInfoBase &EIB) { error(EIB.message()); });
+  };
+  std::string LibName = getImportName(AsLib);
+  std::string Path = getImplibPath();
+
+  // If the import library already exists, replace it only if the contents
+  // have changed.
+  ErrorOr<std::unique_ptr<MemoryBuffer>> OldBuf = MemoryBuffer::getFile(Path);
+  if (!OldBuf) {
+    HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine,
+                                   false, Config->MinGW));
+    return;
+  }
+
+  SmallString<128> TmpName;
+  if (std::error_code EC =
+          sys::fs::createUniqueFile(Path + ".tmp-%%%%%%%%.lib", TmpName))
+    fatal("cannot create temporary file for import library " + Path + ": " +
+          EC.message());
+
+  if (Error E = writeImportLibrary(LibName, TmpName, Exports, Config->Machine,
+                                   false, Config->MinGW)) {
+    HandleError(std::move(E));
+    return;
+  }
+
+  std::unique_ptr<MemoryBuffer> NewBuf = check(MemoryBuffer::getFile(TmpName));
+  if ((*OldBuf)->getBuffer() != NewBuf->getBuffer()) {
+    OldBuf->reset();
+    HandleError(errorCodeToError(sys::fs::rename(TmpName, Path)));
+  }
 }
 
 static void parseModuleDefs(StringRef Path) {
@@ -640,8 +669,8 @@ filterBitcodeFiles(StringRef Path, std::
   log("Creating a temporary archive for " + Path + " to remove bitcode files");
 
   SmallString<128> S;
-  if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path),
-                                             ".lib", S))
+  if (std::error_code EC = sys::fs::createTemporaryFile(
+          "lld-" + sys::path::stem(Path), ".lib", S))
     fatal("cannot create a temporary file: " + EC.message());
   std::string Temp = S.str();
   TemporaryFiles.push_back(Temp);

Added: lld/trunk/test/COFF/unchanged-importlib.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/unchanged-importlib.test?rev=323164&view=auto
==============================================================================
--- lld/trunk/test/COFF/unchanged-importlib.test (added)
+++ lld/trunk/test/COFF/unchanged-importlib.test Mon Jan 22 16:36:42 2018
@@ -0,0 +1,7 @@
+# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
+# RUN: lld-link -out:%t.dll -dll %t.obj
+# RUN: touch -t 198002011200.00 %t.lib
+# RUN: lld-link -out:%t.dll -dll %t.obj
+# RUN: ls -l %t.lib | FileCheck --check-prefix=CHECK %s
+
+# CHECK: Feb 1 1980




More information about the llvm-commits mailing list