是否可以绕过add_subdirectory()命令的新范围创建?

tom*_*ahh 4 cmake

我目前有以下架构

`-- 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
Run Code Online (Sandbox Code Playgroud)

我的根源CMakeLists.txt如下

project(system)

add_subdirectory(dll)
add_subdirectory(sockets)
add_subdirectory(threads)

add_library(${PROJECT_NAME}
    ${${PROJECT_NAME}_HEADERS}
    ${${PROJECT_NAME}_SOURCES}
)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

但是,当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..范围问题了.

所以,如果我找到一个绕过范围创建的解决方案,我会很高兴,但我会采取任何保持架构逻辑的解决方案.

Fra*_*ser 6

我认为你有几个合理的选择.

add_subdirectory命令通常用于包含一个目录(它实际上不需要是文件系统意义上的子目录),它实际上包含一个独立的模块,例如库或可执行文件; 可以在没有父CMakeLists文件的帮助下构建的文件.在这种情况下,子模块的CMakeLists.txt将包含自己的project命令,使得${PROJECT_NAME}难以使用全局变量.

在您的情况下,您似乎只希望子目录的CMakeLists文件将文件列表附加到父作用域中定义的变量.您可以通过CMAKE_CURRENT_LIST_DIR在下级CMakeLists中使用CMake变量来实现此目的:

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
)
Run Code Online (Sandbox Code Playgroud)

确保你不会有一个project在你的子目录CMakeLists文件命令.

在这种情况下,通过使用add_subdirectory命令交换命令可以使这更简单include,从而避免了作用域问题.

为此,请PARENT_SCOPEset命令和顶级CMakeLists.txt中删除args :

add_subdirectory(dll)
add_subdirectory(sockets)
add_subdirectory(threads)
include(dll/CMakeLists.txt)
include(sockets/CMakeLists.txt)
include(threads/CMakeLists.txt)
Run Code Online (Sandbox Code Playgroud)


您的其他相关问题仅限于target_link_libraries(${PROJECT_NAME} pthread)add_library命令之后${PROJECT_NAME}调用定义库的命令.您最简单的选择可能是将命令移动到父CMakeLists.txttarget_link_librariestarget_link_libraries