如何复制cmake目标

2024-03-11

我正在我的 cmake 项目中编写函数,该函数需要从一个目标创建两个目标,并稍微更改其中之一:

option(BORG_STRIP_TEST_BINARIES OFF "Strip symbols from test binaries to reduce disk space usage" )
function(add_borg_test target)
    add_test(${target} ${target} --gtest_color=yes)
    if(BORG_STRIP_TEST_BINARIES)
        # copy target, but make it optional
        duplicate_target(FROM ${target} TO ${target}_debug )
        set_target_properties(${target}_debug PROPERTIES EXCLUDE_FROM_ALL TRUE)
        # alter
        target_link_options(${target} PRIVATE -s)
    endif()
endfunction()

所以这应该是这样工作的:

  1. 我创建使用 gtest 的二进制目标。设置全部target_link_libraries和所有。示例名称example-utests
  2. 相反添加通用add_test,我用的是自定义的add_borg_test
  3. now example-utests带有标志的链接-s并包含在all target.
  4. example-utests_debug不包括在all目标,但当明确请求时,它会链接而不-s.

如何实施duplicate_target从上面的代码片段?


我的第一直觉(抱歉)是质疑为什么要这样做。我不是你,我不知道你的背景,所以问问自己:你是吗?sure您是否认为仅通过生成多个构建系统并为每个构建系统指定单独的配置选项无法实现您想要的目标?毕竟,CMake 的整个设计就是为了让生成构建系统变得容易。


话虽这么说,如果您确信您有充分的理由想要复制/克隆/重复目标定义在同一个构建系统中,然后按照 Brad King(CMake 维护者之一)的建议进行操作这个邮件线程 https://cmake.org/pipermail/cmake-developers/2017-March/029902.html:

尽管您可以这样做,但没有内置的方法可以做到这一点 接近从读取目标属性的宏 原始的以便使用适当的命令重现它们。

它可能会有助于利用如何获取目标的所有属性 https://stackoverflow.com/q/69761538/11107541。请注意,我在我的回答帖子中列出了一些重大限制。我所知道的最佳解决方案仅允许读取内置到 CMake 的目标属性,而不允许读取您或任何其他 CMake 配置代码自定义定义的任何属性。因此,同样的限制也适用于这里的解决方案,大致如下:

execute_process(COMMAND "${CMAKE_COMMAND}" "--help-property-list" "${CMAKE_BINARY_DIR}/--help-property-list.txt")
file(STRINGS "${CMAKE_BINARY_DIR}/--help-property-list.txt" property_list)
function(copy_target_props src_target dest_target)
  set(config_types "${CMAKE_CONFIGURATION_TYPES}")
  if(NOT DEFINED CMAKE_CONFIGURATION_TYPES)
    set(config_types "Release;Debug;RelWithDebInfo;MinSizeRel")
  endif()
  foreach(prop_name ${property_list})
    if("${prop_name}" MATCHES "(^LOCATION)|^VS_DEPLOYMENT_LOCATION$|^MACOSX_PACKAGE_LOCATION$|^CXX_MODULE_SETS$|^HEADER_SETS$|^IMPORTED_GLOBAL$|^INTERFACE_CXX_MODULE_SETS$|^INTERFACE_HEADER_SETS$|^NAME$|^TYPE$")
      continue()
    endif()
    if("${prop_name}" MATCHES "<CONFIG>")
      foreach(config ${config_types})
        string(REPLACE "<CONFIG>" "${config}" config_prop_name "${prop_name}")
        get_target_property(prop_val "${src_target}" "${config_prop_name}")
        if(NOT "${prop_val}" STREQUAL "prop_val-NOTFOUND")
          #message("${config_prop_name}: ${prop_val}")
          set_property(TARGET "${dest_target}" PROPERTY "${config_prop_name}" "${prop_val}")
        endif()
      endforeach()
    else()
      get_target_property(prop_val "${src_target}" "${prop_name}")
      if(NOT "${prop_val}" STREQUAL "prop_val-NOTFOUND")
        #message("${prop_name}: ${prop_val}")
        set_property(TARGET "${dest_target}" PROPERTY "${prop_name}" "${prop_val}")
      endif()
    endif()
  endforeach()
  set(prop_name "IMPORTED_GLOBAL")
  get_target_property(prop_val "${src_target}" "${prop_name}")
  if((NOT "${prop_val}" STREQUAL "prop_val-NOTFOUND") AND "${prop_val}")
    #message("${config_prop_name}: ${prop_val}")
    set_property(TARGET "${dest_target}" PROPERTY "${prop_name}" "${prop_val}")
  endif()
endfunction()

# example usage
add_executable(foo1 foo.c)
add_executable(foo2)
copy_target_props(foo1 foo2)

