CMake:如何更改子目录项目目标的属性?

时间:2017-07-13 23:03:32

标签: c++ cmake poco-libraries build-tools

我试图在我的子项目中组织目标(在这种情况下是poco),但我发现不能为ALIAS目标修改属性。我希望我的外部项目中的目标位于他们自己的文件夹中,而不是在项目树中的任何地方蔓延(比如可视工作室生成器)。有没有更简单的方法来添加具有我自己的属性的项目?

所以而不是:

- CMakePredefinedTargets
    - ALL_BUILD
    - INSTALL
    - ...
- MyTargets
    - SomeLibrary
    - SomeExe
- CppUnit
- Crypto
- Data
- ...

我想:

- CMakePredefinedTargets
    - ALL_BUILD
    - INSTALL
    - ...
- MyTargets
    - SomeLibrary
    - SomeExe
- Poco
    - CppUnit
    - Crypto
    - Data
    - ...

我的尝试:

function(add_subdirectory_with_folder folder_name)
    function(add_library name type)
    _add_library(${ARGV})

    set_target_properties(${name}
        PROPERTIES
        FOLDER "${folder_name}"
    )
    endfunction()
    add_subdirectory(${ARGN})
endfunction()

# External Libs
add_subdirectory_with_folder("Poco" libs/poco)

来自poco库的示例目标:

add_library( "${LIBNAME}" ${LIB_MODE} ${SRCS} )
add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}")
set_target_properties( "${LIBNAME}"
    PROPERTIES
    VERSION ${SHARED_LIBRARY_VERSION} SOVERSION ${SHARED_LIBRARY_VERSION}
    OUTPUT_NAME ${POCO_LIBNAME}
    DEFINE_SYMBOL JSON_EXPORTS
    )

我的目标是做到这一点,所以我不必分叉和维护我想要用于生活质量调整的我自己的库版本。我可以使用不同的方法来组织IDE的项目树吗?我知道externalproject_add存在,但我不认为这有我正在寻找的设施。我将在未来以git-submodules的形式添加其他项目,但是根据是否有更简单的方法,我将探索其他途径。

编辑:

为了澄清,我已经为我自己项目的每个模块使用了单独的CMakeLists.txt,还有一个顶级的CMakeLists.txt,它们将它们连接在一起,以及收集我的目标所依赖的外部库。我想修改外部库的目标,而不必自己分叉和维护它们,因此我在visual studio,xcode或其他方面有很好的文件夹结构。 Linux显然并不重要,因为大多数编辑工具都是基于文件夹的。

1 个答案:

答案 0 :(得分:5)

我试试了你的例子,这是我的两个变种:

  1. 使用BUILDSYSTEM_TARGETSSUBDIRECTORIES目录属性来评估目录中的目标名称列表,其中不包含任何导入的目标或别名目标&#34;:< / p>

    cmake_minimum_required(VERSION 3.7)
    
    project(AliasFolderSub)
    
    set_property(GLOBAL PROPERTY USE_FOLDERS TRUE)
    
    function(get_all_targets _result _dir)
        get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
        foreach(_subdir IN LISTS _subdirs)
            get_all_targets(${_result} "${_subdir}")
        endforeach()
        get_property(_sub_targets DIRECTORY "${_dir}" PROPERTY BUILDSYSTEM_TARGETS)
        set(${_result} ${${_result}} ${_sub_targets} PARENT_SCOPE)
    endfunction()
    
    function(add_subdirectory_with_folder _folder_name _folder)
        add_subdirectory(${_folder} ${ARGN})
        get_all_targets(_targets "${_folder}")
        foreach(_target IN LISTS _targets)
            set_target_properties(
                ${_target}
                PROPERTIES FOLDER "${_folder_name}"
            )
        endforeach()
    endfunction()
    
    # External Libs
    add_subdirectory_with_folder("Poco" libs/poco)
    
  2. 通过将FOLDER目标属性转换为从同名目录属性继承的内容。可以使用define_property()FOLDER属性重新定义为INHERITED来完成此操作:

      

    使用INHERITED选项时,如果未在命令的作用域中设置所请求的属性,则get_property()命令将链接到下一个更高的作用域。 DIRECTORY范围链到GLOBALTARGETSOURCETEST链到DIRECTORY

    cmake_minimum_required(VERSION 2.6)
    
    project(AliasFolderSub)
    
    set_property(GLOBAL PROPERTY USE_FOLDERS TRUE)
    define_property(
        TARGET
        PROPERTY FOLDER
        INHERITED
        BRIEF_DOCS "Set the folder name."
        FULL_DOCS  "Use to organize targets in an IDE."
    )
    
    function(add_subdirectory_with_folder _folder_name _folder)
        add_subdirectory(${_folder} ${ARGN})
        set_property(DIRECTORY "${_folder}" PROPERTY FOLDER "${_folder_name}")
    endfunction()
    
    # External Libs
    add_subdirectory_with_folder("Poco" libs/poco)
    

    :使用define_property()重新定义现有属性的范围是CMake的无证行为。

  3. <强>参考