mold icon indicating copy to clipboard operation
mold copied to clipboard

Can't link haskell programm

Open fulcanelly opened this issue 2 years ago • 10 comments

Error message

<no location info>: error:
    Warning: Couldn't figure out linker information!
             Make sure you're using GNU ld, GNU gold or the built in OS X linker, etc

Steps to reproduce

mold -run ghc Main.hs

Versions

ghc: The Glorious Glasgow Haskell Compilation System, version 8.10.7
mold: 1.0.0 (ed9924895d9b9584106791247596677db8113528; compatible with GNU ld and GNU gold)

fulcanelly avatar Dec 25 '21 18:12 fulcanelly

According to this it seems like ghc parses stdout to obtain linker information, so It should be relatively easy to solve.

But I still can't figure out with which arguments it's call it

fulcanelly avatar Dec 25 '21 19:12 fulcanelly

If I read the Haskell code correctly, the offending call is this one:

        (exitc, stdo, stde) <- readProcessEnvWithExitCode pgm
                               (["-Wl,--version"] ++ args3)
                               c_locale_env

From there the actual executed command is likely:

$CC "-Wl,--version" other_compiler+linker_args

Given gcc strips the -Wl, from the option this means that any of the patterns above is expected to start(???) the output of the linker …

HTH.

BenBE avatar Dec 25 '21 22:12 BenBE

As @BenBE pointed out, https://github.com/ghc/ghc/blob/40c0f67fb557b8d0d02eb805eb94db378489d580/compiler/GHC/SysTools/Info.hs#L128-L150 seems to recognize only LLD, GNU gold and GNU ld at the beginning of of the --version string.

For the sake of compatibility with programs that recognizes substrings in the --version string, mold's --version string contains GNU ld and GNU gold as substrings. But they aren't at the start of a line.

I think ghc is juts too picky about linkers. If it cannot recognize a linker's name, it should continue with the default linker options.

rui314 avatar Dec 26 '21 01:12 rui314

Can you report this bug to ghc?

rui314 avatar Dec 26 '21 01:12 rui314

I reported it

But they have 4000 of issues already, therefore I doubt fix will be fast. So it would be nice to add temporary solution in form of --ghc-fix wich changes --version output to match their patterns

fulcanelly avatar Dec 26 '21 02:12 fulcanelly

It is hard to remove a command line option once it is added, so I don't want to implement a workaround for ghc that way. If you compiled mold from source, you can apply the following patch to change the mold's --version string.

diff --git a/main.cc b/main.cc
index 7bb4916e..4d3bcf6c 100644
--- a/main.cc
+++ b/main.cc
@@ -14,10 +14,10 @@ std::string_view errno_string() {

 #ifdef GIT_HASH
 const std::string mold_version =
-  "mold " MOLD_VERSION " (" GIT_HASH "; compatible with GNU ld and GNU gold)";
+  "LLD mold " MOLD_VERSION " (" GIT_HASH "; compatible with GNU ld and GNU gold)";
 #else
 const std::string mold_version =
-  "mold " MOLD_VERSION " (compatible with GNU ld and GNU gold)";
+  "LLD mold " MOLD_VERSION " (compatible with GNU ld and GNU gold)";
 #endif

 void cleanup() {

rui314 avatar Dec 26 '21 03:12 rui314

Thanks @fulcanelly @rui314

Perhaps either of you could advise about how other projects detect which linker is going to be used? Do they also parse the version string or is there a more robust way?

Then I can execute a fix which agrees with the rest of the ecosystem.

mpickering avatar Dec 30 '21 10:12 mpickering

As far as I can tell, ./configure for example detects a linker by substring. It typically detects GNU ld, GNU gold and LLD if you have to distinguish them. (It typically detects ancient SunOS linkers, HP linkers, etc. as well, but that logic is not relevant anymore.)

In GHC's case, it looks like you guys want to pass -Wl,--hash-size=31 and -Wl,--reduce-memory-overheads only when ld is GNU ld. -Wl,--no-as-needed is always passed whatever the linker is. So, how about this logic?

  1. Initialize LDFLAGS with -Wl,--no-as-needed
  2. If ld --version contains "GNU ld" at the beginning of the line, it must be GNU ld, so append -Wl,--hash-size=31 and -Wl,--reduce-memory-overheads to LDFLAGS

rui314 avatar Dec 30 '21 10:12 rui314

Relevant ghc merge request for those interested: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7296

TerrorJack avatar Jan 07 '22 18:01 TerrorJack

@TerrorJack Cool! But I think there's a bug in that patch. I left a comment there.

rui314 avatar Jan 08 '22 01:01 rui314