[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