forked from mirrors/gecko-dev
Bug 1802228 - Select a host linker in the same manner we do for the target linker. r=firefox-build-system-reviewers,ahochheiden
Differential Revision: https://phabricator.services.mozilla.com/D162912
This commit is contained in:
parent
29ab6a0f40
commit
b2cc8ec2c0
3 changed files with 215 additions and 171 deletions
|
|
@ -1545,192 +1545,234 @@ def enable_linker(linker):
|
||||||
return linker
|
return linker
|
||||||
|
|
||||||
|
|
||||||
@depends(
|
@template
|
||||||
"--enable-linker",
|
def select_linker_tmpl(host_or_target):
|
||||||
c_compiler,
|
if host_or_target is target:
|
||||||
developer_options,
|
deps = depends(
|
||||||
extra_toolchain_flags,
|
"--enable-linker",
|
||||||
target,
|
c_compiler,
|
||||||
when=is_linker_option_enabled,
|
developer_options,
|
||||||
)
|
extra_toolchain_flags,
|
||||||
@checking("for linker", lambda x: x.KIND)
|
target,
|
||||||
@imports("os")
|
when=is_linker_option_enabled,
|
||||||
@imports("shutil")
|
|
||||||
def select_linker(linker, c_compiler, developer_options, toolchain_flags, target):
|
|
||||||
|
|
||||||
if linker:
|
|
||||||
linker = linker[0]
|
|
||||||
else:
|
|
||||||
linker = None
|
|
||||||
|
|
||||||
def is_valid_linker(linker):
|
|
||||||
if target.kernel == "Darwin":
|
|
||||||
valid_linkers = ("ld64", "lld")
|
|
||||||
else:
|
|
||||||
valid_linkers = ("bfd", "gold", "lld", "mold")
|
|
||||||
if linker in valid_linkers:
|
|
||||||
return True
|
|
||||||
if "lld" in valid_linkers and linker.startswith("lld-"):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
if linker and not is_valid_linker(linker):
|
|
||||||
# Check that we are trying to use a supported linker
|
|
||||||
die("Unsupported linker " + linker)
|
|
||||||
|
|
||||||
# Check the kind of linker
|
|
||||||
version_check = ["-Wl,--version"]
|
|
||||||
cmd_base = c_compiler.wrapper + [c_compiler.compiler] + c_compiler.flags
|
|
||||||
|
|
||||||
def try_linker(linker):
|
|
||||||
# Generate the compiler flag
|
|
||||||
if linker == "ld64":
|
|
||||||
linker_flag = ["-fuse-ld=ld"]
|
|
||||||
elif linker:
|
|
||||||
linker_flag = ["-fuse-ld=" + linker]
|
|
||||||
else:
|
|
||||||
linker_flag = []
|
|
||||||
cmd = cmd_base + linker_flag + version_check
|
|
||||||
if toolchain_flags:
|
|
||||||
cmd += toolchain_flags
|
|
||||||
|
|
||||||
# ld64 doesn't have anything to print out a version. It does print out
|
|
||||||
# "ld64: For information on command line options please use 'man ld'."
|
|
||||||
# but that would require doing two attempts, one with --version, that
|
|
||||||
# would fail, and another with --help.
|
|
||||||
# Instead, abuse its LD_PRINT_OPTIONS feature to detect a message
|
|
||||||
# specific to it on stderr when it fails to process --version.
|
|
||||||
env = dict(os.environ)
|
|
||||||
env["LD_PRINT_OPTIONS"] = "1"
|
|
||||||
# Some locales might not print out the strings we are looking for, so
|
|
||||||
# ensure consistent output.
|
|
||||||
env["LC_ALL"] = "C"
|
|
||||||
retcode, stdout, stderr = get_cmd_output(*cmd, env=env)
|
|
||||||
if retcode == 1 and "Logging ld64 options" in stderr:
|
|
||||||
kind = "ld64"
|
|
||||||
|
|
||||||
elif retcode != 0:
|
|
||||||
return None
|
|
||||||
|
|
||||||
elif "mold" in stdout:
|
|
||||||
kind = "mold"
|
|
||||||
|
|
||||||
elif "GNU ld" in stdout:
|
|
||||||
# We are using the normal linker
|
|
||||||
kind = "bfd"
|
|
||||||
|
|
||||||
elif "GNU gold" in stdout:
|
|
||||||
kind = "gold"
|
|
||||||
|
|
||||||
elif "LLD" in stdout:
|
|
||||||
kind = "lld"
|
|
||||||
|
|
||||||
else:
|
|
||||||
kind = "unknown"
|
|
||||||
|
|
||||||
if kind == "unknown" or is_valid_linker(kind):
|
|
||||||
return namespace(
|
|
||||||
KIND=kind,
|
|
||||||
LINKER_FLAG=linker_flag,
|
|
||||||
)
|
|
||||||
|
|
||||||
result = try_linker(linker)
|
|
||||||
if result is None and linker:
|
|
||||||
die("Could not use {} as linker".format(linker))
|
|
||||||
|
|
||||||
if (
|
|
||||||
linker is None
|
|
||||||
and target.kernel == "Darwin"
|
|
||||||
and c_compiler.type == "clang"
|
|
||||||
and (
|
|
||||||
(developer_options and c_compiler.version >= "13.0")
|
|
||||||
or c_compiler.version >= "15.0"
|
|
||||||
)
|
)
|
||||||
):
|
host_or_target_str = "target"
|
||||||
result = try_linker("lld")
|
else:
|
||||||
elif (
|
deps = depends(
|
||||||
linker is None
|
dependable(None),
|
||||||
and developer_options
|
host_c_compiler,
|
||||||
and (result is None or result.KIND in ("bfd", "gold"))
|
developer_options,
|
||||||
):
|
dependable(None),
|
||||||
# try and use lld if available.
|
host,
|
||||||
tried = try_linker("lld")
|
)
|
||||||
if (result is None or result.KIND != "gold") and (
|
host_or_target_str = "host"
|
||||||
tried is None or tried.KIND != "lld"
|
|
||||||
|
@deps
|
||||||
|
@checking(f"for {host_or_target_str} linker", lambda x: x.KIND)
|
||||||
|
@imports("os")
|
||||||
|
@imports("shutil")
|
||||||
|
def select_linker(linker, c_compiler, developer_options, toolchain_flags, target):
|
||||||
|
|
||||||
|
if linker:
|
||||||
|
linker = linker[0]
|
||||||
|
else:
|
||||||
|
linker = None
|
||||||
|
|
||||||
|
def is_valid_linker(linker):
|
||||||
|
if target.kernel == "Darwin":
|
||||||
|
valid_linkers = ("ld64", "lld")
|
||||||
|
else:
|
||||||
|
valid_linkers = ("bfd", "gold", "lld", "mold")
|
||||||
|
if linker in valid_linkers:
|
||||||
|
return True
|
||||||
|
if "lld" in valid_linkers and linker.startswith("lld-"):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
if linker and not is_valid_linker(linker):
|
||||||
|
# Check that we are trying to use a supported linker
|
||||||
|
die("Unsupported linker " + linker)
|
||||||
|
|
||||||
|
# Check the kind of linker
|
||||||
|
version_check = ["-Wl,--version"]
|
||||||
|
cmd_base = c_compiler.wrapper + [c_compiler.compiler] + c_compiler.flags
|
||||||
|
|
||||||
|
def try_linker(linker):
|
||||||
|
# Generate the compiler flag
|
||||||
|
if linker == "ld64":
|
||||||
|
linker_flag = ["-fuse-ld=ld"]
|
||||||
|
elif linker:
|
||||||
|
linker_flag = ["-fuse-ld=" + linker]
|
||||||
|
else:
|
||||||
|
linker_flag = []
|
||||||
|
cmd = cmd_base + linker_flag + version_check
|
||||||
|
if toolchain_flags:
|
||||||
|
cmd += toolchain_flags
|
||||||
|
|
||||||
|
# ld64 doesn't have anything to print out a version. It does print out
|
||||||
|
# "ld64: For information on command line options please use 'man ld'."
|
||||||
|
# but that would require doing two attempts, one with --version, that
|
||||||
|
# would fail, and another with --help.
|
||||||
|
# Instead, abuse its LD_PRINT_OPTIONS feature to detect a message
|
||||||
|
# specific to it on stderr when it fails to process --version.
|
||||||
|
env = dict(os.environ)
|
||||||
|
env["LD_PRINT_OPTIONS"] = "1"
|
||||||
|
# Some locales might not print out the strings we are looking for, so
|
||||||
|
# ensure consistent output.
|
||||||
|
env["LC_ALL"] = "C"
|
||||||
|
retcode, stdout, stderr = get_cmd_output(*cmd, env=env)
|
||||||
|
if retcode == 1 and "Logging ld64 options" in stderr:
|
||||||
|
kind = "ld64"
|
||||||
|
|
||||||
|
elif retcode != 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
elif "mold" in stdout:
|
||||||
|
kind = "mold"
|
||||||
|
|
||||||
|
elif "GNU ld" in stdout:
|
||||||
|
# We are using the normal linker
|
||||||
|
kind = "bfd"
|
||||||
|
|
||||||
|
elif "GNU gold" in stdout:
|
||||||
|
kind = "gold"
|
||||||
|
|
||||||
|
elif "LLD" in stdout:
|
||||||
|
kind = "lld"
|
||||||
|
|
||||||
|
else:
|
||||||
|
kind = "unknown"
|
||||||
|
|
||||||
|
if kind == "unknown" or is_valid_linker(kind):
|
||||||
|
return namespace(
|
||||||
|
KIND=kind,
|
||||||
|
LINKER_FLAG=linker_flag,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = try_linker(linker)
|
||||||
|
if result is None and linker:
|
||||||
|
die("Could not use {} as linker".format(linker))
|
||||||
|
|
||||||
|
if (
|
||||||
|
linker is None
|
||||||
|
and target.kernel == "Darwin"
|
||||||
|
and c_compiler.type == "clang"
|
||||||
|
and (
|
||||||
|
(developer_options and c_compiler.version >= "13.0")
|
||||||
|
or c_compiler.version >= "15.0"
|
||||||
|
)
|
||||||
):
|
):
|
||||||
tried = try_linker("gold")
|
result = try_linker("lld")
|
||||||
if tried is None or tried.KIND != "gold":
|
elif (
|
||||||
tried = None
|
linker is None
|
||||||
if tried:
|
and developer_options
|
||||||
result = tried
|
and (result is None or result.KIND in ("bfd", "gold"))
|
||||||
|
):
|
||||||
|
# try and use lld if available.
|
||||||
|
tried = try_linker("lld")
|
||||||
|
if (result is None or result.KIND != "gold") and (
|
||||||
|
tried is None or tried.KIND != "lld"
|
||||||
|
):
|
||||||
|
tried = try_linker("gold")
|
||||||
|
if tried is None or tried.KIND != "gold":
|
||||||
|
tried = None
|
||||||
|
if tried:
|
||||||
|
result = tried
|
||||||
|
|
||||||
if result is None:
|
if result is None:
|
||||||
die("Failed to find an adequate linker")
|
die("Failed to find an adequate linker")
|
||||||
|
|
||||||
# If an explicit linker was given, error out if what we found is different.
|
# If an explicit linker was given, error out if what we found is different.
|
||||||
if linker and not linker.startswith(result.KIND):
|
if linker and not linker.startswith(result.KIND):
|
||||||
die("Could not use {} as linker".format(linker))
|
die("Could not use {} as linker".format(linker))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
return select_linker
|
||||||
|
|
||||||
|
|
||||||
|
select_linker = select_linker_tmpl(target)
|
||||||
set_config("LINKER_KIND", select_linker.KIND)
|
set_config("LINKER_KIND", select_linker.KIND)
|
||||||
|
|
||||||
|
|
||||||
@depends_if(
|
@template
|
||||||
select_linker,
|
def linker_ldflags_tmpl(host_or_target):
|
||||||
target,
|
if host_or_target is target:
|
||||||
target_sysroot,
|
deps = depends_if(
|
||||||
target_multiarch_dir,
|
select_linker,
|
||||||
android_platform,
|
target,
|
||||||
c_compiler,
|
target_sysroot,
|
||||||
developer_options,
|
target_multiarch_dir,
|
||||||
)
|
android_platform,
|
||||||
@imports("os")
|
c_compiler,
|
||||||
def linker_ldflags(
|
developer_options,
|
||||||
linker,
|
)
|
||||||
target,
|
else:
|
||||||
sysroot,
|
deps = depends_if(
|
||||||
multiarch_dir,
|
select_linker_tmpl(host),
|
||||||
android_platform,
|
host,
|
||||||
c_compiler,
|
host_sysroot,
|
||||||
developer_options,
|
host_multiarch_dir,
|
||||||
):
|
dependable(None),
|
||||||
flags = list((linker and linker.LINKER_FLAG) or [])
|
host_c_compiler,
|
||||||
# rpath-link is irrelevant to wasm, see for more info https://github.com/emscripten-core/emscripten/issues/11076.
|
developer_options,
|
||||||
if sysroot.path and multiarch_dir and target.os != "WASI":
|
)
|
||||||
for d in ("lib", "usr/lib"):
|
|
||||||
multiarch_lib_dir = os.path.join(sysroot.path, d, multiarch_dir)
|
@deps
|
||||||
if os.path.exists(multiarch_lib_dir):
|
@imports("os")
|
||||||
# Non-Debian-patched binutils linkers (both BFD and gold) don't lookup
|
def linker_ldflags(
|
||||||
# in multi-arch directories.
|
linker,
|
||||||
flags.append("-Wl,-rpath-link,%s" % multiarch_lib_dir)
|
target,
|
||||||
# GCC also needs -L.
|
sysroot,
|
||||||
if c_compiler.type == "gcc":
|
multiarch_dir,
|
||||||
flags.append("-L%s" % multiarch_lib_dir)
|
android_platform,
|
||||||
if c_compiler.type == "gcc" and sysroot.bootstrapped and sysroot.stdcxx_version:
|
c_compiler,
|
||||||
flags.append(
|
developer_options,
|
||||||
"-L{}/usr/lib/gcc/{}/{}".format(
|
|
||||||
sysroot.path, multiarch_dir, sysroot.stdcxx_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if android_platform:
|
|
||||||
flags.append("-L{}/usr/lib".format(android_platform))
|
|
||||||
flags.append("-Wl,--rpath-link={}/usr/lib".format(android_platform))
|
|
||||||
flags.append("--sysroot")
|
|
||||||
flags.append(android_platform)
|
|
||||||
if (
|
|
||||||
developer_options
|
|
||||||
and linker
|
|
||||||
and linker.KIND == "lld"
|
|
||||||
and target.kernel != "WINNT"
|
|
||||||
):
|
):
|
||||||
flags.append("-Wl,-O0")
|
flags = list((linker and linker.LINKER_FLAG) or [])
|
||||||
return flags
|
# rpath-link is irrelevant to wasm, see for more info https://github.com/emscripten-core/emscripten/issues/11076.
|
||||||
|
if sysroot.path and multiarch_dir and target.os != "WASI":
|
||||||
|
for d in ("lib", "usr/lib"):
|
||||||
|
multiarch_lib_dir = os.path.join(sysroot.path, d, multiarch_dir)
|
||||||
|
if os.path.exists(multiarch_lib_dir):
|
||||||
|
# Non-Debian-patched binutils linkers (both BFD and gold) don't lookup
|
||||||
|
# in multi-arch directories.
|
||||||
|
flags.append("-Wl,-rpath-link,%s" % multiarch_lib_dir)
|
||||||
|
# GCC also needs -L.
|
||||||
|
if c_compiler.type == "gcc":
|
||||||
|
flags.append("-L%s" % multiarch_lib_dir)
|
||||||
|
if (
|
||||||
|
c_compiler.type == "gcc"
|
||||||
|
and sysroot.bootstrapped
|
||||||
|
and sysroot.stdcxx_version
|
||||||
|
):
|
||||||
|
flags.append(
|
||||||
|
"-L{}/usr/lib/gcc/{}/{}".format(
|
||||||
|
sysroot.path, multiarch_dir, sysroot.stdcxx_version
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if android_platform:
|
||||||
|
flags.append("-L{}/usr/lib".format(android_platform))
|
||||||
|
flags.append("-Wl,--rpath-link={}/usr/lib".format(android_platform))
|
||||||
|
flags.append("--sysroot")
|
||||||
|
flags.append(android_platform)
|
||||||
|
if (
|
||||||
|
developer_options
|
||||||
|
and linker
|
||||||
|
and linker.KIND == "lld"
|
||||||
|
and target.kernel != "WINNT"
|
||||||
|
):
|
||||||
|
flags.append("-Wl,-O0")
|
||||||
|
return flags
|
||||||
|
|
||||||
|
return linker_ldflags
|
||||||
|
|
||||||
|
|
||||||
|
linker_ldflags = linker_ldflags_tmpl(target)
|
||||||
add_old_configure_assignment("LINKER_LDFLAGS", linker_ldflags)
|
add_old_configure_assignment("LINKER_LDFLAGS", linker_ldflags)
|
||||||
|
|
||||||
|
add_old_configure_assignment("HOST_LINKER_LDFLAGS", linker_ldflags_tmpl(host))
|
||||||
|
|
||||||
|
|
||||||
# There's a wrinkle with MinGW: linker configuration is not enabled, so
|
# There's a wrinkle with MinGW: linker configuration is not enabled, so
|
||||||
# `select_linker` is never invoked. Hard-code around it.
|
# `select_linker` is never invoked. Hard-code around it.
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ USE_PTHREADS=
|
||||||
_PTHREAD_LDFLAGS=""
|
_PTHREAD_LDFLAGS=""
|
||||||
|
|
||||||
LDFLAGS="$LDFLAGS $LINKER_LDFLAGS"
|
LDFLAGS="$LDFLAGS $LINKER_LDFLAGS"
|
||||||
|
HOST_LDFLAGS="$HOST_LDFLAGS $HOST_LINKER_LDFLAGS"
|
||||||
|
|
||||||
if test -z "$JS_STANDALONE"; then
|
if test -z "$JS_STANDALONE"; then
|
||||||
autoconfmk=autoconf-js.mk
|
autoconfmk=autoconf-js.mk
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ MOZ_USE_PTHREADS=
|
||||||
_PTHREAD_LDFLAGS=""
|
_PTHREAD_LDFLAGS=""
|
||||||
|
|
||||||
LDFLAGS="$LDFLAGS $LINKER_LDFLAGS"
|
LDFLAGS="$LDFLAGS $LINKER_LDFLAGS"
|
||||||
|
HOST_LDFLAGS="$HOST_LDFLAGS $HOST_LINKER_LDFLAGS"
|
||||||
|
|
||||||
if test "$COMPILE_ENVIRONMENT"; then
|
if test "$COMPILE_ENVIRONMENT"; then
|
||||||
MOZ_ANDROID_NDK
|
MOZ_ANDROID_NDK
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue