[build] Link with lld on Windows when using Clang.

- Make the build deterministic

Bug: https://github.com/dart-lang/sdk/issues/55995
Change-Id: Ic800dd66f23bc402dfede09db3f67f01aa82d29d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373360
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2024-07-02 21:16:39 +00:00 committed by Commit Queue
parent 4c1e63a3c0
commit b82383953d
4 changed files with 63 additions and 4 deletions

View file

@ -257,7 +257,10 @@ if (is_win) {
"//build/config/win:winver",
]
if (is_clang) {
_native_compiler_configs += [ "//build/config/win:relative_paths" ]
_native_compiler_configs += [
"//build/config/win:relative_paths",
"//build/config/win:deterministic_builds",
]
}
}
if (is_posix) {

View file

@ -221,3 +221,31 @@ config("relative_paths") {
"-no-canonical-prefixes",
]
}
if (is_clang) {
build_timestamp =
exec_script("//tools/make_coff_timestamp.py", [], "trim string")
}
config("deterministic_builds") {
if (is_clang) {
# /Brepro lets the compiler not write the mtime field in the .obj output.
# link.exe /incremental relies on this field to work correctly, but lld
# never looks at this timestamp, so it's safe to pass this flag with
# lld and get more deterministic compiler output in return.
# In LTO builds, the compiler doesn't write .obj files containing mtimes,
# so /Brepro is ignored there.
cflags = [ "/Brepro" ]
# lld defaults to writing the current time in the pe/coff header.
# For build reproducibility, pass an explicit timestamp. See
# build/compute_build_timestamp.py for how the timestamp is chosen.
# (link.exe also writes the current time, but it doesn't have a flag to
# override that behavior.)
ldflags = [ "/TIMESTAMP:" + build_timestamp ]
# Use a fake fixed base directory for paths in the pdb to make the pdb
# output fully deterministic and independent of the build directory.
ldflags += [ "/PDBSourcePath:o:\fake\prefix" ]
}
}

View file

@ -140,9 +140,18 @@ template("msvc_toolchain") {
]
}
if (is_clang) {
prefix = rebase_path("$clang_base_path/bin", root_build_dir)
lib = "$prefix/lld-link.exe /lib"
link = "$prefix/lld-link.exe"
} else {
lib = "lib.exe"
link = "link.exe"
}
tool("alink") {
rspfile = "{{output}}.rsp"
command = "$python_path $tool_wrapper_path link-wrapper $env False lib.exe /nologo /ignore:4221 /OUT:{{output}} @$rspfile"
command = "$python_path $tool_wrapper_path link-wrapper $env False $lib /nologo /ignore:4221 /OUT:{{output}} @$rspfile"
description = "LIB {{output}}"
outputs = [
# Ignore {{output_extension}} and always use .lib, there's no reason to
@ -163,7 +172,7 @@ template("msvc_toolchain") {
# foo.dll.lib
rspfile = "${dllname}.rsp"
link_command = "$python_path $tool_wrapper_path link-wrapper $env False link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:${dllname}.pdb @$rspfile"
link_command = "$python_path $tool_wrapper_path link-wrapper $env False $link /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:${dllname}.pdb @$rspfile"
# TODO(brettw) support manifests
#manifest_command = "$python_path $tool_wrapper_path manifest-wrapper $env mt.exe -nologo -manifest $manifests -out:${dllname}.manifest"
@ -216,7 +225,7 @@ template("msvc_toolchain") {
rspfile = "$binary_output.rsp"
pdbfile = "$binary_output.pdb"
link_command = "$python_path $tool_wrapper_path link-wrapper $env False link.exe /nologo /OUT:$binary_output /PDB:$pdbfile @$rspfile"
link_command = "$python_path $tool_wrapper_path link-wrapper $env False $link /nologo /OUT:$binary_output /PDB:$pdbfile @$rspfile"
# TODO(brettw) support manifests
#manifest_command = "$python_path $tool_wrapper_path manifest-wrapper $env mt.exe -nologo -manifest $manifests -out:{{output}}.manifest"

View file

@ -0,0 +1,19 @@
# Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
import subprocess
import utils
import sys
def Main():
p = subprocess.Popen(['git', 'show', '--no-patch', '--format=%ct'],
shell=utils.IsWindows(),
cwd=utils.DART_DIR)
p.communicate()
return p.wait()
if __name__ == '__main__':
sys.exit(Main())