Bug 1489443 - Set GCC_USE_GNU_LD based on linker kind. r=froydnj
authorNick Alexander <nalexander@mozilla.com>
Wed, 17 Oct 2018 19:46:03 +0000
changeset 497550 63248a593eae0a14ffc33ab0057cf41d3ecb8018
parent 497549 eb2a83cba95aafab7713af2a444de144320b31e9
child 497551 0623ed3cb752851d5f96618b6a5f7c3048b49b60
push id9996
push userarchaeopteryx@coole-files.de
push dateThu, 18 Oct 2018 18:37:15 +0000
treeherdermozilla-beta@8efe26839243 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1489443
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1489443 - Set GCC_USE_GNU_LD based on linker kind. r=froydnj The desired outcome of this change is that we'll set -Wl,--version-script based on linker kind and not on the output of $LINKER -v. This is a cheap way to address a simple problem that has a complicated ideal solution. The underlying issue is that in some situations, when targeting Android, a macOS system ld is interrogated to determine if a cross-compiling linker "is GNU ld" and a particular linker feature is set in that situation. The macOS system ld doesn't pass the "is GNU ld" test, and the linker feature isn't set; that causes link failures, even though the actual linker has nothing to do with the system ld. The ideal solution is to test for linker capabilities dynamically. We do a lot of that in old-configure.in, and we don't do any of that in toolchain.configure. Rather than start testing in toolchain.configure, we hard-code: a cheap solution to the immediate problem. MinGW suffers somewhat from the opposite problem: the linker "is GNU ld" (compatible), but the linker checks don't happen at all. We hard-code for MinGW based on the C compiler instead. Differential Revision: https://phabricator.services.mozilla.com/D8471
build/autoconf/toolchain.m4
build/moz.configure/toolchain.configure
js/src/old-configure.in
old-configure.in
python/mozbuild/mozbuild/action/generate_symbols_file.py
security/generate_mapfile.py
--- a/build/autoconf/toolchain.m4
+++ b/build/autoconf/toolchain.m4
@@ -29,22 +29,16 @@ if test "$CC_TYPE" = "clang"; then
     GNU_CXX=1
     CLANG_CC=1
     CLANG_CXX=1
 fi
 if test "$CC_TYPE" = "clang-cl"; then
     CLANG_CL=1
 fi
 
