Is it possible to get around creating a new scope for the add_subdirectory () command?

I currently have the following architecture

`-- system |-- CMakeLists.txt |-- dll | |-- CMakeLists.txt | |-- UnixDLoader.cpp | |-- ... | `-- WinDLoader.hh |-- sockets | |-- CMakeLists.txt | |-- crossplateform_utils.h | |-- ... | `-- Udp.hh `-- threads |-- CMakeLists.txt |-- IMutex.hh |-- ... `-- WinThread.hh 

My CMakeLists.txt root is as follows

 project(system) add_subdirectory(dll) add_subdirectory(sockets) add_subdirectory(threads) add_library(${PROJECT_NAME} ${${PROJECT_NAME}_HEADERS} ${${PROJECT_NAME}_SOURCES} ) 

and in threads/ , for example, I have the following

 list(APPEND ${PROJECT_NAME}_HEADERS IThread.hh UnixThread.hh WinThread.hh IMutex.hh UnixMutex.hh WinMutex.hh ) set(${PROJECT_NAME}_HEADERS ${${PROJECT_NAME}_HEADERS} PARENT_SCOPE) list(APPEND ${PROJECT_NAME}_SOURCES UnixThread.cpp WinThread.cpp UnixMutex.cpp WinMutex.cpp PARENT_SCOPE ) set(${PROJECT_NAME}_SOURCES ${${PROJECT_NAME}_SOURCES} PARENT_SCOPE) if(UNIX) target_link_libraries(${PROJECT_NAME} pthread) endif(UNIX) 

but since add_subdirectory() creates a new scope, my ${PROJECT_NAME}_* variables are empty. I read about set(... PARENT_SCOPE) , but the paths become invalid, and in any case cmake causes an error when calling target_link_libraries() in system/threads/CMakeLists.txt saying Cannot specify link libraries for target "system" which is not built by this project. . Problem again.

So, although it would be nice for me if I could find a solution to circumvent the creation of a domain, I will take any solution that supports the logic of my architecture.

+4
source share
1 answer

I have some reasonable options.

The add_subdirectory command add_subdirectory often used to include a directory (in fact, it will not be a subdirectory in the sense of the file system), which really contains a stand-alone module, for example. library or executable file; which can be built without the help of the parent CMakeLists file. In this case, the CMakeLists.txt submodule will contain its own project command, which makes it difficult to use the global variable ${PROJECT_NAME} .

In your case, it seems that you just want the CMakeLists files in the subdirectories to add the file lists to the variables defined in the parent scope. You can achieve this using the CMake variable CMAKE_CURRENT_LIST_DIR in subordinate CMakeLists:

 set(${PROJECT_NAME}_HEADERS ${${PROJECT_NAME}_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/IThread.hh ${CMAKE_CURRENT_LIST_DIR}/UnixThread.hh ${CMAKE_CURRENT_LIST_DIR}/WinThread.hh ${CMAKE_CURRENT_LIST_DIR}/IMutex.hh ${CMAKE_CURRENT_LIST_DIR}/UnixMutex.hh ${CMAKE_CURRENT_LIST_DIR}/WinMutex.hh PARENT_SCOPE ) set(${PROJECT_NAME}_SOURCES ${${PROJECT_NAME}_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/UnixThread.cpp ${CMAKE_CURRENT_LIST_DIR}/WinThread.cpp ${CMAKE_CURRENT_LIST_DIR}/UnixMutex.cpp ${CMAKE_CURRENT_LIST_DIR}/WinMutex.cpp PARENT_SCOPE ) 

Make sure you do not have the project command in the CMakeLists files of your subdirectories.

In this case, this can be made a little simpler by replacing the add_subdirectory command with the include command, which will avoid problems with defining the scope.

To do this, remove the PARENT_SCOPE arguments from the set commands and in the top-level CMakeLists.txt:

 add_subdirectory(dll) add_subdirectory(sockets) add_subdirectory(threads) include(dll/CMakeLists.txt) include(sockets/CMakeLists.txt) include(threads/CMakeLists.txt) 


Another problem with target_link_libraries(${PROJECT_NAME} pthread) is simply that after the target_link_libraries command, the add_library command is add_library to define the library ${PROJECT_NAME} . Your easiest option is probably to move the target_link_libraries command to the parent CMakeLists.txt

+6
source

All Articles