Setting linker in Clang builds on Windows


I have a C++ project which I would like to build with Clang, and link with MSVC link.exe. The only way I was able to figure out how to make this happen was to modify the Windows-Clang.cmake file included with my CMake distribution (3.21), modifying the lines which define the CMAKE_${lang}_CREATE_SHARED_LIBRARY and CMAKE_${lang}_LINK_EXECUTABLE.

Below is a snippet of what that file looks like after my modifications:

In the original version of the file, the underlined portions were “-fuse-ld=lld-link”, which resulted in the Clang linker being used in all circumstances.

I assume that the intention of the CMake developers is not for users to modify these files, so what is the idiomatic way of effecting a change equivalent to this? The root of the difficulty seems to be that this flag is hard-coded in this file rather than being drawn from some other configuration variable.

Any advice would be greatly appreciated.

Zachary Benavides

You should be able to use CMAKE_{EXE,MODULE,SHARED}_LINKER_FLAGS variable to add this to all link lines in your own project (or in a per-build configuration).

1 Like

Thanks for the reply Ben.

That approach works for my use case, but in perhaps a somewhat unexpected way. The prefix of the generated linker command still contains the option that I want to change with the default value from that file above, but then contains the option again with the argument that I set in the CMAKE_EXE_FLAGS variable. Clang apparently handles this by overwriting the value, which results in the desired behavior in my case. So thank you!

Are you aware of any way to control the full set of options that CMake passes to the compiler driver during the linking phase, or are we essentially at the mercy of the choices made in these platform modules?

CMake doesn’t offer fine-grained control over the command lines because it prefers to offer abstractions (where possible). There are some features which are generator-specific, but for the IDE generators, even CMake doesn’t have fine-grained control over the command lines to offer in the first place, so these kinds of controls don’t really work in general. That doesn’t preclude offering it, but it’s a tough line to follow.