Handling of linker flags inconsistent

While working on https://gitlab.kitware.com/cmake/cmake/-/merge_requests/9107 I noticed that linker flag handling is inconsistent.

What exactly is inconsistent?
According to the docs variables like CMAKE_SHARED_LINKER_FLAGS_<CONFIG> are flags passed to the linker or flags used by the linker. This however is only true if the link rule is actually invoking the linker directly and not through the compiler frontend. As such the description is currently only true for Windows-MSVC where the link rules invoke link directly. Secondly, there are variables like CMAKE_<LANG>_LINKER_WRAPPER_FLAG which is used to tell cmake what to prepend to stuff added via target_link_options etc. This however leads to a design flag where the user actually needs to know the internal CMake rule to know if CMAKE_SHARED_LINKER_FLAGS_<CONFIG> should have -Xlinker/-Wl, or not. The problem is probably historic due to Makefiles typically invoking CC for linkage and using LDFLAGS directly, so it is always clear that -Xlinker/-Wl, is necessary (Ignoring manual written Makefile rules for MSVC etc.).

In my case wanting to using a clang(for CUDA/ASM)/clang-cl (for C/CXX) mixed toolchain it leads to the problem where one time the compiler is used for linkage and another time the linker ist used for linkage needing to define CMAKE_SHARED_LINKER_FLAGS_<CONFIG> theoretically on a language based level due to the above inconsistency with the link flags (probably could always add -Xlinker due to MSVC being nice about unknown flags but this would give a lot of warnings).

Possible suggestions for a solution.
a) Prepend the wrapper flag to CMAKE_SHARED_LINKER_FLAGS_<CONFIG> if it isn’t there yet
b) Use a response file for all given linker flags and always apply the wrapper flag. This would work -Xlinker/-Wl, and /link

So what would be the best solution for this problem going forward?

Cc: @brad.king

These variables are meant to be command-line fragments of the final link line regardless of whether it is driven by a compiler driver or a direct linker invocation. Indeed the convention comes from the $CC $LDFLAGS days, and yes it requires whoever is setting the value to know how the link step is driven.

target_link_options is a more modern method of adding linker flags, and it provides the LINKER: prefix to map to any needed wrapper flag. Maybe we could consider resolving the LINKER: prefix inside the link flags variables too.

1 Like

Maybe we could consider resolving the LINKER: prefix inside the link flags variables too.

That should make switching between different linker rules possible.

I’ve opened CMake Issue 25620 for this.