From 8ae7f818d91ec53978ae7bb6eca0d6b40c45c6fb Mon Sep 17 00:00:00 2001 From: Erik Chen Date: Thu, 15 Aug 2019 18:47:52 +0000 Subject: [PATCH] Add a flag to zero the mtime in OSO fields for deterministic builds on macOS. This requires a sufficiently new version of ld64. I confirmed that the one that comes bundled with Xcode 10.12.1 is new enough. There's no harm in setting this for older versions of ld64. This is currently gated behind the gn arg mac_deterministic_build because lldb has a bug that causes it to fail to load object files when the binary is built deterministically. Bug: 330262 Change-Id: I9802420a46f487888f4768c01168dae1b8d88359 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1711105 Reviewed-by: Nico Weber Commit-Queue: Erik Chen Auto-Submit: Erik Chen Cr-Original-Commit-Position: refs/heads/master@{#687360} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 7dc7c87cff652ab9a63f83029682c488e3ba515d --- toolchain/mac/BUILD.gn | 10 ++++++++++ toolchain/mac/linker_driver.py | 14 +++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/toolchain/mac/BUILD.gn b/toolchain/mac/BUILD.gn index c83b83a7d..c58a13cb1 100644 --- a/toolchain/mac/BUILD.gn +++ b/toolchain/mac/BUILD.gn @@ -27,6 +27,12 @@ declare_args() { # tools as they can cause lots of I/O contention when invoking ninja with a # large number of parallel jobs (e.g. when using distributed build like goma). bundle_pool_depth = -1 + + # This makes the linker set timestamps in Mach-O files to 0. This isn't + # enabled by default because this breaks Xcode's lldb. This has been fixed in + # https://reviews.llvm.org/rL368199 but that has not yet made it into a public + # lldb release. + mac_deterministic_build = false } if (current_toolchain == default_toolchain) { @@ -150,6 +156,10 @@ template("mac_toolchain") { _strippath = "$mac_bin_path" + "strip" linker_driver += " -Wcrl,strippath," + _strippath + if (mac_deterministic_build) { + linker_driver += " --deterministic" + } + # On iOS, the final applications are assembled using lipo (to support fat # builds). The correct flags are passed to the linker_driver.py script # directly during the lipo call. diff --git a/toolchain/mac/linker_driver.py b/toolchain/mac/linker_driver.py index 7353702a2..e51705058 100755 --- a/toolchain/mac/linker_driver.py +++ b/toolchain/mac/linker_driver.py @@ -15,6 +15,10 @@ import sys DSYMUTIL_INVOKE = ['xcrun', 'dsymutil'] STRIP_INVOKE = ['xcrun', 'strip'] +# Setting this flag will emit a deterministic binary by stripping dates from the +# N_OSO field. +DETERMINISTIC_FLAG = '--deterministic' + # The linker_driver.py is responsible for forwarding a linker invocation to # the compiler driver, while processing special arguments itself. # @@ -69,20 +73,28 @@ def Main(args): # the arguments being passed to the compiler driver. linker_driver_actions = {} compiler_driver_args = [] + deterministic = False for arg in args[1:]: if arg.startswith(_LINKER_DRIVER_ARG_PREFIX): # Convert driver actions into a map of name => lambda to invoke. driver_action = ProcessLinkerDriverArg(arg) assert driver_action[0] not in linker_driver_actions linker_driver_actions[driver_action[0]] = driver_action[1] + elif arg == DETERMINISTIC_FLAG: + deterministic = True else: compiler_driver_args.append(arg) linker_driver_outputs = [_FindLinkerOutput(compiler_driver_args)] try: + # Zero the mtime in OSO fields for deterministic builds. + # https://crbug.com/330262. + env = os.environ.copy() + if deterministic: + env['ZERO_AR_DATE'] = '1' # Run the linker by invoking the compiler driver. - subprocess.check_call(compiler_driver_args) + subprocess.check_call(compiler_driver_args, env=env) # Run the linker driver actions, in the order specified by the actions list. for action in _LINKER_DRIVER_ACTIONS: