Magnus pushed to branch wip/mangoiv/improve-linker-discovery at Glasgow Haskell Compiler / GHC
Commits:
4 changed files:
- distrib/configure.ac.in
- hadrian/src/Rules/BinaryDist.hs
- + m4/bindist_determine_linker.m4
- m4/find_merge_objects.m4
Changes:
| ... | ... | @@ -175,7 +175,11 @@ AC_SUBST([CmmCPPSupportsG0]) |
| 175 | 175 | |
| 176 | 176 | dnl ** Which ld to use?
|
| 177 | 177 | dnl --------------------------------------------------------------
|
| 178 | -FIND_LD([$target],[GccUseLdOpt])
|
|
| 178 | +dnl currently if you pass $LD=foo, merge objs command will be set to $(which foo)
|
|
| 179 | +dnl which is not required by GHC and also wrong.
|
|
| 180 | +BINDIST_DETERMINE_LINKER([$target],[GccUseLdOpt])
|
|
| 181 | +dnl at this point, we should have set LD in all cases, so FIND_MERGE_OBJECTS command can
|
|
| 182 | +dnl go off and do it's thing
|
|
| 179 | 183 | FIND_MERGE_OBJECTS()
|
| 180 | 184 | CONF_GCC_LINKER_OPTS_STAGE1="$CONF_GCC_LINKER_OPTS_STAGE1 $GccUseLdOpt"
|
| 181 | 185 | CONF_GCC_LINKER_OPTS_STAGE2="$CONF_GCC_LINKER_OPTS_STAGE2 $GccUseLdOpt"
|
| ... | ... | @@ -365,16 +365,17 @@ bindistRules = do |
| 365 | 365 | |
| 366 | 366 | -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz
|
| 367 | 367 | tarPath <- builderPath (Tar Create)
|
| 368 | - cmd [Cwd $ root -/- bindist_folder] tarPath
|
|
| 369 | - [ "-c", compressorTarFlag compressor, "-f"
|
|
| 370 | - , ghcVersionPretty <.> "tar" <.> compressorExtension compressor
|
|
| 371 | - , ghcVersionPretty ]
|
|
| 368 | + cmd [Cwd $ root -/- bindist_folder] tarPath $
|
|
| 369 | + [ "-c"
|
|
| 370 | + , "-f" , compressorExtension compressor $ ghcVersionPretty <.> "tar"
|
|
| 371 | + , ghcVersionPretty ] <> compressorTarFlag compressor
|
|
| 372 | 372 | |
| 373 | 373 | forM_ [("binary", buildBinDist), ("reloc-binary", buildBinDistReloc)] $ \(name, mk_bindist) -> do
|
| 374 | 374 | phony (name <> "-dist") $ mk_bindist Xz
|
| 375 | 375 | phony (name <> "-dist-gzip") $ mk_bindist Gzip
|
| 376 | 376 | phony (name <> "-dist-bzip2") $ mk_bindist Bzip2
|
| 377 | 377 | phony (name <> "-dist-xz") $ mk_bindist Xz
|
| 378 | + phony (name <> "-dist-uncompressed") $ mk_bindist NoCompressor
|
|
| 378 | 379 | |
| 379 | 380 | phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz
|
| 380 | 381 | phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz
|
| ... | ... | @@ -430,7 +431,7 @@ bindistRules = do |
| 430 | 431 | fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f
|
| 431 | 432 | | otherwise = f
|
| 432 | 433 | |
| 433 | -data Compressor = Gzip | Bzip2 | Xz
|
|
| 434 | +data Compressor = Gzip | Bzip2 | Xz | NoCompressor
|
|
| 434 | 435 | deriving (Eq, Ord, Show)
|
| 435 | 436 | |
| 436 | 437 | |
| ... | ... | @@ -448,16 +449,18 @@ generateBuildMk BindistConfig{..} = do |
| 448 | 449 | a =. b = a ++ " = " ++ b
|
| 449 | 450 | |
| 450 | 451 | -- | Flag to pass to tar to use the given 'Compressor'.
|
| 451 | -compressorTarFlag :: Compressor -> String
|
|
| 452 | -compressorTarFlag Gzip = "--gzip"
|
|
| 453 | -compressorTarFlag Xz = "--xz"
|
|
| 454 | -compressorTarFlag Bzip2 = "--bzip"
|
|
| 452 | +compressorTarFlag :: Compressor -> [String]
|
|
| 453 | +compressorTarFlag Gzip = ["--gzip"]
|
|
| 454 | +compressorTarFlag Xz = ["--xz" ]
|
|
| 455 | +compressorTarFlag Bzip2 = ["--bzip"]
|
|
| 456 | +compressorTarFlag NoCompressor = []
|
|
| 455 | 457 | |
| 456 | 458 | -- | File extension to use for archives compressed with the given 'Compressor'.
|
| 457 | -compressorExtension :: Compressor -> String
|
|
| 458 | -compressorExtension Gzip = "gz"
|
|
| 459 | -compressorExtension Xz = "xz"
|
|
| 460 | -compressorExtension Bzip2 = "bz2"
|
|
| 459 | +compressorExtension :: Compressor -> String -> String
|
|
| 460 | +compressorExtension Gzip p = p <.> "gz"
|
|
| 461 | +compressorExtension Xz p = p <.> "xz"
|
|
| 462 | +compressorExtension Bzip2 p = p <.> "bz2"
|
|
| 463 | +compressorExtension NoCompressor p = p
|
|
| 461 | 464 | |
| 462 | 465 | -- | A list of files that allow us to support a simple
|
| 463 | 466 | -- @./configure [...] && make install@ workflow.
|
| 1 | +# BINDIST_DETERMINE_LINKER
|
|
| 2 | +# ------------------------
|
|
| 3 | +#
|
|
| 4 | +# This is used to determine the linker within the bindists configure
|
|
| 5 | +#
|
|
| 6 | +# Notes:
|
|
| 7 | +# - usually, linking works by invoking $CC
|
|
| 8 | +# - objects are merged using $LD directly
|
|
| 9 | +# - $LD is a configure variable and is meaningless to $CC
|
|
| 10 | +# - gcc only knows linker *flavours*, it cannot use paths
|
|
| 11 | +# which means that the linker path should not be an absolute path
|
|
| 12 | +# - clang konws --ld-path which means that it can be passed that
|
|
| 13 | +# flag and also merge objs can be an absolute path
|
|
| 14 | +#
|
|
| 15 | +# Algorithm:
|
|
| 16 | +# if $LD is set
|
|
| 17 | +# then if $CC accepts --ld-path=$(which $LD)
|
|
| 18 | +# then set --ld-path=$(which $LD), MergeObjsCommand=$(which $LD)
|
|
| 19 | +# else if $CC accepts --fuse-ld=$LD ($LD is a linker flavour, not an absolute path)
|
|
| 20 | +# then set -fuse-ld=$LD, MergeObjsCommand=$LD (not $(which ld))
|
|
| 21 | +# else Reject with
|
|
| 22 | +# "$LD is not compatible with $CC you chose. This means that $LD is either
|
|
| 23 | +# an unsupported linker flavour or your $CC does not support absolute linker
|
|
| 24 | +# paths"
|
|
| 25 | +# else if --disable-ld-override is set or $target is macos
|
|
| 26 | +# then if $CC accepts --ld-path=$(which ld)
|
|
| 27 | +# then set --ld-path=$(which ld), set MergeObjsCommand=$(which ld)
|
|
| 28 | +# else set *no* flag (equivalent to --fuse-ld=ld, if you will), set MergeObjsCommand=ld
|
|
| 29 | +# else if $CC accepts --ld-path=$(which ld.lld)
|
|
| 30 | +# then set --ld-path=$(which ld.lld), MergeObjsCommand=$(which ld.lld)
|
|
| 31 | +# else if $CC accepts -fuse-ld=lld
|
|
| 32 | +# then set -fuse-ld=lld, MergeObjsCommand=ld.lld
|
|
| 33 | +# else set *no* flag (equivalent to --fuse-ld=ld), set MergeObjsCommand=ld
|
|
| 34 | +#
|
|
| 35 | +# $1 = the platform
|
|
| 36 | +# $2 = the variable to set with GHC options to configure gcc to use the chosen linker
|
|
| 37 | +#
|
|
| 38 | +AC_DEFUN([BINDIST_DETERMINE_LINKER],[
|
|
| 39 | + AC_ARG_ENABLE(ld-override,
|
|
| 40 | + [AS_HELP_STRING([--disable-ld-override],
|
|
| 41 | + [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]])],
|
|
| 42 | + [],
|
|
| 43 | + [enable_ld_override=yes])
|
|
| 44 | + |
|
| 45 | + AC_REQUIRE([AC_PROG_CC])
|
|
| 46 | + AC_REQUIRE([AC_CANONICAL_TARGET])
|
|
| 47 | + |
|
| 48 | + check_ld_path() {
|
|
| 49 | + AC_MSG_CHECKING([whether C compiler supports --ld-path=[$]1])
|
|
| 50 | + ld_path="[$]1"
|
|
| 51 | + echo 'int main(void) { return 0; }' > conftest.c
|
|
| 52 | + if $CC -o conftest.o "--ld-path=$ld_path" $LDFLAGS conftest.c > /dev/null 2>&1
|
|
| 53 | + then
|
|
| 54 | + AC_MSG_RESULT([yes])
|
|
| 55 | + ld_path_ok=yes
|
|
| 56 | + else
|
|
| 57 | + AC_MSG_RESULT([no])
|
|
| 58 | + ld_path_ok=no
|
|
| 59 | + fi
|
|
| 60 | + rm -f conftest.c conftest.o
|
|
| 61 | + }
|
|
| 62 | + |
|
| 63 | + check_fuse_ld() {
|
|
| 64 | + AC_MSG_CHECKING([whether C compiler supports -fuse-ld=[$]1])
|
|
| 65 | + ld="[$]1"
|
|
| 66 | + echo 'int main(void) {return 0;}' > conftest.c
|
|
| 67 | + if $CC -o conftest.o -fuse-ld=[$]1 $LDFLAGS conftest.c > /dev/null 2>&1
|
|
| 68 | + then
|
|
| 69 | + AC_MSG_RESULT([yes])
|
|
| 70 | + fuse_ld_ok=yes
|
|
| 71 | + else
|
|
| 72 | + AC_MSG_RESULT([no])
|
|
| 73 | + fuse_ld_ok=no
|
|
| 74 | + fi
|
|
| 75 | + rm -f conftest.c conftest.o
|
|
| 76 | + }
|
|
| 77 | + |
|
| 78 | + try_set_linker_to() {
|
|
| 79 | + AC_MSG_CHECKING([whether linker can be set to [$]1])
|
|
| 80 | + tmp_ld=[$]1
|
|
| 81 | + abs_path=`command -v "$tmp_ld" 2>/dev/null` # get absolute path of $tmp_ld if it isn't already one
|
|
| 82 | + ld_path_ok="no"
|
|
| 83 | + if test "z$abs_path" != "z" && check_ld_path "$abs_path" && test "x$ld_path_ok" = "xyes";
|
|
| 84 | + then $2="--ld-path=$abs_path"
|
|
| 85 | + AC_CHECK_TARGET_TOOL([LD], [$abs_path])
|
|
| 86 | + linker_set_successfully=yes
|
|
| 87 | + else # --ld-path does not work or $LD cannot be resolved to an absolute path
|
|
| 88 | + fuse_ld_ok=no
|
|
| 89 | + if check_fuse_ld "$tmp_ld" && test "x$fuse_ld_ok" = "xyes";
|
|
| 90 | + then $2="-fuse-ld=$tmp_ld"
|
|
| 91 | + AC_CHECK_TARGET_TOOL([LD], [$tmp_ld])
|
|
| 92 | + linker_set_successfully=yes
|
|
| 93 | + else AC_MSG_WARN(["$tmp_ld could not be set via either '--ld-path' or '-fuse-ld"])
|
|
| 94 | + linker_set_successfully=no
|
|
| 95 | + fi
|
|
| 96 | + fi
|
|
| 97 | + }
|
|
| 98 | + |
|
| 99 | + # we are lenient when $LD=ld and just act as if $LD wasn't set and
|
|
| 100 | + # enable-ld-override is off
|
|
| 101 | + if test "z$LD" != "z" && test "z$LD" != "zld";
|
|
| 102 | + then linker_set_successfully=no
|
|
| 103 | + try_set_linker_to "$LD"
|
|
| 104 | + if test "z$linker_set_successfully" != "zyes";
|
|
| 105 | + then AC_MSG_FAILURE([ $tmp_ld is an invalid linker. If your C compiler accepts the '--ld-path' flag,
|
|
| 106 | + \$LD can be either of an executable name that is in \$PATH *or* a path to an executable.
|
|
| 107 | + If your C compiler only supports the '--fuse-ld' flag, \$LD can only be one of the linker flavours supported
|
|
| 108 | + by it. Mind that if your C compiler supports '--ld-path', 'configure' will always prefer using an absolute path
|
|
| 109 | + to your linker as that is less error-prone.])
|
|
| 110 | + fi
|
|
| 111 | + |
|
| 112 | + else # $LD is not set -- we will do the ld-override non-sense
|
|
| 113 | + if test "x$enable_ld_override" = "xyes" && test "z$LD" != "zld" && case "$1" in
|
|
| 114 | + *-darwin) false ;; # don't do the ld override thing on macos
|
|
| 115 | + *) true ;;
|
|
| 116 | + esac;
|
|
| 117 | + then
|
|
| 118 | + AC_MSG_NOTICE(["enable ld override was set and no more specific linker was chosen by setting \$LD, trying to find best possible linker"])
|
|
| 119 | + try_set_linker_to "lld"
|
|
| 120 | + if test "z$linker_set_successfully" != "zyes";
|
|
| 121 | + then # ... bail out, just use ld in path
|
|
| 122 | + $2=""
|
|
| 123 | + AC_CHECK_TARGET_TOOL([LD], [ld])
|
|
| 124 | + fi
|
|
| 125 | + else # ld override is not set and $LD not set either
|
|
| 126 | + $2=""
|
|
| 127 | + AC_CHECK_TARGET_TOOL([LD], [ld])
|
|
| 128 | + fi
|
|
| 129 | + fi
|
|
| 130 | + |
|
| 131 | + AC_MSG_NOTICE([linker discovery set $2 set to $$2])
|
|
| 132 | + |
|
| 133 | + CHECK_LD_COPY_BUG([$1])
|
|
| 134 | +]) |
| ... | ... | @@ -22,7 +22,6 @@ AC_DEFUN([CHECK_MERGE_OBJECTS],[ |
| 22 | 22 | ])
|
| 23 | 23 | |
| 24 | 24 | AC_DEFUN([FIND_MERGE_OBJECTS],[
|
| 25 | - AC_REQUIRE([FIND_LD])
|
|
| 26 | 25 | |
| 27 | 26 | if test -z ${MergeObjsCmd+x}; then
|
| 28 | 27 | AC_MSG_NOTICE([Setting cmd])
|