diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2023-09-27 13:22:55 (GMT) |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2023-10-13 09:52:35 (GMT) |
commit | 96a953b1ed7e41260aa0869bad0ff14c788cf57e (patch) | |
tree | d9bedd8494b073f3795e4ed80f01b22a2b5a9093 /Tests/RunCMake | |
parent | ee5f31ba727e392e1ebc9f5be54c74ac1868d029 (diff) | |
download | CMake-96a953b1ed7e41260aa0869bad0ff14c788cf57e.zip CMake-96a953b1ed7e41260aa0869bad0ff14c788cf57e.tar.gz CMake-96a953b1ed7e41260aa0869bad0ff14c788cf57e.tar.bz2 |
Add options to specify linker tool
Offer the capability, through variable `CMAKE_LINKER_TYPE`, as well as
the target property `LINKER_TYPE` to specify which linker must be used.
The implementation of this capability is specified by variables specific
to the language and linker type: `CMAKE_<LANG>_USING_LINKER_<TYPE>`.
Some definitions are provided as part of `CMake`.
For example, to select the `LLVM` linker rather than the standard one,
the type `LLD` should be specified through the variable `CMAKE_LINKER_TYPE`.
And, on `Apple`, `Linux` and some environments on `Windows`, the variable
`CMAKE_<LANG>_USING_LINKER_LLD` has value `-fuse-ld=lld`. And for `Windows`
environments based on `MSVC`, where the linker is used directly, the tool
`lld-link.exe` will be used rather than `link.exe`.
Fixes: #19174, #24254, #24990
Diffstat (limited to 'Tests/RunCMake')
17 files changed, 170 insertions, 0 deletions
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 4387c5b..4f80015 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -737,6 +737,14 @@ if((CMAKE_C_COMPILER_ID STREQUAL "AppleClang" endif() endif() +if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin|Windows)" + AND CMAKE_C_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU|MSVC|NVIDIA)$" + AND NOT CMAKE_GENERATOR STREQUAL "Green Hills MULTI") + add_RunCMake_test(LinkerSelection -DCMake_TEST_CUDA=${CMake_TEST_CUDA} + -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} + -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}) +endif() + add_RunCMake_test(File_Archive) add_RunCMake_test(File_Configure) add_RunCMake_test(File_Generate) diff --git a/Tests/RunCMake/LinkerSelection/AppleClassic.cmake b/Tests/RunCMake/LinkerSelection/AppleClassic.cmake new file mode 100644 index 0000000..62a12ad --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/AppleClassic.cmake @@ -0,0 +1,7 @@ + +enable_language(C) + +set(CMAKE_LINKER_TYPE APPLE_CLASSIC) + +add_executable(main main.c) +target_link_libraries(main PRIVATE m m) diff --git a/Tests/RunCMake/LinkerSelection/CMakeLists.txt b/Tests/RunCMake/LinkerSelection/CMakeLists.txt new file mode 100644 index 0000000..6a9ce76 --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.28) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/LinkerSelection/CustomLinkerType-build-check.cmake b/Tests/RunCMake/LinkerSelection/CustomLinkerType-build-check.cmake new file mode 100644 index 0000000..235c38e --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/CustomLinkerType-build-check.cmake @@ -0,0 +1,2 @@ + +include("${CMAKE_CURRENT_LIST_DIR}/LinkerType-validation.cmake") diff --git a/Tests/RunCMake/LinkerSelection/CustomLinkerType.cmake b/Tests/RunCMake/LinkerSelection/CustomLinkerType.cmake new file mode 100644 index 0000000..4bf98b0 --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/CustomLinkerType.cmake @@ -0,0 +1,36 @@ + +enable_language(C) + +set(CMAKE_C_USING_LINKER_FOO_C "${CMAKE_C_USING_LINKER_LLD}") + +add_executable(main main.c) +set_property(TARGET main PROPERTY LINKER_TYPE "$<$<LINK_LANGUAGE:C>:FOO_C>$<$<LINK_LANGUAGE:CUDA>:FOO_CUDA>") + +if(CMake_TEST_CUDA) + enable_language(CUDA) + + set(CMAKE_CUDA_USING_LINKER_FOO_CUDA "${CMAKE_CUDA_USING_LINKER_LLD}") + + add_executable(mainCU main.cu) + set_property(TARGET mainCU PROPERTY LINKER_TYPE "$<$<LINK_LANGUAGE:C>:FOO_C>$<$<LINK_LANGUAGE:CUDA>:FOO_CUDA>") +endif() + +# +# Generate file for validation +# +if (CMAKE_C_USING_LINKER_MODE STREQUAL "TOOL") + cmake_path(GET CMAKE_C_USING_LINKER_FOO_C FILENAME LINKER_TYPE_OPTION) +else() + set(LINKER_TYPE_OPTION "${CMAKE_C_USING_LINKER_FOO_C}") +endif() +if(CMake_TEST_CUDA) + if (CMAKE_CUDA_USING_LINKER_MODE STREQUAL "TOOL") + cmake_path(GET CMAKE_CUDA_USING_LINKER_FOO_CUDA FILENAME CUDA_LINKER) + else() + set(CUDA_LINKER "${CMAKE_CUDA_USING_LINKER_FOO_CUDA}") + endif() + string(APPEND LINKER_TYPE_OPTION "|${CUDA_LINKER}") +endif() + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER_TYPE_OPTION.cmake" + "set(LINKER_TYPE_OPTION \"${LINKER_TYPE_OPTION}\")\n") diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt new file mode 100644 index 0000000..11aea7a --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt @@ -0,0 +1,3 @@ +CMake Error in CMakeLists.txt: + LINKER_TYPE 'FOO' is unknown. Did you forgot to define + 'CMAKE_C_USING_LINKER_FOO' variable\? diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake b/Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake new file mode 100644 index 0000000..bbe398c --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake @@ -0,0 +1,5 @@ + +enable_language(C) + +set(CMAKE_LINKER_TYPE FOO) +add_executable(main main.c) diff --git a/Tests/RunCMake/LinkerSelection/LinkerType-validation.cmake b/Tests/RunCMake/LinkerSelection/LinkerType-validation.cmake new file mode 100644 index 0000000..3f82479 --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/LinkerType-validation.cmake @@ -0,0 +1,9 @@ + +include ("${RunCMake_TEST_BINARY_DIR}/LINKER_TYPE_OPTION.cmake") + +# In some environment, `=` character is escaped +string(REPLACE "=" "\\\\?=" LINKER_TYPE_OPTION "${LINKER_TYPE_OPTION}") + +if (NOT actual_stdout MATCHES "${LINKER_TYPE_OPTION}") + set (RunCMake_TEST_FAILED "Not found expected '${LINKER_TYPE_OPTION}'.") +endif() diff --git a/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake b/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake new file mode 100644 index 0000000..cae4ca4 --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake @@ -0,0 +1,44 @@ +include(RunCMake) + +if (RunCMake_GENERATOR MATCHES "Visual Studio 9 2008") + run_cmake(UnsupportedLinkerType) + return() +endif() + +run_cmake(InvalidLinkerType) + +# look-up for LLVM linker +if (WIN32) + set (LINKER_NAMES lld-link) +else() + set(LINKER_NAMES ld.lld ld64.lld) +endif() +find_program(LLD_LINKER NAMES ${LINKER_NAMES}) + +macro(run_cmake_and_build test) + run_cmake_with_options(${test} -DCMake_TEST_CUDA=${CMake_TEST_CUDA}) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) + set(RunCMake_TEST_NO_CLEAN 1) + if(CMake_TEST_CUDA) + string(APPEND "|${CMAKE_CUDA_USING_LINKER_LLD}") + endif() + run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release --verbose ${ARGN}) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) +endmacro() + +if(LLD_LINKER) + block(SCOPE_FOR VARIABLES) + set(CMAKE_VERBOSE_MAKEFILE TRUE) + set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE) + set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE) + + run_cmake_and_build(ValidLinkerType) + run_cmake_and_build(CustomLinkerType) + endblock() +endif() + +if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0") + run_cmake_and_build(AppleClassic) +endif() diff --git a/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-result.txt b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-stderr.txt b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-stderr.txt new file mode 100644 index 0000000..6473451 --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-stderr.txt @@ -0,0 +1,3 @@ +CMake Error at UnsupportedLinkerType.cmake:[0-9]+ \(add_executable\): + 'LINKER_TYPE' property, specified on target 'main', is not supported by + this generator. diff --git a/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType.cmake b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType.cmake new file mode 100644 index 0000000..1b0703c --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType.cmake @@ -0,0 +1,5 @@ + +enable_language(C) + +set(CMAKE_LINKER_TYPE LDD) +add_executable(main main.c) diff --git a/Tests/RunCMake/LinkerSelection/ValidLinkerType-build-check.cmake b/Tests/RunCMake/LinkerSelection/ValidLinkerType-build-check.cmake new file mode 100644 index 0000000..235c38e --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/ValidLinkerType-build-check.cmake @@ -0,0 +1,2 @@ + +include("${CMAKE_CURRENT_LIST_DIR}/LinkerType-validation.cmake") diff --git a/Tests/RunCMake/LinkerSelection/ValidLinkerType.cmake b/Tests/RunCMake/LinkerSelection/ValidLinkerType.cmake new file mode 100644 index 0000000..a685ac1 --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/ValidLinkerType.cmake @@ -0,0 +1,32 @@ + +enable_language(C) + +set(CMAKE_LINKER_TYPE LLD) + +add_executable(main main.c) + +if(CMake_TEST_CUDA) + enable_language(CUDA) + + add_executable(mainCU main.cu) +endif() + +# +# Generate file for validation +# +if (CMAKE_C_USING_LINKER_MODE STREQUAL "TOOL") + cmake_path(GET CMAKE_C_USING_LINKER_LLD FILENAME LINKER_TYPE_OPTION) +else() + set(LINKER_TYPE_OPTION "${CMAKE_C_USING_LINKER_LLD}") +endif() +if(CMake_TEST_CUDA) + if (CMAKE_CUDA_USING_LINKER_MODE STREQUAL "TOOL") + cmake_path(GET CMAKE_CUDA_USING_LINKER_LLD FILENAME CUDA_LINKER) + else() + set(CUDA_LINKER "${CMAKE_CUDA_USING_LINKER_LLD}") + endif() + string(APPEND LINKER_TYPE_OPTION "|${CUDA_LINKER}") +endif() + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER_TYPE_OPTION.cmake" + "set(LINKER_TYPE_OPTION \"${LINKER_TYPE_OPTION}\")\n") diff --git a/Tests/RunCMake/LinkerSelection/main.c b/Tests/RunCMake/LinkerSelection/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/LinkerSelection/main.cu b/Tests/RunCMake/LinkerSelection/main.cu new file mode 100644 index 0000000..766b775 --- /dev/null +++ b/Tests/RunCMake/LinkerSelection/main.cu @@ -0,0 +1,5 @@ + +int main() +{ + return 0; +} |