我太懒了,无法编写一个不需要手动定义第二个目标的实际复制函数。但你可以通过阅读目标来做到这一点TYPE源目标的属性,然后对所有add_executable/add_library变体(首次定义目标后无法更改目标的类型(source https://stackoverflow.com/a/76078866/11107541)).


还有另一种适用性有限的技术 - 与其说是用于复制目标,不如说是为了使公共目标属性设置可重用(同样,适用性有限):在接口库 https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries,然后将多个相似的目标链接到接口目标,以便它们继承接口目标的值。


最后一点:我有一个项目,我使用 CMake 来驱动 PGO 两个阶段的训练和优化构建,我在其中创建了项目ExternalProject本身,并为训练和使用阶段定义了两个自定义构建配置,这需要不同的编译标志。也就是说(毫无帮助),您所采取的方法的适用性取决于具体情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何复制cmake目标 的相关文章

随机推荐

  • 单击提交时验证文本区域

    我正在开发允许用户向系统发送反馈的网站 我使用文本区域和提交按钮创建了反馈表 最重要的是 当用户点击提交时 如果用户输入了一些我不希望他们输入的单词 该反馈将不会发送到系统 它会提醒用户在点击提交之前删除该单词 从现在开始 我只是创建一个简
  • 数据库中的最佳货币格式

    在我的数据库中与 ASP NET Web 应用程序结合使用的最佳货币格式是什么 我不确定浮点数和小数哪个更好 请注意 我不需要特定于文化的设置 如果您使用的是 SQL Server 则您拥有 money 类型 它会转换为 NET 中的十进制
  • 条件成员函数

    关于在 C 类中条件定义成员函数的建议是什么 问题集中在限制 DLL 中某些类的外部暴露 特别是当这些类作为参数传入时 显然这不是您想要对数据成员做的事情 但是函数应该没问题 不是吗 例如 class A public void func1
  • django 中的自定义 404 和 500 页面 -> DEBUG = True

    我想向客户展示我的网站示例 它还没有完全完成 但是对我来说隐藏错误并且不显示我的代码库非常重要 如果在开发模式下发生服务器错误 django 会执行哪些操作 就像这样 Django 描述出了什么问题 https i stack imgur
  • D3.js 中的日期格式

    我在 csv 中有一个列 日期 它将日期存储在 2003 02 01 年月日 中 我想将日期格式化为月份和年份 例如 2003 年 4 月 我该怎么做 var format d3 time format m Y data forEach f
  • 除了网站之外,还有 Webpack splitchunks.name 作为功能文档吗?

    随着 webpack 4 的引入 splitChunks name用于定义分割块的名称 在这里 文档说可以将键映射到自定义命名的函数 https webpack js org plugins split chunks plugin spli
  • C# 接口实现 - 为什么这不能构建?

    抱歉 如果之前有人问过这个问题 但实际上不可能用谷歌搜索 我认为 int 数组实现了 IEnumerable 因此 Thing 应该能够实现 IThing 怎么没有呢 public interface IThing IEnumerable
  • 普遍的 SQL 查询

    是否有人有一个查询来搜索 Pervasive 数据库中所有表中的所有列以获取特定值 我正在努力寻找有关此的任何信息 在 sql server 中似乎很容易做到 但在 Pervasive 中则不然 返回按表名排序的所有表的列表 按 xf na
  • IntelliJ IDEA 中的 JSP 调试

    有谁知道如何调试JSP in IntelliJ IDEA 当我在我的中设置断点时JSP文件中 这些断点似乎从未生效 调试器永远不会碰到它们 IDEA 似乎认为断点是有效的 我确实看到一个红点放置在我放置断点的行的左侧 我在 IntelliJ
  • Apache Thrift 中的对称加密 (AES)

    我有两个使用 Thrift 进行交互的应用程序 他们共享相同的密钥 我需要加密他们的消息 使用对称算法 例如 AES 是有意义的 但我还没有找到任何库来执行此操作 所以我做了一个研究并看到了以下选项 使用内置 SSL 支持 我可以使用内置的
  • 在 python 中查找并替换多个值

    我想查找一维数组 列表中的多个值并将其替换为新值 以列表为例 a 2 3 2 5 4 4 1 2 我想更换 val old 1 2 3 4 5 with val new 2 3 4 5 1 因此新数组是 a new 3 4 3 1 5 5
  • 覆盖 Eclipse 中的重命名操作

    I am new to eclipse plugin development I am in the need of overriding the rename dialog for the files in a specific cust
  • 管理二进制版本

    我正在寻找有关如何管理共同构成发行版本的二进制文件工件的工具和建议 该项目如下所示 Package Version Component A Version Component B Version Component C Version 可能
  • Laravel 4 - 验证器 - 文件大小

    只是询问有关 Laravels 验证器的问题 我网站的用户有时会上传大约 100MB 的文件 我看过 http laravel com docs 4 2 validation http laravel com docs 4 2 valida
  • 如何创建固定结构的对象?

    我的揭示模块中有以下代码 但我不确定如何声明 定义imageListItem 这严格来说是一个 DTO 并不真正需要任何信息隐藏 我是否正确定义了这个对象 var imageListItem function var title Objec
  • Gorilla Sessions - 如何根据请求自动更新 Cookie 过期时间?

    我知道许多其他语言和 Web 框架会在每次通过后端访问会话 或类似的操作 时自动将 cookie 的过期时间更新为会话超时 我不相信 Gorilla 提供这个实用程序 我正在考虑编写一些请求中间件 如果它检测到有效会话 将延长 cookie
  • jQuery 事件未触发

    我一直在努力让它发挥作用 基本上我有一个搜索框 其中有一个默认字符串 即搜索 当用户单击输入字段时它应该消失 这是代码 HTML
  • 构建 MAUI Android 失败

    我创建了一个全新的 MAUI 应用程序 我必须创建一个新应用程序 因为当我升级 Visual Studio 预览版时 我使用预览版本创建的先前应用程序无法工作 这个应用程序使用 prism maui 这应该没有任何区别 我还使用使用预览版本
  • 即使明确设置,PreparedStatement 也不会超时

    我正在尝试模拟一个场景 其中我的服务失去与数据库的连接并且无法执行INSERT通过阻止与 iptables 的连接 但我无法使executeQuery 方法超时 我所做的是为PreparedStatement设置一个超时 如下所示state
  • 如何复制cmake目标

    我正在我的 cmake 项目中编写函数 该函数需要从一个目标创建两个目标 并稍微更改其中之一 option BORG STRIP TEST BINARIES OFF Strip symbols from test binaries to r