crt: Manually do the linker test for __ImageBase Instead of using AC_LINK_IFELSE, construct a test file and manually run a compile/linking command. This fixes the linker test when bootstrapping a toolchain from scratch. This matches the previous configure time link test we had, which was removed in 6f53dbf6d423fab5a9fc6b3e4b07bdcf66d253b5. See baaf945d53f7dedb15b6f5342bd04e8fd4952211, 30af18252d4e965e98612e215b8cf6b7ae42c01a, ccda8b5229e428a6fa7036140778b23d11b554e8 and bda8fc0064e12d07e0f0e0c696dc0568b13c096f for earlier attempts at making configure time linker tests that work across various tools when bootstrapping the toolchain itself; this solution incorporates all the lessons learnt from the previous linker tests. Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-crt/configure.ac b/mingw-w64-crt/configure.ac index a6d1208..3660478 100644 --- a/mingw-w64-crt/configure.ac +++ b/mingw-w64-crt/configure.ac
@@ -370,7 +370,48 @@ # Check for __ImageBase linker symbol. AC_MSG_CHECKING([whether the linker provides __ImageBase symbol]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern unsigned char __ImageBase[];]], [[return __ImageBase[0];]])], [ld_provides_imagebase=yes], [ld_provides_imagebase=no]) +# Run this test manually instead of wrapping it in AC_LINK_IFELSE; when +# bootstrapping an environment, an earlier linking test will have failed, +# which both causes autoconf to refuse to run any linker test at all, +# and even if $ac_no_link is overridden, the linker test iteslf will explicitly +# check that the linker actually produced output in the given output file. +# If $ac_exeext is empty, as it is when the earlier linker test failed, gcc +# will behave differently depending on version. If run with "gcc conftest.c +# -o conftest", old versions will produce explicitly a file named "conftest", +# while modern GCC versions will produce "conftest.exe". AC_LINK_IFELSE will +# explicitly look for the output file named "conftest$ac_exeext", which isn't +# found, and the test fails even though linking succeeded. +# +# Therefore, just do a manual test; run the linking command and check the return +# code whether it was successful or not. +# +# This test uses both mainCRTStartup and main functions, to let lld deduce +# entry point and subsystem automatically without having to manually specify, +# anything. And as long as main() is provided, we need to implicitly provide +# __main as well, since the compiler injects a call to it. + +cat <<_ACEOF >conftest.$ac_ext +extern unsigned char __ImageBase[[]]; +void __main(void) { +} +int main(void) { + return __ImageBase[[0]]; +} +int mainCRTStartup(void) { + return main(); +} +_ACEOF + +echo "$as_me:$LINENO: $CC conftest.$ac_ext $LDFLAGS -nostdlib -o conftest$ac_exeext" >&AS_MESSAGE_LOG_FD +# Doing the link test with -nosdlib, to avoid trying to link in any libraries +# which might not exist yet at this point. +if $CC conftest.$ac_ext $LDFLAGS -nostdlib -o conftest$ac_exeext >&AS_MESSAGE_LOG_FD 2>&1; then + ld_provides_imagebase=yes +else + ld_provides_imagebase=no +fi +rm -f conftest$ac_exeext conftest.$ac_ext + AC_MSG_RESULT([$ld_provides_imagebase]) AM_CONDITIONAL([LD_PROVIDES_IMAGEBASE],[test $ld_provides_imagebase = yes])