-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLD] [COFF] Pick timestamps from the SOURCE_DATE_EPOCH variable #81326
Conversation
The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time.
@llvm/pr-subscribers-lld @llvm/pr-subscribers-platform-windows Author: Martin Storsjö (mstorsjo) ChangesThe SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time. Full diff: https://github.com/llvm/llvm-project/pull/81326.diff 2 Files Affected:
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index e0afb6b18805b2..22ee2f133be98a 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1825,7 +1825,15 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
}
} else {
config->repro = false;
- config->timestamp = time(nullptr);
+ if (std::optional<std::string> epoch =
+ Process::GetEnv("SOURCE_DATE_EPOCH")) {
+ StringRef value(*epoch);
+ if (value.getAsInteger(0, config->timestamp))
+ fatal(Twine("invalid SOURCE_DATE_EPOCH timestamp: ") + value +
+ ". Expected 32-bit integer");
+ } else {
+ config->timestamp = time(nullptr);
+ }
}
// Handle /alternatename
diff --git a/lld/test/COFF/timestamp.test b/lld/test/COFF/timestamp.test
index fbdc5788a33a55..f94eeee8793f01 100644
--- a/lld/test/COFF/timestamp.test
+++ b/lld/test/COFF/timestamp.test
@@ -3,9 +3,11 @@ RUN: yaml2obj %p/Inputs/generic.yaml -o %t.obj
RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.1.exe
RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.2.exe
RUN: lld-link %t.obj /debug /timestamp:0 /entry:main /nodefaultlib /out:%t.3.exe
+RUN: env SOURCE_DATE_EPOCH=0 lld-link %t.obj /debug /entry:main /nodefaultlib /out:%t.4.exe
RUN: llvm-readobj --file-headers --coff-debug-directory %t.1.exe | FileCheck %s --check-prefix=HASH
RUN: llvm-readobj --file-headers --coff-debug-directory %t.2.exe | FileCheck %s --check-prefix=HASH
RUN: llvm-readobj --file-headers --coff-debug-directory %t.3.exe | FileCheck %s --check-prefix=ZERO
+RUN: llvm-readobj --file-headers --coff-debug-directory %t.4.exe | FileCheck %s --check-prefix=ZERO
HASH: ImageFileHeader {
HASH: TimeDateStamp: [[STAMP:.*]]
|
@@ -3,9 +3,11 @@ RUN: yaml2obj %p/Inputs/generic.yaml -o %t.obj | |||
RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.1.exe | |||
RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.2.exe | |||
RUN: lld-link %t.obj /debug /timestamp:0 /entry:main /nodefaultlib /out:%t.3.exe | |||
RUN: env SOURCE_DATE_EPOCH=0 lld-link %t.obj /debug /entry:main /nodefaultlib /out:%t.4.exe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be useful to test another value like clang/test/Preprocessor/SOURCE_DATE_EPOCH.c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I added more tests for more interesting cases.
What do you think of backporting this to 18.x? It’s not a bug fix per se, but a pretty safe improvement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM for a backport to improve reproducibility!
There’s not much info online about this. Do you know where it was first introduced? |
Ah nvm found it: https://reproducible-builds.org/docs/source-date-epoch/ |
…m#81326) The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time. See https://reproducible-builds.org/docs/source-date-epoch/ for reference on the use of this variable. (cherry picked from commit 0df8aed)
Does this deserve an update of the release notes for 18.0? |
Good point - yeah I think it does; I can make a separate PR to update the notes on the branch. |
The release notes for non-ELF ports are a barebone. @mstorsjo Do you want to find all interesting commits using You may create a feature request with the base branch set to release/18.x and then add the |
I did something similar already - filling in the stuff which is already there - but I only looked at the commits that I have been involved in myself, that I'm more familiar with. But I guess it would be useful to have a look through all of them - it's just a little bit more work. I'll see if I can get to it in the next few days. |
…m#81326) The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time. See https://reproducible-builds.org/docs/source-date-epoch/ for reference on the use of this variable. (cherry picked from commit 0df8aed)
…m#81326) The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time. See https://reproducible-builds.org/docs/source-date-epoch/ for reference on the use of this variable. (cherry picked from commit 0df8aed)
FYI: https://lab.llvm.org/buildbot/#/builders/178/builds/6797/steps/7/logs/FAIL__lld__timestamp_test Only happens on the 32 bit bot. |
Oops, sorry about that, and sorry for not noticing the buildbot mail earlier. It looks like the code itself is right, but Although, https://learn.microsoft.com/en-us/windows/win32/debug/pe-format doesn't seem to say anything explicitly about the signedness of this field either, but treating it as an unsigned seems reasonable. It does say that the value I guess the simplest way forward is to test with |
…m#81326) The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time. See https://reproducible-builds.org/docs/source-date-epoch/ for reference on the use of this variable. (cherry picked from commit 0df8aed)
…m#81326) The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time. See https://reproducible-builds.org/docs/source-date-epoch/ for reference on the use of this variable. (cherry picked from commit 0df8aed)
…m#81326) The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build. When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time. See https://reproducible-builds.org/docs/source-date-epoch/ for reference on the use of this variable. (cherry picked from commit 0df8aed)
lld from llvm 18 respects it. We are doing our own PE cleaning for now, but this could eventually take over (once `debian:testing` switches to 18 and possibly `ld` also implements it.) https://releases.llvm.org/18.1.0/tools/lld/docs/ReleaseNotes.html#coff-improvements llvm/llvm-project#81326
lld from llvm 18 respects it. We are doing our own PE cleaning for now, but this could eventually take over (once `debian:testing` switches to 18 and possibly `ld` also implements it.) https://releases.llvm.org/18.1.0/tools/lld/docs/ReleaseNotes.html#coff-improvements llvm/llvm-project#81326
The SOURCE_DATE_EPOCH environment variable can be set in order to get reproducible build.
When linking PE/COFF modules with LLD, the timestamp field is set to the current time, unless either the /timestamp: or /Brepro option is set. If neither of them is set, check the SOURCE_DATE_EPOCH variable, before resorting to using the actual current date and time.