mold
mold copied to clipboard
Can't link haskell programm
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)
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
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.
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.
Can you report this bug to ghc?
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
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() {
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.
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?
- Initialize LDFLAGS with
-Wl,--no-as-needed
- 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
Relevant ghc merge request for those interested: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7296
@TerrorJack Cool! But I think there's a bug in that patch. I left a comment there.