Adding multiple executables in CMake
Solution 1
My suggestion is to tackle this in two phases:
- Build a library from the
.cpp
and.h
files, usingadd_library
- Iterate through all your
.cxx
files and create an executable from each, usingadd_executable
andforeach
Build the library
This could be something as simple as
file( GLOB LIB_SOURCES lib/*.cpp )
file( GLOB LIB_HEADERS lib/*.h )
add_library( YourLib ${LIB_SOURCES} ${LIB_HEADERS} )
Build all the executables
Simply loop over all the .cpp files and create separate executables.
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
# file( GLOB APP_SOURCES RELATIVE app/*.cxx )
file( GLOB APP_SOURCES app/*.cxx )
foreach( testsourcefile ${APP_SOURCES} )
# I used a simple string replace, to cut off .cpp.
string( REPLACE ".cpp" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
# Make sure YourLib is linked to each app
target_link_libraries( ${testname} YourLib )
endforeach( testsourcefile ${APP_SOURCES} )
Some warnings:
-
file( GLOB )
is usually not recommended, because CMake will not automatically rebuild if a new file is added. I used it here, because I do not know your sourcefiles. - In some situations, source-files may be found with a full pathname. If necessary, use the RELATIVE flag for
find( GLOB ... )
. - Manually setting the source-files requires a change to CMakeLists.txt, which triggers a rebuild. See this question for the (dis-)advantages of globbing.
- I generated the testname using a
string( REPLACE ... )
. I could have used get_filename_component with theNAME_WE
flag.
Concerning "general" CMake info, I advise you to read some of the broad "CMake Overview" questions already asked here on stackoverflow. E.g.:
Solution 2
I find myself in a similar situation when organizing an OpenGL project with multiple sample files where each of these files contain a main method.
The settings below will generate a separate executable per c/cpp file as well as copying required dependencies to the target bin folder.
Folder Structure
my-project
│── ch01_01.c
│── ch02_01.cpp
│── CMakeLists.txt
│── Resources
│ │── Libraries
│ │ │── glew
│ │ │ │── bin
│ │ │ │── include
│ │ │ │── lib
│ │ │── glfw
│ │ │ │── include
│ │ │ │── lib
CMakeLists.txt
cmake_minimum_required (VERSION 3.9)
project ("my-project")
include_directories(Resources/Libraries/glew/include
Resources/Libraries/glfw/include)
link_directories(Resources/Libraries/glew/lib
Resources/Libraries/glfw/lib)
link_libraries(opengl32.lib
glew32.lib
glfw3.lib)
set(CMAKE_EXE_LINKER_FLAGS "/NODEFAULTLIB:MSVCRT")
file(GLOB SOURCE_FILES *.c *.cpp)
foreach(SOURCE_PATH ${SOURCE_FILES})
get_filename_component(EXECUTABLE_NAME ${SOURCE_PATH} NAME_WE)
add_executable(${EXECUTABLE_NAME} ${SOURCE_PATH})
# Copy required DLLs to the target folder
add_custom_command(TARGET ${EXECUTABLE_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/Resources/Libraries/glew/bin/glew32.dll"
"${CMAKE_BINARY_DIR}/glew32.dll")
endforeach(SOURCE_PATH ${SOURCE_FILES})
Optional Steps
In Visual Studio
-
Open the project with 'Open a local Folder' option in the Start Window
-
When adding a new file you may either:
- Cancel the dialog asking to automatically
add_executable
to CMakeLists.txt - Disable this behavior by unchecking 'Enable automatic CMake script modification for file operations from folder view' in
Tools > Options > CMake
- Cancel the dialog asking to automatically
As newly added files are not picked up automatically as CMakeLists.txt is never changed, simply regenerate the cache like so:
Project > CMake Cache (x64-Debug) > Delete Cache
Project > Generate Cache for my-project
Now you may simply right click a given c/cpp file and Set as Startup Item
to be able to debug it with F5
.
Environment
- cmake version 3.18.20081302-MSVC_2
- Microsoft Visual Studio Community 2019 Version 16.8.3
Starter Template
I put together this starter template on GitHub in case you are interested.
Related videos on Youtube

ssb
Updated on January 29, 2022Comments
-
ssb over 1 year
My code in a C++ project is organised as follows
- I have several
.cpp
and.h
files which contains my classes - I have several
.cxx
files which have to be compiled against the.cpp
files and some external libraries.
Now, each of the
.cxx
files have amain()
method, so I need to add a different executable for each of these files having the same name as the file.Also, these
.cxx
files might not get linked to the same external libraries.I want to write this build in CMake, in which I am kind of a newbie, how do I go about this?
- I have several