我目前有以下架构
`-- 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
我的根CMakeLists.txt
如下
project(system)
add_subdirectory(dll)
add_subdirectory(sockets)
add_subdirectory(threads)
add_library(${PROJECT_NAME}
${${PROJECT_NAME}_HEADERS}
${${PROJECT_NAME}_SOURCES}
)
并在threads/
例如,我有以下
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)
但是,当add_subdirectory()
创建新范围时,我的${PROJECT_NAME}_*
变量为空。我读到了set(... PARENT_SCOPE)
,但是这些路径变成了无效状态,无论如何cmake在target_link_libraries()
system/threads/CMakeLists.txt
Cannot specify link libraries for target "system" which is not built by this project.
的{{1}}调用{{1}}时产生错误。范围问题再次出现。
所以,如果我找到一个绕过范围创建的解决方案,我会很高兴,但我会采取任何保持架构逻辑的解决方案。
答案 0 :(得分:6)
我认为你有几个合理的选择。
add_subdirectory
命令通常用于包含一个目录(它实际上不需要是文件系统意义上的子目录),它实际上包含一个独立的模块,例如:图书馆或可执行文件;可以在没有父CMakeLists文件的帮助下构建的文件。在这种情况下,子模块的CMakeLists.txt将包含自己的project
命令,这使得使用全局${PROJECT_NAME}
变量变得困难。
在您的情况下,您似乎只希望子目录的CMakeLists文件将文件列表附加到父作用域中定义的变量。您可以通过在下级CMakeLists中使用CMake变量CMAKE_CURRENT_LIST_DIR
来实现此目的:
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
)
确保不在子目录的CMakeLists文件中有project
命令。
在这种情况下,通过使用include
命令交换add_subdirectory
命令可以稍微简化一下,从而避免了范围问题。
要执行此操作,请从PARENT_SCOPE
命令和顶级CMakeLists.txt中删除set
args:
add_subdirectory(dll)
add_subdirectory(sockets)
add_subdirectory(threads)
include(dll/CMakeLists.txt)
include(sockets/CMakeLists.txt)
include(threads/CMakeLists.txt)
您与target_link_libraries(${PROJECT_NAME} pthread)
相关的其他问题仅限于以下事实:定义库add_library
的{{1}}命令在 {{1}之后被称为命令。您最简单的选择可能是将${PROJECT_NAME}
命令移动到父CMakeLists.txt