CMake 属性之目标属性

打印 上一主题 下一主题

主题 904|帖子 904|积分 2712

【写在前面】

CMake 可以通过属性来存储信息。它就像是一个变量,但它被附加到一些其他的实体上,像是一个目录大概是一个目标。例如一个全局的属性可以是一个有用的非缓存的全局变量。
在 CMake 的众多属性中,目标属性 ( Target Properties ) 扮演着尤为重要的角色,它们直接关联到终极天生的可执行文件、库文件等构建产物。
更直观一点,假如把目标类比为 类 ( Class ),那么目标属性则类似 类成员 ( Class  Member )
  1. class Target {
  2.     string target_property;
  3. };
复制代码
【正文开始】

天生目标的方式有三种:
  1. #生成可执行文件目标test
  2. add_executable(test test.cpp)
  3. #生成共享库目标test_lib
  4. add_library(test_lib SHARED test.cpp)
  5. #生成静态库目标test_lib
  6. add_library(test_lib STATIC test.cpp)
复制代码
定义目标属性:

给目标定义属性的命令为:
  1. define_property(<GLOBAL | DIRECTORY | TARGET | SOURCE |
  2.                  TEST | VARIABLE | CACHED_VARIABLE>
  3.                  PROPERTY <name> [INHERITED]
  4.                  [BRIEF_DOCS <brief-doc> [docs...]]
  5.                  [FULL_DOCS <full-doc> [docs...]]
  6.                  [INITIALIZE_FROM_VARIABLE <variable>])
复制代码
在范围内定义一个属性,用于 set_property() 和 get_property() 命令。它主要用于定义属性的初始化或继承方式。从汗青上看,该命令还将文档与属性相关联,但这不再被视为主要用例。
示例:
  1. # 定义一个目标属性 TEST_TARGET,带有简短和详细描述
  2. define_property(TARGET PROPERTY TEST_TARGET
  3.     BRIEF_DOCS "A test property"
  4.     FULL_DOCS "A long description of this test property"
  5. )
复制代码
设置目标属性:

给目标设置属性的命令为:
  1. set_property(<GLOBAL                      |
  2.               DIRECTORY [<dir>]           |
  3.               TARGET    [<target1> ...]   |
  4.               SOURCE    [<src1> ...]
  5.                         [DIRECTORY <dirs> ...]
  6.                         [TARGET_DIRECTORY <targets> ...] |
  7.               INSTALL   [<file1> ...]     |
  8.               TEST      [<test1> ...]     |
  9.               CACHE     [<entry1> ...]    >
  10.              [APPEND] [APPEND_STRING]
  11.              PROPERTY <name> [<value1> ...])
复制代码
在范围的零个或多个对象上设置一个属性。
假如给出 APPEND 选项,列表将附加到任何现有的属性值(除了忽略和不附加空值)。假如给出 APPEND_STRING 选项,字符串将作为字符串附加到任何现有属性值,即它会产生更长的字符串而不是字符串列表。当使用 APPEND 或 APPEND_STRING 以及定义为支持 INHERITED 举动的属性时(请参阅 :command:define_property),在找到要附加到的初始值时不会发生继承。假如该属性尚未在指定范围内直接设置,则该命令的举动就似乎没有给出 APPEND 或 APPEND_STRING 一样。
其中,有一个专用于设置目标属性命令:
  1. set_target_properties(target1 target2 ...
  2.                       PROPERTIES prop1 value1
  3.                       prop2 value2 ...)
复制代码
设置目标的属性。该命令的语法是列出您要更改的全部目标,然后提供您接下来要设置的值。您可以使用任何您想要的 prop 值对,稍后使用 get_property() 或 get_target_property() 命令提取它。
示例:
  1. # 设置目标 TEST_TARGET 的属性 P_1 和 P_2 的值
  2. set_target_properties(TEST_TARGET PROPERTIES
  3.     P_1 "这是属性P_1的值"
  4.     P_2 "这是属性P_2的值"
  5. )
复制代码
获取目标属性:

