2017-07-13 157 views
4

我想在我的子项目(在这种情况下,poco)组织目标,但我已经发现,无法修改ALIAS目标的属性。我希望我的外部项目中的目标位于它们自己的文件夹中,而不是蔓延到项目树中的任何地方(比如Visual Studio生成器)。有没有更容易的方法来添加我自己的属性项目?CMake:如何更改子目录项目目标上的属性?

所以不是:

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

我想:

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

我尝试:

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 
    ) 
:从POCO库

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) 

实例目标

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

编辑:

为了澄清,我已经使用一个单独的CMakeLists.txt为自己的项目的每个模块,再加上顶级的CMakeLists.txt它关系到他们在一起,以及收集外部库我的目标依赖。我想修改外部库的目标,而不必自己分叉和维护它们,这样我就可以在Visual Studio,xcode或其他程序中拥有漂亮的文件夹结构。 Linux显然并不重要,因为大多数编辑工具都是基于文件夹的。

+1

可以在每个目录添加的CMakeLists.txt如果你想。为每个项目创建一个,并包含主目录中的目录。 – skypjack

+0

@skypjack,你误会了。在我自己的项目中,我已经这样做了,但是我想修改别人项目的属性而不修改项目本身。当我需要它时,不需要为Poco分配生命的质量。 – BleuGamer

回答

3

我已经给你举例一个尝试,这里有我的两个变种:

  1. 使用BUILDSYSTEM_TARGETSSUBDIRECTORIES目录属性目录中的评估对象的名单是“不包括任何进口目标或别名目标“:

    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目标属性到从同名的目录财产继承的东西。

    随着INHERITED选项get_property()命令将链到下一个较高的范围,当所请求的属性没有在给定的范围设定:这可以使用define_property()重新定义FOLDER属性作为INHERITED来完成命令。 DIRECTORY范围链到GLOBALTARGET,SOURCETEST链到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的无证行为。

参考

+0

第一个选项不起作用,但第二个选项正是我想要的。最终,我会将这些转移到/cmake模块以获得更多控制权,但这是一个很好的开始。谢谢! – BleuGamer

+0

@BleuGamer不客气。你使用哪个版本的CMake?第一个选项至少需要CMake版本3.7。第二个版本的优点在于,该目录属性会自动传播到子目录。 – Florian

+0

@BleuGamer更新了第一个选项以迭代子目录。 – Florian