mold
mold copied to clipboard
Create mold-config.cmake
This creates a CMake config file that makes it easy for users to use mold in their CMake projects. Sample usage:
root@1b8ec34409d4:~/hello# cat CMakeLists.txt
add_executable(hello hello.cc)
find_package(mold CONFIG)
if(mold_FOUND)
target_use_mold(hello)
endif()
root@1b8ec34409d4:~/hello# mkdir build && cd build
root@1b8ec34409d4:~/hello/build# cmake ..
<output truncated>
-- Build files have been written to: /root/hello/build
root@1b8ec34409d4:~/hello/build# cmake --build .
[ 50%] Building CXX object CMakeFiles/hello.dir/hello.o
[100%] Linking CXX executable hello
[100%] Built target hello
root@1b8ec34409d4:~/hello/build# readelf -p .comment hello
String dump of section '.comment':
[ 0] GCC: (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
[ 2c] mold 1.7.0 (b63bb4aecf7afd23858d8d743eee734ca9f3868d; compatible with GNU ld)
Thanks to configure_package_config_file
it is not difficult to create a relocatable config file that can be installed anywhere, because no absolute paths are hardcoded in the generated file. Instead there's this line in the generated file which computes the prefix relative to its own location:
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
target_use_mold
is implemented by simply adding a linker flag. It assumes that CMAKE_LINKER
is not manually set to a linker executable, or something else that's not compatible (if that's the case, the user won't need this anyway). -B${LIBEXECDIR}/mold/ld
is used on non-macOS targets. For macOS targets, -fuse-ld=${BINDIR}/ld64.mold
is used, because the ld
in mold's LIBEXECDIR
will invoke the ELF linker.
I created this with the intention of resolving #849, but it ended up being a little different from what #849 asked for, as this target_use_mold
function does not allow the user to choose their own linker. But here's what I think:
- Just as mentioned in the readme, it seems that the compatible way to tell both Clang and GCC (pre-12.1) to use a specific linker is to use the
-B
flag. But that requires the linker to have its ownld
somewhere. To my knowledge, there's no such thing from gold and lld. [^1] - I personally think that maybe
target_use_mold
is good enough. The config file is distributed with mold, so it would be a little peculiar to do something like:
find_package(mold CONFIG)
if(mold_FOUND)
mold_target_use_linker(<target> lld)
endif()
What do you think, @rui314?
[^1]: That's not impossible to implement, though -- a proxy as simple as ld.$LINKER "$@"
will do, I think.
I made a stupid mistake that I didn't realise until I rebased -- there's no reason to restrict that to executable targets.
I think we need to do two things for CMake integration:
Short term solution: We want to provide a package like this, and let the user to use the mold linker if it is available. So the typical usage pattern would be:
find_package(mold CONFIG)
if(mold_FOUND)
target_use_mold(<target-name>)
endif()
Long term solution*: I'd generalize the fetature so that the function takes a linker name like target_use_linker(<target_name> [ bfd | gold | lld | mold])
. And then contribute it to CMake rather than to this project.
This patch should work as a short-term solution, so I'm fine with that. I'm no CMake expert, so I'm not sure if it is good enough though, so let me allow more time to review it. But it's general looking good.
Do you want to work on the long-term solution by the way?
Short term solution: We want to provide a package like this, and let the user to use the mold linker if it is available.
Agreed. So that's what's being done here, on mold's side.
find_package(mold CONFIG) if(mold_FOUND) target_use_mold(<target-name>) endif()
Oops, I missed the mold_FOUND
part -- will update the usage example later.
This patch should work as a short-term solution, so I'm fine with that. I'm no CMake expert, so I'm not sure if it is good enough though, so let me allow more time to review it. But it's general looking good.
Sure, thanks, Rui-san.
Do you want to work on the long-term solution by the way?
Understood. I'd be genuinely interested! But speaking off the top of my head, that'd be quite some work, and from where I'm standing, I may not be familiar enough with CMake to qualify :( . While I'll definitely have a look at it, I think it's best to leave that opportunity open to those who are more capable.
This pull request is a bad solution for the short-term problem. *-config.cmake
are used to pass include directories, libraries, compile options, and CMake target. None is required for using mold. All you need to do is find the executalbe mold or mold.exe.
Given CMake 3.29 (not yet released) will support an easy way to set the linker, I suggest closing this pull request.