>我目前有以下架构
`-- 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.
.再次出现范围问题。
因此,如果我找到一个绕过范围创建的解决方案,我会很好,但我会采用任何保持我的架构逻辑的解决方案。
我认为你有几个合理的选择。
add_subdirectory
命令通常用于包含一个目录(它实际上不一定是文件系统意义上的子目录),该目录实际上包含一个独立的模块,例如库或可执行文件;一个可以在没有父CMakeLists文件帮助的情况下构建的模块。 在这种情况下,子模块的 CMakeLists.txt 将包含自己的project
命令,这使得全局${PROJECT_NAME}
变量的使用变得困难。
在您的情况下,您似乎只是希望子目录的 CMakeLists 文件将文件列表附加到父作用域中定义的变量。 您可以通过在从属 CMakeList 中使用 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
命令。
在这种情况下,通过将add_subdirectory
命令与include
命令交换,可以稍微简化一下,从而避免范围问题。
为此,请从set
命令和顶级 CMakeList 中删除PARENT_SCOPE
参数.txt:
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)
相关的另一个问题只是因为定义库${PROJECT_NAME}
的add_library
命令是在target_link_libraries
命令之后调用的。 最简单的选择可能是将target_link_libraries
命令移动到父 CMakeLists.txt