Issue
In CMake projects with multiple targets, I often find myself repeating some code over and over again. See this example:
cmake_minimum_required(VERSION 3.12)
project(rapid_benchmark)
set(CMAKE_CXX_STANDARD 17)
add_executable(benchmark main.cpp)
add_executable(benchmark_parallel main.cpp) # enable parallel processing
add_executable(benchmark_openmp main.cpp) # enable openmp
add_executable(benchmark_static main.cpp) # enable static optimizations
# ... more targets
# Adding basic dependecies
find_package(abc)
if(abc_FOUND)
target_link_libraries(benchmark abc::abc)
target_link_libraries(benchmark_parallel abc::abc)
target_link_libraries(benchmark_openmp abc::abc)
# ... all other targets ...
# The same for the includes etc.
find_package(xyz)
if(xyz_FOUND)
target_link_libraries(benchmark xyz::xyz)
# ... all other targets ...
This is annoying and error prone, especially when adding new targets.
How can I avoid repetitive code with multiple targets in a CMake project?
For example, is there a way to put the targets into a kind of list and call target_link_libraries
on that list?
Solution
Same as Bernhard said, but in CMake :)
macro(add_benchmark)
set(singleValue NAME)
set(multipleValues SOURCES)
cmake_parse_arguments(local "" "${singleValue}" "${multipleValues}" ${ARGN})
set (libraries)
if (abc_FOUND)
set (libraries ${libraries} abc::abc)
endif()
if (xyz_FOUND)
set (libraries ${libraries} xyz::xyz)
endif()
add_executable(${local_NAME} ${local_SOURCES})
target_link_libraries(${local_NAME} ${libraries})
endmacro()
Then you can simply call it as any other CMake command:
add_benchmark(
NAME benchmark
SOURCES main.cpp
)
add_benchmark(
NAME benchmark_other
SOURCES main.cpp other.cpp
)
Answered By - AlexDenisov Answer Checked By - Cary Denson (WPSolving Admin)