-if test "$GNU_CC"; then
-    if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
-        GCC_USE_GNU_LD=1
-    fi
-fi
-
 AC_SUBST(CLANG_CXX)
 AC_SUBST(CLANG_CL)
 ])
 
 AC_DEFUN([MOZ_CROSS_COMPILER],
 [
 echo "cross compiling from $host to $target"
 
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1797,16 +1797,31 @@ def select_linker(linker, c_compiler, de
     return result
 
 
 set_config('LD_IS_BFD', depends(select_linker.KIND)
            (lambda x: x == 'bfd' or None))
 add_old_configure_assignment('LINKER_LDFLAGS', select_linker.LINKER_FLAG)
 
 
+# There's a wrinkle with MinGW: linker configuration is not enabled, so
+# `select_linker` is never invoked.  Hard-code around it.
+@depends(select_linker, target, c_compiler)
+def gcc_use_gnu_ld(select_linker, target, c_compiler):
+    if select_linker is not None:
+        return select_linker.KIND in ('bfd', 'gold', 'lld')
+    if target.kernel == 'WINNT' and c_compiler.type == 'clang':
+        return True
+    return None
+
+
+# GCC_USE_GNU_LD=1 means the linker is command line compatible with GNU ld.
+set_config('GCC_USE_GNU_LD', gcc_use_gnu_ld)
+add_old_configure_assignment('GCC_USE_GNU_LD', gcc_use_gnu_ld)
+
 # Assembler detection
 # ==============================================================
 
 js_option(env='AS', nargs=1, help='Path to the assembler')
 
 @depends(target, c_compiler)
 def as_info(target, c_compiler):
     if c_compiler.type in ('msvc', 'clang-cl'):
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -1765,18 +1765,16 @@ AC_SUBST(HOST_LDFLAGS)
 AC_SUBST_LIST(HOST_OPTIMIZE_FLAGS)
 AC_SUBST(HOST_AR)
 AC_SUBST(HOST_AR_FLAGS)
 AC_SUBST(HOST_RANLIB)
 AC_SUBST(HOST_BIN_SUFFIX)
 
 AC_SUBST(TARGET_XPCOM_ABI)
 
-AC_SUBST(GCC_USE_GNU_LD)
-
 AC_SUBST_LIST(DSO_CFLAGS)
 AC_SUBST_LIST(DSO_PIC_CFLAGS)
 AC_SUBST(DSO_LDOPTS)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(MOZ_LINKER)
 AC_SUBST(WIN32_CONSOLE_EXE_LDFLAGS)
--- a/old-configure.in
+++ b/old-configure.in
@@ -4207,17 +4207,16 @@ AC_SUBST(HOST_AR_FLAGS)
 AC_SUBST(HOST_RANLIB)
 AC_SUBST(HOST_BIN_SUFFIX)
 
 AC_SUBST(TARGET_XPCOM_ABI)
 AC_SUBST(HAVE_TOOLCHAIN_SUPPORT_MSSSE3)
 AC_SUBST(HAVE_TOOLCHAIN_SUPPORT_MSSE4_1)
 AC_SUBST(HAVE_X86_AVX2)
 AC_SUBST(HAVE_ALTIVEC)
-AC_SUBST(GCC_USE_GNU_LD)
 
 AC_SUBST_LIST(DSO_CFLAGS)
 AC_SUBST_LIST(DSO_PIC_CFLAGS)
 AC_SUBST(DSO_LDOPTS)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(NS_ENABLE_TSF)
--- a/python/mozbuild/mozbuild/action/generate_symbols_file.py
+++ b/python/mozbuild/mozbuild/action/generate_symbols_file.py
@@ -66,17 +66,17 @@ def generate_symbols_file(output, *args)
         # The DATA variable is "simply" expanded by the preprocessor, to
         # nothing on non-Windows, such that we only get the symbol name on
         # those platforms, and to DATA on Windows, so that the "DATA" part
         # is, in fact, part of the symbol name as far as the symbols variable
         # is concerned.
         assert ext == '.def'
         output.write('LIBRARY %s\nEXPORTS\n  %s\n'
                      % (libname, '\n  '.join(symbols)))
-    elif buildconfig.substs['GCC_USE_GNU_LD']:
+    elif buildconfig.substs.get('GCC_USE_GNU_LD'):
         # A linker version script is generated for GNU LD that looks like the
         # following:
         # liblibrary.so {
         # global:
         #   symbol1;
         #   symbol2;
         #   ...
         # local:
--- a/security/generate_mapfile.py
+++ b/security/generate_mapfile.py
@@ -17,17 +17,18 @@
 # Mozilla's supports building on Linux for Windows using MinGW. MinGW
 # expects all lines containing ;+ removed and all ;- tokens removed.
 
 import buildconfig
 
 
 def main(output, input):
     is_darwin = buildconfig.substs['OS_ARCH'] == 'Darwin'
-    is_mingw = "WINNT" == buildconfig.substs['OS_ARCH'] and buildconfig.substs['GCC_USE_GNU_LD']
+    is_mingw = "WINNT" == buildconfig.substs['OS_ARCH'] and \
+        buildconfig.substs.get('GCC_USE_GNU_LD')
 
     with open(input, 'rb') as f:
         for line in f:
             line = line.rstrip()
             # On everything except MinGW, remove all lines containing ';-'
             if not is_mingw and ';-' in line:
                 continue
             # On OS X, remove all lines containing ';+'