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 a main()
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?
My suggestion is to tackle this in two phases:
- Build a library from the
.cpp
and .h
files, using add_library
- Iterate through all your
.cxx
files and create an executable from each, using add_executable
and foreach
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 the NAME_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.:
- CMake tutorial
- What are the dusty corners a newcomer to CMake will want to know?