Issue
I am trying to collect a list of all of the executables my project generates and create a make target that runs all of the binaries.
Here's an example project structure:
.
├── CMakeLists.txt
├── cmake
│ └── collect_binaries.cmake
└── src
├── CMakeLists.txt
├── a
│ ├── CMakeLists.txt
│ └── a.cpp
└── b
├── CMakeLists.txt
└── b.cpp
My top level CMakeLists.txt file is below. As you can see, I'm setting a global list which I would like to use.
cmake_minimum_required(VERSION 3.15)
project(
example
VERSION 0.0.0
LANGUAGES CXX
)
include(cmake/collect_binaries.cmake)
set(EXECUTABLES_LIST)
add_subdirectory(src)
add_custom_target(run_all ALL
COMMAND ${CMAKE_COMMAND} -E echo "Running all executables..."
)
message(STATUS "executables: ${EXECUTABLES_LIST}")
# Add performance executables as dependencies for the custom target
add_dependencies(run_all ${EXECUTABLES_LIST})
foreach(exe IN LISTS ${EXECUTABLES_LIST})
add_custom_command(
TARGET run_all POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Running ${exe}..."
COMMAND $<TARGET_FILE:${exe}>
)
endforeach()
I intend to collect all my targets by wrapping the call to add_executable with my own function, defined in cmake/collect_binaries.cmake:
function(collect target_name)
add_executable(${target_name} ${ARGN})
set(${EXECUTABLES_LIST} "${EXECUTABLES_LIST}" "${target_name}" PARENT_SCOPE)
endfunction()
Here are the rest of my files:
src/CMakeLists.txt:
add_subdirectory(a)
add_subdirectory(b)
src/a/CMakeLists.txt:
collect(
a a.cpp
)
src/b/CMakeLists.txt:
collect(
b b.cpp
)
both a and b.cpp:
#include <iostream>
int main() {
std::cout << "here" << std::endl;
return 0;
}
When I run this:
mkdir build
cd build
cmake ..
I can see that the executables are not appended to the list:
:: cmake ..
-- The CXX compiler identification is AppleClang 14.0.0.14000029
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- executables:
CMake Error at CMakeLists.txt:21 (add_dependencies):
add_dependencies called with incorrect number of arguments
-- Configuring incomplete, errors occurred!
Solution
Iterate over all subdirectories and iterate over all targets and check if the target is a executable then add it to a list. And output.
function(get_all_executables out)
if(NOT DEFINED ${out})
set(${out})
endif()
if(ARGC EQUAL 2)
set(root ${ARGV1})
else()
set(root ${CMAKE_SOURCE_DIR})
endif()
#
get_directory_property(targets BUILDSYSTEM_TARGETS DIRECTORY ${root})
foreach(target IN LISTS targets)
get_target_property(type ${target} TYPE)
if(type STREQUAL "EXECUTABLE")
list(APPEND ${out} ${target})
endif()
endforeach()
get_directory_property(dirs SUBDIRECTORIES DIRECTORY ${root})
foreach(dir IN LISTS dirs)
get_all_executables(${out} ${dir})
endforeach()
set(${out} ${${out}} PARENT_SCOPE)
endfunction()
get_all_executables(list)
message(FATAL_ERROR "EXECUTABLES:" ${list})
Answered By - KamilCuk Answer Checked By - Katrina (WPSolving Volunteer)