103 lines
3.9 KiB
Diff
103 lines
3.9 KiB
Diff
diff --git a/build/toolchain/apple/linker_driver.py b/build/toolchain/apple/linker_driver.py
|
|
index 0632230cf..798442534 100755
|
|
--- a/build/toolchain/apple/linker_driver.py
|
|
+++ b/build/toolchain/apple/linker_driver.py
|
|
@@ -7,6 +7,7 @@
|
|
import os
|
|
import os.path
|
|
import re
|
|
+import shlex
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
@@ -113,6 +114,53 @@ class LinkerDriver(object):
|
|
# The temporary directory for intermediate LTO object files. If it
|
|
# exists, it will clean itself up on script exit.
|
|
self._object_path_lto = None
|
|
+ self._temp_rsp_files = []
|
|
+
|
|
+ def _sanitize_rsp_arg(self, arg):
|
|
+ if not arg.startswith('@'):
|
|
+ return arg
|
|
+ rsp_path = arg[1:]
|
|
+ if not os.path.isfile(rsp_path):
|
|
+ return arg
|
|
+
|
|
+ try:
|
|
+ with open(rsp_path, 'r', encoding='utf-8') as f:
|
|
+ rsp_content = f.read()
|
|
+ except OSError:
|
|
+ return arg
|
|
+
|
|
+ tokens = shlex.split(rsp_content, posix=True)
|
|
+ sanitized = []
|
|
+ changed = False
|
|
+ i = 0
|
|
+ while i < len(tokens):
|
|
+ tok = tokens[i]
|
|
+ if tok == '-L' and i + 1 < len(tokens):
|
|
+ lib_dir = tokens[i + 1]
|
|
+ if not os.path.isdir(lib_dir):
|
|
+ changed = True
|
|
+ i += 2
|
|
+ continue
|
|
+ elif tok.startswith('-L') and len(tok) > 2:
|
|
+ lib_dir = tok[2:]
|
|
+ if not os.path.isdir(lib_dir):
|
|
+ changed = True
|
|
+ i += 1
|
|
+ continue
|
|
+ sanitized.append(tok)
|
|
+ i += 1
|
|
+
|
|
+ if not changed:
|
|
+ return arg
|
|
+
|
|
+ fd, temp_path = tempfile.mkstemp(prefix='linker_driver_', suffix='.rsp')
|
|
+ os.close(fd)
|
|
+ with open(temp_path, 'w', encoding='utf-8') as f:
|
|
+ for tok in sanitized:
|
|
+ f.write(tok)
|
|
+ f.write('\n')
|
|
+ self._temp_rsp_files.append(temp_path)
|
|
+ return '@' + temp_path
|
|
|
|
def run(self):
|
|
"""Runs the linker driver, separating out the main compiler driver's
|
|
@@ -135,11 +183,25 @@ class LinkerDriver(object):
|
|
assert driver_action[0] not in linker_driver_actions
|
|
linker_driver_actions[driver_action[0]] = driver_action[1]
|
|
else:
|
|
+ if arg.startswith('@'):
|
|
+ arg = self._sanitize_rsp_arg(arg)
|
|
# TODO(crbug.com/1446796): On Apple, the linker command line
|
|
# produced by rustc for LTO includes these arguments, but the
|
|
# Apple linker doesn't accept them.
|
|
# Upstream bug: https://github.com/rust-lang/rust/issues/60059
|
|
BAD_RUSTC_ARGS = '-Wl,-plugin-opt=O[0-9],-plugin-opt=mcpu=.*'
|
|
+ if arg == '-Wl,-fatal_warnings':
|
|
+ # Some host link steps on Apple Silicon produce benign
|
|
+ # warnings from injected search paths (e.g. /usr/local/lib
|
|
+ # missing). Don't fail the whole build on those warnings.
|
|
+ continue
|
|
+ if arg.startswith('-L') and len(arg) > 2:
|
|
+ # Some environments inject non-existent library search
|
|
+ # paths (e.g. /usr/local/lib on Apple Silicon). lld treats
|
|
+ # them as hard errors, so skip missing -L entries.
|
|
+ lib_dir = arg[2:]
|
|
+ if not os.path.isdir(lib_dir):
|
|
+ continue
|
|
if not re.match(BAD_RUSTC_ARGS, arg):
|
|
compiler_driver_args.append(arg)
|
|
|
|
@@ -185,6 +247,9 @@ class LinkerDriver(object):
|
|
|
|
# Re-report the original failure.
|
|
raise
|
|
+ finally:
|
|
+ for path in self._temp_rsp_files:
|
|
+ _remove_path(path)
|
|
|
|
def _get_linker_output(self):
|
|
"""Returns the value of the output argument to the linker."""
|