2012-12-31 34 views
4

目前,我有以下结构是否可以绕过add_subdirectory()命令的新范围创建?

`-- 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.txtCannot specify link libraries for target "system" which is not built by this project.产生错误。范围问题再次。

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

回答

6

在这里我有一些合理的选择。

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

就你而言,你似乎只是想让子目录的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命令。

在这种情况下,可以通过将add_subdirectory命令与include命令交换,从而避免范围界定问题,从而使其稍微简单一些。

要做到这一点,从set命令删除PARENT_SCOPE ARGS,并在顶层的CMakeLists.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

+0

您的解决方案非常完美,非常感谢。 – tomahh

相关问题