After some work, I’ve managed to get this kind of working, but I’m running into strange issues.
First of all, I’ve managed to fix the syntax with the following:
set(CMAKE_LINKER lld-link CACHE STRING "")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>" CACHE STRING "")
I’m running into issues where the link executable line is getting constantly overridden however…
If I place the lines in the top level CMakeLists.txt for the parent project, it links properly with lld-link
, however any subprojects still build with vs_link_exe
!
If I place the lines in a toolchain file, and pass it via -DCMAKE_TOOLCHAIN_FILE
, the linker exe gets set for all of the compiler checks, and then is overridden AGAIN for the projects.
Here is an example:
Toolchain file:
# set lld link as our linker
set(CMAKE_LINKER lld-link CACHE STRING "")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>" CACHE STRING "")
message("ToolChain CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}")
Top level project file:
cmake_minimum_required(VERSION 3.23.0)
project(
King
VERSION 1.0.0
LANGUAGES C CXX)
message(STATUS "Setting linker to ${CMAKE_LINKER}")
#if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_LINKER MATCHES ".*lld-link.*")
# set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>")
#endif()
message("Project CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}")
Running initial CMake configuration results in the following ( I am using an MSVC developer prompt):
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_TOOLCHAIN_FILE="D:/Projects/king/cmake/toolchains/msvc-lld-link.cmake" -G Ninja "D:\Projects\king"
ToolChain CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>
ToolChain CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>
-- The C compiler identification is MSVC 19.31.31104.0
-- The CXX compiler identification is MSVC 19.31.31104.0
-- Detecting C compiler ABI info
ToolChain CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
ToolChain CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Setting linker to C:/Program Files/LLVM/bin/lld-link.exe
Project CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- <CMAKE_LINKER> /nologo <OBJECTS> /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>
-- Looking for pthread.h
ToolChain CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- Looking for C++ include mntent.h
ToolChain CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> /out:<TARGET>
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Projects/king/build/test
Note that the project CMAKE_CXX_LINK_EXECUTABLE gets reset back to the compiler detected one…
I guess it’s not respecting the fact that it has already been set and it is getting overridden? I am not sure what else I can do here.