Reputation: 517
I'm currently dealing with a less than ideal CMake setup that I am trying to rectify. The top level CMakeListsMain.txt contains compiler settings, include directories, macros, etc, which all projects depend on and use. My source tree contains many projects, but I've scaled it down here.
src/
CMakeListsMain.txt
project1/
-->CMakeLists.txt
project2/
-->CMakeLists.txt
headers/
-->source headers for every project
For example CMakeListsMain.txt looks something like this, yet way more complex:
MACRO(USE_BOOST target)
target_link_libraries(${target} boost_thread-mt boost_filesystem-mt boost_regex-mt boost_system-mt)
ENDMACRO(USE_BOOST)
MACRO(USE_PTHREAD target)
target_link_libraries(${target} pthread)
ENDMACRO(USE_PTHREAD)
add_subdirectory(project1)
add_subdirectory(project2)
Project 1 and 2 both use the macros and other settings in the top level CMakeListsTop.txt
Previously if I wanted to build one project, CMake would have to run on every directory, which is not good.
My question is if I wanted to build each project separately from each other how would I get access to these macros and other settings. Currently I have abstracted out the macros into a different file and have been including that file in the CMakeLists.txt of each project. Doing it this way I would also have to use absolute paths to reference the header files in the source tree instead of using CMAKE_SOURCE_DIR/headers
.
I can't really change the layout of the source tree without getting approval, but is there an easier way to do this or something I have overlooked?
Upvotes: 2
Views: 2135
Reputation: 3083
Add this macro
MACRO(ADD_PROJECT PROJECT)
IF(${PROJECT} OR ALL)
add_subdirectory(${PROJECT})
ENDIF()
ENDMACRO()
to your top-level CMakeLists.txt, and replace all occurrences of add_subdirectory
with
ADD_PROJECT(project1)
ADD_PROJECT(project2)
and so on. Now you can build any single project by calling cmake with the flag -Dproject1=1
etc., or the whole project with -DALL=1
.
Upvotes: 1
Reputation: 5348
You could move the macros and settings out into a module. You can then wrap the module in an include guard to ensure it is only executed once and include it from each of the CMakeLists.txt that need to be built independently.
So for your example, the module file would look like:
IF(NOT DEFINED MAIN_SETTINGS_INCLUDED)
SET(MAIN_SETTINGS_INCLUDED ON)
MACRO(USE_BOOST target)
target_link_libraries(${target} boost_thread-mt boost_filesystem-mt boost_regex-mt boost_system-mt)
ENDMACRO(USE_BOOST)
MACRO(USE_PTHREAD target)
target_link_libraries(${target} pthread)
ENDMACRO(USE_PTHREAD)
ENDIF()
Upvotes: 1