获取目标的属性的命令为:
  1. get_property(<variable>
  2.              <GLOBAL             |
  3.               DIRECTORY [<dir>]  |
  4.               TARGET    <target> |
  5.               SOURCE    <source>
  6.                         [DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
  7.               INSTALL   <file>   |
  8.               TEST      <test>   |
  9.               CACHE     <entry>  |
  10.               VARIABLE           >
  11.              PROPERTY <name>
  12.              [SET | DEFINED | BRIEF_DOCS | FULL_DOCS])
复制代码
从范围内的一个对象获取一个属性。
假如给出了 SET 选项,变量将被设置为一个布尔值,指示该属性是否已被设置。假如给出了 DEFINED 选项,变量将被设置为一个布尔值,指示该属性是否已被定义,例如使用 define_property 命令。 假如给出了BRIEF_DOCS 或 FULL_DOCS,那么该变量将被设置为一个字符串,其中包含所请求属性的文档。假如为尚未定义的属性请求文档,则返回 “NOTFOUND”。
其中,有一个专用于获取目标属性命令:
  1. get_target_property(<VAR> target property)
复制代码
从目标获取属性。属性的值存储在变量“”中。假如未找到目标属性,则举动取决于它是否已被定义为 INHERITED 属性(请参阅:command:define_property)。非继承属性会将设置为-NOTFOUND,而继承属性将搜刮相关的父范围,如 define_property() 命令所述,假如仍然找不到属性  将被设置为空字符串。
使用 set_target_properties() 设置目标属性值。属性通常用于控制目标的构建方式,但有些属性会查询目标。此命令可以获得迄今为止创建的任何目标的属性。目标不需要位于当前的 CMakeLists.txt 文件中。
示例:
  1. # 获取目标 TEST_TARGET 的属性 P_1 的值,并将其存储在变量 TEST_TARGET_P1 中
  2. get_target_property(TEST_TARGET_P1 TEST_TARGET P_1)
复制代码
最后完备测试一遍:
  1. # 要求 CMake 最低版本为 3.16cmake_minimum_required(VERSION 3.16)# 定义项目名称为 PROPERTY_TEST,版本号为 1.0,使用 C++ 语言project(PROPERTY_TEST VERSION 1.0 LANGUAGES CXX)# 添加一个名为 TEST_TARGET 的可执行文件,其源文件为 test.cppadd_executable(TEST_TARGET test.cpp)# 定义一个目标属性 TEST_TARGET,带有简短和详细描述
  2. define_property(TARGET PROPERTY TEST_TARGET
  3.     BRIEF_DOCS "A test property"
  4.     FULL_DOCS "A long description of this test property"
  5. )# 设置目标 TEST_TARGET 的属性 P_1 和 P_2 的值
  6. set_target_properties(TEST_TARGET PROPERTIES
  7.     P_1 "这是属性P_1的值"
  8.     P_2 "这是属性P_2的值"
  9. )# 获取目标 TEST_TARGET 的属性 P_1 的值,并将其存储在变量 TEST_TARGET_P1 中
  10. get_target_property(TEST_TARGET_P1 TEST_TARGET P_1) # 打印变量 TEST_TARGET_P1 的值message("TEST_TARGET_P1: ${TEST_TARGET_P1}")
复制代码
CMake 输出如下:

【结语】

最后,属性在 CMake 中是可继承的。这意味着,假如一个目标继承了另一个目标的属性,那么它将自动获得父目标的属性值。这种继承关系在构建大型项目时非常有用,由于它淘汰了重复的配置。
CMake 的属性系统是一个强大的工具,它提供了细粒度的控制,答应我们定制构建过程。通过合理使用属性,我们可以创建更加机动和可维护的构建系统。掌握属性的使用,是每个 CMake 用户进阶的必经之路,希望这篇文章能够帮助你更好地理解和使用 CMake 的属性系统。
项目链接(多多star呀..⭐_⭐):
Github 地址:https://github.com/mengps/LearnCMake

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表