Magnus pushed to branch wip/mangoiv/improve-linker-discovery at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • distrib/configure.ac.in
    ... ... @@ -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"
    

  • hadrian/src/Rules/BinaryDist.hs
    ... ... @@ -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.
    

  • m4/bindist_determine_linker.m4
    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
    +])

  • m4/find_merge_objects.m4
    ... ... @@ -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])