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 root CMakeLists.txt is as follow
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, as add_subdirectory() creates a new scope, my ${PROJECT_NAME}_* variables are empty. I read about set(... PARENT_SCOPE), but the paths become invalids and anyhow cmake produces an error on the call to target_link_libraries() in system/threads/CMakeLists.txt saying Cannot specify link libraries for target "system" which is not built by this project.. Scope issue again.
So I though I would be nice if I found a solution to bypass the scope creation, but I’ll take any solution that keeps the logic of my architecture.
You have a couple of reasonable options here I think.
The
add_subdirectorycommand is often used to include a directory (it needn’t actually be a subdirectory in the filesystem sense) which really contains a standalone module, e.g. a library or executable; one which can be built without the help of a parent CMakeLists file. In this case, the submodule’s CMakeLists.txt would contain its ownprojectcommand, rendering the use of a global${PROJECT_NAME}variable difficult.In your case, it appears that you simply want the subdirectories’ CMakeLists files to append lists of files to variables defined in the parent scope. You can achieve this by making use of the CMake variable
CMAKE_CURRENT_LIST_DIRin your subordinate CMakeLists:Ensure you don’t have a
projectcommand in your subdirectories’ CMakeLists files.This can be made slightly simpler in this case by swapping the
add_subdirectorycommand with theincludecommand, hence avoiding scoping issues.To do this, remove the
PARENT_SCOPEargs from thesetcommands, and in the top-level CMakeLists.txt:Your other issue relating to
target_link_libraries(${PROJECT_NAME} pthread)is simply down to the fact that theadd_librarycommand defining the library${PROJECT_NAME}is called after thetarget_link_librariescommand. Your simplest option is probably to move thetarget_link_librariescommand to the parent CMakeLists.txt