Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcc: Add mold variant to use mold for linking #44117

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

msimberg
Copy link
Contributor

Triggered by #44034 (comment).

This adds a mold variant to gcc which, when enabled, adds mold to GCC's search paths and -fuse-ld=mold to use mold without a user having to specify it themselves. With these changes I'm able to create an executable that reports:

String dump of section '.comment':
  [     0]  GCC: (SUSE Linux) 7.5.0
  [    18]  mold 2.31.0 (compatible with GNU ld)
  [    3d]  GCC: (Spack GCC) 13.2.0

It might make sense to add conflicts for when the -fuse-ld=mold flag doesn't work. The fallback option would be to use mold's ld alias in libexec/mold and only set -B. From what I can tell the current approach does not allow overriding the linker with a manually provided -fuse-ld, which may be a problem for some users but I don't know how much of a problem it is as long as the mold variant is off by default.

From mold's README:

On Unix, the linker command (usually /usr/bin/ld) is indirectly invoked by the compiler driver (typically cc, gcc, or clang), which is in turn indirectly invoked by make or other build system commands.

If you can specify an additional command line option for your compiler driver by modifying the build system's config files, add one of the following flags to use mold instead of /usr/bin/ld:

For Clang: pass -fuse-ld=mold

For GCC 12.1.0 or later: pass -fuse-ld=mold

For GCC before 12.1.0: the -fuse-ld option does not accept mold as a valid argument, so you need to use the -B option instead. The -B option tells GCC where to look for external commands like ld.

If you have installed mold with make install, there should be a directory named /usr/libexec/mold (or /usr/local/libexec/mold, depending on your $PREFIX), and the ld command should be there. The ld is actually a symlink to mold. So, all you need is to pass -B/usr/libexec/mold (or -B/usr/local/libexec/mold) to GCC.

If you haven't installed ld.mold to any $PATH, you can still pass -fuse-ld=/absolute/path/to/mold to clang to use mold. However, GCC does not accept an absolute path as an argument for -fuse-ld.

Note: clang also supports -fuse-ld=mold, but I don't know how to enable that the same way in the llvm package, so I'm not going to deal with that (at least in this PR...).

@haampie
Copy link
Member

haampie commented May 10, 2024

🎉

@haampie
Copy link
Member

haampie commented May 10, 2024

I need to check this bit:

        # Binutils
        if spec.satisfies("+binutils"):
            binutils = spec["binutils"].prefix.bin
            options.extend(
                [
                    "--with-gnu-ld",
                    "--with-ld=" + binutils.ld,
                    "--with-gnu-as",
                    "--with-as=" + binutils.join("as"),
                ]
            )

which I believe is not entirely correct in that is uses absolute paths instead of file names, although now that I'm reading GCC's docs it does look sensible... (https://gcc.gnu.org/install/configure.html#with-as) In any case, it's likely we can delete those lines because we have this other -B<prefix> bit already.

Also I'm OK with gcc +binutils +mold like this PR allows, so that users can pick their favorite linker at runtime.

@msimberg
Copy link
Contributor Author

Also I'm OK with gcc +binutils +mold like this PR allows, so that users can pick their favorite linker at runtime.

Allowing +binutils +mold was an unintentional oversight by me 😅 though if you think it's ok to keep it like this that's fine by me. Note though that as far as I can tell the current version does not actually allow overriding the linker because (from a --verbose build) the -fuse-ld=mold and -B flags end up after flags provided on the command line.

@@ -129,6 +129,7 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage, CompilerPackage):
description="Compilers and runtime libraries to build",
)
variant("binutils", default=False, description="Build via binutils")
variant("mold", default=False, description="Use mold as the linker by default")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting as a reminder to revisit before merging. Maybe add

Suggested change
variant("mold", default=False, description="Use mold as the linker by default")
variant("mold", default=False, description="Use mold as the linker by default", when="@12:")

or

Suggested change
variant("mold", default=False, description="Use mold as the linker by default")
variant("mold", default=False, description="Use mold as the linker by default")
conflicts("+mold", when="@:11")

@haampie
Copy link
Member

haampie commented May 10, 2024

@alalazo knows a way to prepend.

Notice that +binutils also adds an assembler, and mold is only a linker, so we should be able to have both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants