CMake:如何更改子目录项目目标的属性?
CMake: How do I change properties on subdirectory project targets?
我正在尝试在我的子项目中组织目标(在本例中为 poco(,但我发现无法为 ALIAS 目标修改属性。我希望外部项目中的目标位于它们自己的文件夹中,而不是分散在项目树中的任何位置(例如 Visual Studio 生成器(。有没有更简单的方法可以使用我自己的属性添加项目?
所以代替:
- 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 子模块的形式添加其他项目,但根据是否有更简单的方法,我将探索其他途径。
编辑:
澄清一下,我已经为我自己项目的每个模块使用了一个单独的 CMakeLists.txt以及一个顶级 CMakeLists.txt将它们联系在一起,以及收集我的目标所依赖的外部库。我想修改外部库的目标,而不必自己分叉和维护它们,这样我在Visual Studio,xcode或其他方面就有了很好的文件夹结构。Linux显然并不重要,因为大多数编辑工具已经基于文件夹。
我已经尝试了您的示例,这是我的两个变体:
-
使用
BUILDSYSTEM_TARGETS
和SUBDIRECTORIES
目录属性评估目录中"不包含任何导入的目标或别名目标"的目标名称列表: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)
-
通过将
FOLDER
目标属性转换为从同名目录属性继承的内容。这可以使用define_property()
将FOLDER
属性重新定义为INHERITED
:使用
INHERITED
选项,当请求的属性未在给定命令的范围内设置时,get_property(( 命令将链接到下一个更高的范围。DIRECTORY
范围链到GLOBAL
.TARGET
、SOURCE
和TEST
链到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 的未记录行为。
引用
目录- 属性和子目录
- 在CMake中等同于"make dist">
- 如何使用 cmake 为嵌套子目录设置 Visual Studio 筛选器
https://github.com/andry81/tacklelib
https://github.com/andry81/tacklelib/blob/master/cmake/tacklelib/Project.cmake
cmake_minimum_required(VERSION 3.14)
# enable project folders
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
## cmake builtin search paths and includes
LIST(APPEND CMAKE_MODULE_PATH "${TACKLELIB_CMAKE_ROOT}")
include(tacklelib/Project)
include(tacklelib/EnableTargetsExtension)
project(MyApp)
set(MYLIB_ROOT ...)
# somewhere at the end ...
## project folders
tkl_set_target_folder(CMAKE_CURRENT_LIST_DIR . * . UTILITY . util)
tkl_set_target_folder(CMAKE_CURRENT_LIST_DIR . * "tests" EXECUTABLE . exe)
tkl_set_target_folder(CMAKE_CURRENT_LIST_DIR . * . "SHARED_LIBRARY;STATIC_LIBRARY" . lib)
tkl_set_target_folder(MYLIB_ROOT * * . UTILITY . _3dparty/utility/mylib/util)
tkl_set_target_folder(MYLIB_ROOT * * "tests" EXECUTABLE . _3dparty/utility/mylib/exe)
tkl_set_target_folder(MYLIB_ROOT * * . "SHARED_LIBRARY;STATIC_LIBRARY" . _3dparty/utility/mylib/lib)
tkl_set_target_folder(MYLIB_ROOT * "tests" . * . _3dparty/utility/mylib/tests)
CMake 命令行:
cmake.exe -G "..." "-DTACKLELIB_CMAKE_ROOT=.../_externals/tacklelib/cmake" ...
项目目录结构:
...
_externals/
_out/
include/
src/
CMakeLists.txt
_out
- 具有 cmake 缓存和输出的目录
解决方案布局:
_3dparty
utility
mylib
lib
mylib
CMakePredefinedTargets
ALL_BUILD
INSTALL
ZERO_CHECK
exe
myapp
util
bundle
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++概念:如何使用'concept'检查模板化结构的属性?
- C++A*算法并不总是在路径中具有目标节点
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 通过指向指针数组的指针访问子类的属性
- MSVC是否支持C++11样式的属性而不是__declspec
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 为测试目标创建具有不同源文件夹的文件
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 类的C++属性似乎已重新初始化
- Qt Quick-如何仅从c++代码与qml属性交互
- 使用源向量作为目标
- CMake 错误 - 目标 foo INTERFACE_SOURCES属性包含在源目录中以前缀为前缀的路径
- CMake 设置使用不正确的参数数调用的目标属性
- CMake:如何更改子目录项目目标的属性?
- boost::msm 用法:如何设置目标状态的属性
- 当使用MSBuild目标文件时,查看vsc++项目中的有效属性
- 目标c属性到非托管c++
- CMake:何时使用 add_definitions 而不是 set_target_properties(目标属性COM