【问题标题】:Populating ${SRCS} from CMakeLists.txt in subdirectories在子目录中从 CMakeLists.txt 填充 ${SRCS}
【发布时间】:2011-08-12 22:25:15
【问题描述】:

我目前在我的项目根目录的CMakeLists.txt 文件中定义了一个${SRCS} 变量,列出了我的可执行文件所需的每个源文件:

SET (SRCS main.cpp
          dir1/file1.cpp
          dir1/file2.cpp
          dir2/file3.cpp
          dir2/file4.cpp)

如何在每个子目录中的CMakeLists.txt 文件中分发此列表?那就是:

CMakeLists.txt
    Adds main.cpp to SRCS and subdirectories dir1 and dir2

dir1/CMakeLists.txt
    Adds file1.cpp, file2.cpp to SRCS

dir2/CMakeLists.txt
    Adds file3.cpp, file4.cpp to SRCS

【问题讨论】:

    标签: cmake


    【解决方案1】:

    最好隐藏在 CMake macro 中设置变量 SRCS 的所有细节。然后可以在所有项目 CMake 列表文件中调用该宏来添加源。

    在项目根文件夹的CMakeLists.txt中,添加如下宏定义:

    macro (add_sources)
        file (RELATIVE_PATH _relPath "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
        foreach (_src ${ARGN})
            if (_relPath)
                list (APPEND SRCS "${_relPath}/${_src}")
            else()
                list (APPEND SRCS "${_src}")
            endif()
        endforeach()
        if (_relPath)
            # propagate SRCS to parent directory
            set (SRCS ${SRCS} PARENT_SCOPE)
        endif()
    endmacro()
    
    add_sources(main.cpp)
    add_subdirectory(dir1)
    add_subdirectory(dir2)
    
    message(STATUS "${SRCS}")
    

    宏首先为每个参数计算源文件相对于项目根目录的路径。如果从项目子目录中调用宏,则需要使用 PARENT_SCOPE 选项将变量 SRCS 的新值传播到父文件夹。

    在子目录中,您可以简单地添加一个宏调用,例如在dir1/CMakeLists.txt 添加:

    add_sources(file1.cpp file2.cpp)
    

    并在dir2/CMakeLists.txt 添加:

    add_sources(file3.cpp file4.cpp)
    

    【讨论】:

    • 你确定没有开箱即用的东西来构建带有嵌套子目录的库吗??
    • @James 看到这个question的答案
    • 非常彻底和有用的答案。谢谢!
    • 我试过你的宏,如果我有一个顶级目录和一级子目录,它就可以正常工作。但是,它不适用于更多级别的嵌套,例如 .、./sub1 和 ./sub1/sub2。在这种情况下,sub2 正确地看到了 SRCS,sub1 也正确,但是顶部文件夹 (.) 只看到它自己的源和 sub1 中的源,没有 sub2... 结果我需要先做 add_subdirectory() 然后才调用 add_sources() - 这样就可以了。有什么办法可以避免这种行为?
    • 如果您有多个级别的嵌套目录,请使用 global property 而不是 CMake 变量。
    【解决方案2】:

    Michael Wild [1] 在 CMake 邮件列表中发布了一个类似于 sakra 建议的宏。它使用全局属性而不是向上传播变量。

    [1]http://www.cmake.org/pipermail/cmake/2010-March/035992.html

    【讨论】:

      【解决方案3】:

      在 dir1/CMakeLists.txt 中放这个:

      set(SRCS ${SRCS} file1.cpp PARENT_SCOPE)

      如果这不起作用,唯一的解决方案是

      set(DIR1_SRCS "file1.cpp" PARENT_SCOPE)

      然后在 ./CMakeLists.txt

      set(SRCS ${DIR1_SRCS} ${DIR2_SRCS})

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-29
        相关资源
        最近更新 更多