summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2017-06-29 19:38:51 -0400
committerBen Gamari <ben@smart-cactus.org>2017-06-29 19:38:52 -0400
commit625143f473b58d770d2515b91c2566b52d35a4c3 (patch)
tree5da1910c86956cb4ae6ea8534d0867bfeae134e3
parent007f255644f885d445e47e291e50eb12b5ecd08d (diff)
downloadhaskell-625143f473b58d770d2515b91c2566b52d35a4c3.tar.gz
configure: Coerce gcc to use $LD instead of system default
The configure script will now try to coerce gcc to use the linker pointed to by $LD instead of the system default (typically bfd ld). Moreover, we now check for `ld.gold` and `ld.lld` before trying `ld`. The previous behavior can be reverted to by using the new --disable-ld-override flag. On my machine gold seems to trigger an apparent infelicity in constructor behavior, causing T5435_asm to fail. I've opened #13883 to record this issue and have accepted the questionable constructor ordering for the time being. Test Plan: Validate with `config_args='--enable-ld-override'` Reviewers: austin, hvr, simonmar Subscribers: duog, nh2, rwbarton, thomie, erikd, snowleopard GHC Trac Issues: #13541, #13810, #13883 Differential Revision: https://phabricator.haskell.org/D3449
-rw-r--r--aclocal.m4106
-rw-r--r--configure.ac9
-rw-r--r--distrib/configure.ac.in25
-rw-r--r--testsuite/tests/rts/all.T4
4 files changed, 82 insertions, 62 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index b94f70bada..677c0e77bc 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -590,7 +590,7 @@ AC_DEFUN([FP_SET_CFLAGS_C99],
# FPTOOLS_SET_C_LD_FLAGS
# ----------------------------------
-# Set the C, LD and CPP flags for a given platform
+# Set the C, LD and CPP flags for a given platform.
# $1 is the platform
# $2 is the name of the CC flags variable
# $3 is the name of the linker flags variable when linking with gcc
@@ -598,7 +598,6 @@ AC_DEFUN([FP_SET_CFLAGS_C99],
# $5 is the name of the CPP flags variable
AC_DEFUN([FPTOOLS_SET_C_LD_FLAGS],
[
- FIND_LD([$$1],[UseLd])
AC_MSG_CHECKING([Setting up $2, $3, $4 and $5])
case $$1 in
i386-*)
@@ -665,15 +664,6 @@ AC_DEFUN([FPTOOLS_SET_C_LD_FLAGS],
esac
- case $UseLd in
- *ld.gold)
- $3="$$3 -fuse-ld=gold"
- ;;
- *ld.bfd)
- $3="$$3 -fuse-ld=bfd"
- ;;
- esac
-
# If gcc knows about the stack protector, turn it off.
# Otherwise the stack-smash handler gets triggered.
echo 'int main(void) {return 0;}' > conftest.c
@@ -2015,41 +2005,6 @@ AC_DEFUN([FIND_LLVM_PROG],[
fi
])
-# FIND_LD
-# ---------
-# Find the version of `ld` to use. This is used in both in the top level
-# configure.ac and in distrib/configure.ac.in.
-#
-# $1 = the platform
-# $2 = the variable to set
-#
-AC_DEFUN([FIND_LD],[
- AC_CHECK_TARGET_TOOL([LD], [ld])
- case $1 in
- arm*linux* | \
- aarch64*linux* )
- # Arm and Aarch64 requires use of the binutils ld.gold linker.
- # This case should catch at least arm-unknown-linux-gnueabihf,
- # arm-linux-androideabi, arm64-unknown-linux and
- # aarch64-linux-android
- AC_CHECK_TARGET_TOOL([LD_GOLD], [ld.gold])
- if test "$LD_GOLD" != ""; then
- $2="$LD_GOLD"
- elif test `$LD --version | grep -c "GNU gold"` -gt 0; then
- AC_MSG_NOTICE([ld is ld.gold])
- $2="$LD"
- else
- AC_MSG_WARN([could not find ld.gold, falling back to $LD])
- $2="$LD"
- fi
- ;;
- *)
- $2="$LD"
- ;;
- esac
- CHECK_LD_COPY_BUG($1)
-])
-
# CHECK_LD_COPY_BUG()
# -------------------
# Check for binutils bug #16177 present in some versions of the bfd ld
@@ -2284,4 +2239,63 @@ AC_DEFUN([FP_BFD_SUPPORT], [
)
])
+
+# FP_CC_LINKER_FLAG_TRY()
+# --------------------
+# Try a particular linker to see whether we can use it. In particular, determine
+# whether we can convince gcc to use it via a -fuse-ld=... flag.
+#
+# $1 = the name of the linker to try
+# $2 = the variable to set with the appropriate GHC flag if the linker is
+# found to be usable
+AC_DEFUN([FP_CC_LINKER_FLAG_TRY], [
+ AC_MSG_CHECKING([whether C compiler supports -fuse-ld=$1])
+ echo 'int main(void) {return 0;}' > conftest.c
+ if $CC -o conftest.o -fuse-ld=$1 conftest.c > /dev/null 2>&1
+ then
+ $2="-fuse-ld=$1"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ rm -f conftest.c conftest.o
+])
+
+# FIND_LD
+# ---------
+# Find the version of `ld` to use and figure out how to get gcc to use it for
+# linking (if --enable-ld-override is enabled). This is used in both in the top
+# level configure.ac and in distrib/configure.ac.in.
+#
+# $1 = the platform
+# $2 = the variable to set with GHC options to configure gcc to use the chosen linker
+#
+AC_DEFUN([FIND_LD],[
+ AC_ARG_ENABLE(ld-override,
+ [AC_HELP_STRING([--disable-ld-override],
+ [Prevent GHC from overriding the default linker used by gcc. If ld-override is enabled GHC will try to tell gcc to use whichever linker is selected by the LD environment variable. [default=override enabled]])],
+ [],
+ [enable_ld_override=yes])
+
+ if test "x$enable_ld_override" = "xyes"; then
+ AC_CHECK_TARGET_TOOLS([LD], [ld.gold ld.lld ld])
+ UseLd=''
+
+ out=`$LD --version`
+ case $out in
+ "GNU ld"*) FP_CC_LINKER_FLAG_TRY(bfd, $2) ;;
+ "GNU gold"*) FP_CC_LINKER_FLAG_TRY(gold, $2) ;;
+ "LLD"*) FP_CC_LINKER_FLAG_TRY(lld, $2) ;;
+ *) AC_MSG_NOTICE([unknown linker version $out]) ;;
+ esac
+ if test "z$2" = "z"; then
+ AC_MSG_NOTICE([unable to convince '$CC' to use linker '$LD'])
+ fi
+ else
+ AC_CHECK_TARGET_TOOL([LD], [ld])
+ fi
+
+ CHECK_LD_COPY_BUG([$1])
+])
+
# LocalWords: fi
diff --git a/configure.ac b/configure.ac
index c0961cf8fc..92d37141ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -414,7 +414,6 @@ then
# are screwed up. Configure doesn't think they're ever equal and
# so never tried without the prefix.
AC_PATH_PROG([CC],[gcc], [clang])
- AC_PATH_PROG([LD],[ld], [lld])
AC_PATH_PROG([NM],[nm])
AC_PATH_PROG([AR],[ar])
AC_PATH_PROG([RANLIB],[ranlib])
@@ -530,9 +529,12 @@ FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2])
-dnl ** Which ld to use?
+dnl ** Choose a linker
dnl --------------------------------------------------------------
-FIND_LD([$target],[LdCmd])
+FIND_LD([$target],[GccUseLdOpt])
+CONF_GCC_LINKER_OPTS_STAGE1="$CONF_GCC_LINKER_OPTS_STAGE1 $GccUseLdOpt"
+CONF_GCC_LINKER_OPTS_STAGE2="$CONF_GCC_LINKER_OPTS_STAGE2 $GccUseLdOpt"
+LdCmd="$LD"
AC_SUBST([LdCmd])
dnl ** Which nm to use?
@@ -694,7 +696,6 @@ FP_PROG_LD_BUILD_ID
FP_PROG_LD_NO_COMPACT_UNWIND
FP_PROG_LD_FILELIST
-
FPTOOLS_SET_C_LD_FLAGS([target],[CFLAGS],[LDFLAGS],[IGNORE_LINKER_LD_FLAGS],[CPPFLAGS])
FPTOOLS_SET_C_LD_FLAGS([build],[CONF_CC_OPTS_STAGE0],[CONF_GCC_LINKER_OPTS_STAGE0],[CONF_LD_LINKER_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAGE1],[CONF_LD_LINKER_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
diff --git a/distrib/configure.ac.in b/distrib/configure.ac.in
index cea3c493e9..53c79e1a2d 100644
--- a/distrib/configure.ac.in
+++ b/distrib/configure.ac.in
@@ -84,23 +84,11 @@ FIND_LLVM_PROG([OPT], [opt], [$LlvmVersion])
OptCmd="$OPT"
AC_SUBST([OptCmd])
-dnl ** Which ld to use?
-dnl --------------------------------------------------------------
-FIND_LD([$target],[LdCmd])
-AC_SUBST([LdCmd])
-
FP_GCC_VERSION
FP_GCC_SUPPORTS_NO_PIE
AC_PROG_CPP
-FP_PROG_LD_IS_GNU
-FP_PROG_LD_BUILD_ID
-FP_PROG_LD_NO_COMPACT_UNWIND
-FP_PROG_LD_FILELIST
-
-#
dnl ** Check gcc version and flags we need to pass it **
-#
FP_GCC_EXTRA_FLAGS
FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS])
@@ -127,6 +115,19 @@ AC_SUBST(CONF_CPP_OPTS_STAGE0)
AC_SUBST(CONF_CPP_OPTS_STAGE1)
AC_SUBST(CONF_CPP_OPTS_STAGE2)
+dnl ** Which ld to use?
+dnl --------------------------------------------------------------
+FIND_LD([$target],[GccUseLdOpt])
+CONF_GCC_LINKER_OPTS_STAGE1="$CONF_GCC_LINKER_OPTS_STAGE1 $GccUseLdOpt"
+CONF_GCC_LINKER_OPTS_STAGE2="$CONF_GCC_LINKER_OPTS_STAGE2 $GccUseLdOpt"
+LdCmd="$LD"
+AC_SUBST([LdCmd])
+
+FP_PROG_LD_IS_GNU
+FP_PROG_LD_BUILD_ID
+FP_PROG_LD_NO_COMPACT_UNWIND
+FP_PROG_LD_FILELIST
+
dnl ** Set up the variables for the platform in the settings file.
dnl May need to use gcc to find platform details.
dnl --------------------------------------------------------------
diff --git a/testsuite/tests/rts/all.T b/testsuite/tests/rts/all.T
index f32a35be3e..e02f880d7c 100644
--- a/testsuite/tests/rts/all.T
+++ b/testsuite/tests/rts/all.T
@@ -169,6 +169,10 @@ def checkDynAsm(actual_file, normaliser):
actual = actual_str.split()
if actual == ['initArray1', 'initArray2', 'ctors1', 'ctors2', 'success']:
return 1
+ elif actual == ['initArray1', 'initArray2', 'ctors2', 'ctors1', 'success']:
+ # gold seems to produce this ordering; this is slightly odd but if it's
+ # wrong it's not our fault. See #13883.
+ return 1
elif actual == ['ctors1', 'ctors2', 'initArray1', 'initArray2', 'success']:
if_verbose(1, 'T5435_dyn_asm detected old-style dlopen, see #8458')
return 1