CMake中add_custom_command的使用

news2024/11/19 23:21:38

      CMake中的add_custom_command命令用于将自定义构建规则添加到生成的构建系统(Add a custom build rule to the generated build system),其格式如下:

add_custom_command(OUTPUT output1 [output2 ...]
                   COMMAND command1 [ARGS] [args1...]
                   [COMMAND command2 [ARGS] [args2...] ...]
                   [MAIN_DEPENDENCY depend]
                   [DEPENDS [depends...]]
                   [BYPRODUCTS [files...]]
                   [IMPLICIT_DEPENDS <lang1> depend1
                                    [<lang2> depend2] ...]
                   [WORKING_DIRECTORY dir]
                   [COMMENT comment]
                   [DEPFILE depfile]
                   [JOB_POOL job_pool]
                   [VERBATIM] [APPEND] [USES_TERMINAL]
                   [COMMAND_EXPAND_LISTS]) # Generating Files

add_custom_command(TARGET <target>
                   PRE_BUILD | PRE_LINK | POST_BUILD
                   COMMAND command1 [ARGS] [args1...]
                   [COMMAND command2 [ARGS] [args2...] ...]
                   [BYPRODUCTS [files...]]
                   [WORKING_DIRECTORY dir]
                   [COMMENT comment]
                   [VERBATIM] [USES_TERMINAL]
                   [COMMAND_EXPAND_LISTS]) # Build Events

      1.Generating Files:添加自定义命令以生成输出。这定义了生成指定输出文件的命令。
      选项包括:
      (1).APPEND:将COMMAND和DEPENDS选项值附加到指定的第一个输出的自定义命令。之前必须已经调用过具有相同输出的此命令。
      (2).BYPRODUCTS:指定命令预期生成的文件。如果副产品(byproduct)名是相对路径,它将相对于当前源目录相对应的构建树目录进行解释。每个副产品文件都将自动标记为GENERATED源文件属性。
      (3).COMMAND:指定要在构建时执行的命令行。如果指定了多个COMMAND,它们将按顺序执行,但不一定组成有状态的shell或batch脚本。可选的ARGS参数是为了向后兼容。
      (4).COMMENT:在构建时执行命令之前显示给定的消息。
      (5).DEPENDS:指定命令所依赖的文件。每个参数都转换为依赖项。如果未指定DEPENDS,则只要缺少OUTPUT,该命令就会运行;如果该命令实际上并未创建OUTPUT,则该规则将始终运行。
      (6).COMMAND_EXPAND_LISTS:COMMAND参数中的列表(list)将被扩展。
      (7).IMPLICIT_DEPENDS:请求扫描输入文件的隐式依赖项。给定的语言指定应使用其相应依赖扫描器的编程语言(programming language).目前仅支持C和CXX语言扫描器。必须为IMPLICIT_DEPENDS列表中的每个文件指定语言。IMPLICIT_DEPENDS选项目前仅支持Makefile生成器,其它生成器将忽略该选项。
      此选项不能与DEPFILE选项同时指定。
      (8).JOB_POOL:为Ninja生成器指定一个池(pool).
      (9).MAIN_DEPENDENCY:指定命令的主要输入源文件。每个源文件最多可以有一个命令将其指定为其主要依赖项。编译命令(即用于库或可执行文件)算作隐式主要依赖项,它会被自定义命令规范悄悄覆盖。
      (10).OUTPUT:指定命令预期生成的输出文件。如果输出名是相对路径,它将相对于当前源目录相对应的构建树目录进行解释。每个输出文件都将自动标记为GENERATED源文件属性。如果自定义命令的输出实际上并未创建为磁盘上的文件,则应使用SYMBOLIC源文件属性对其进行标记。
      (11).USES_TERMINAL:如果可能,该命令将被授予直接访问终端(terminal)的权限。
      (12).VERBATIM:命令的所有参数都将为构建工具正确转义(escaped),以便调用的命令接收每个参数不变。建议使用VERBATIM,因为它可以实现正确的行为。当没有给出VERBATIM时,行为是特定于平台的。
      (13).WORKING_DIRECTORY:使用给定的当前工作目录执行命令。如果是相对路径,会被解释为相对于当前源目录对应的构建树目录。
      (14).DEPFILE:指定一个包含自定义命令依赖项的depfile。它通常由自定义命令本身发出。这个关键字只能在生成器支持的情况下使用。
      DEPFILE不能与Makefile Generators的IMPLICIT_DEPENDS选项同时指定。

message("##CMAKE_COMMAND: ${CMAKE_COMMAND}") # ## CMAKE_COMMAND: /usr/bin/cmake
# 只有在构建时add_custom_command才会真正生效,解析cmake阶段只会判断有无语法错误,在调用add_library命令时才会有xxx.cpp, main.cpp文件生成
# 在build目录下会生成xxx.cpp, main.cpp文件
# add.cpp的md5和COMMENT信息会直接在终端输出
add_custom_command(
    OUTPUT xxx.cpp main.cpp
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp xxx.cpp
    COMMAND ${CMAKE_COMMAND} -E md5sum ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/samples/sample_add.cpp main.cpp
    COMMENT "**** test cmake command: add_custom_command"
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp
    VERBATIM
)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(add SHARED xxx.cpp)
add_executable(main main.cpp)
target_link_libraries(main add)

      2.Build Events:将自定义命令添加到target,如库或可执行文件.这对于在构建target之前或之后执行操作非常有用。该命令将成为target的一部分,并且仅在构建target本身时执行如果target已构建,则不会执行该命令
      这将定义一个新命令,该命令将与构建指定的<target>关联。<target>必须在当前目录中定义;不能指定在其它目录中定义的target。
      命令何时发生取决于指定以下哪项:
      (1).PRE_BUILD:在Visual Studio Generators上,在target中执行任何其它规则之前运行。在其它生成器(generator)上,在PRE_LINK命令之前运行。
      (2).PRE_LINK:在编译源代码之后但在链接二进制文件(binary)或运行静态库的库管理员(librarian)或存档器工具(archiver tool)之前运行。这不是为add_custom_target命令创建的target定义的。
      (3).POST_BUILD:在执行target中的所有其它规则后运行。
      使用TARGET格式时,project应始终指定上述三个关键字之一。出于向后兼容性(backward compatibility)的原因,如果没有给出这样的关键字,则假定为POST_BUILD,但project应明确提供其中一个关键字以明确他们期望的行为。

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(add SHARED ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp)

# 在执行add_custom_command前target add已存在,否则会报error: No TARGET 'add' has been created in this directory
# add.cpp的md5和COMMENT信息会直接在终端输出
add_custom_command(TARGET add POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E md5sum ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp
    COMMENT "**** test cmake command: add_custom_command"
    VERBATIM
)

      执行测试代码需要多个文件

      build.sh内容如下:

#! /bin/bash

# supported input parameters(cmake commands)
params=(function macro cmake_parse_arguments \
		find_library find_path find_file find_program find_package \
		cmake_policy cmake_minimum_required project include \
		string list set foreach message option if while return \
		math file configure_file \
		include_directories add_executable add_library target_link_libraries install \
		target_sources add_custom_command add_custom_target)

usage()
{
	echo "Error: $0 needs to have an input parameter"

	echo "supported input parameters:"
	for param in ${params[@]}; do
		echo "  $0 ${param}"
	done

	exit -1
}

if [ $# != 1 ]; then
	usage
fi

flag=0
for param in ${params[@]}; do
	if [ $1 == ${param} ]; then
		flag=1
		break
	fi
done

if [ ${flag} == 0 ]; then
	echo "Error: parameter \"$1\" is not supported"
	usage
	exit -1
fi

if [[ ! -d "build" ]]; then
	mkdir build
	cd build
else
	cd build
fi

echo "==== test $1 ===="

# test_set.cmake: cmake -DTEST_CMAKE_FEATURE=$1 --log-level=verbose ..
# test_option.cmake: cmake -DTEST_CMAKE_FEATURE=$1 -DBUILD_PYTORCH=ON ..
cmake -DTEST_CMAKE_FEATURE=$1 ..
# It can be executed directly on the terminal, no need to execute build.sh, for example: cmake -P test_set.cmake
make
# make install # only used in cmake files with install command

      CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.22)
project(cmake_feature_usage)

message("#### current cmake version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}")
include(test_${TEST_CMAKE_FEATURE}.cmake)
message("==== test finish ====")

      test_add_custom_command.cmake内容为上面的所有测试代码段。

      另外还包括三个目录:include,source,samples,它们都是非常简单的实现,仅用于测试,如下:

      可能的执行结果如下图所示: 

      GitHub: https://github.com/fengbingchun/Linux_Code_Test

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/72118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【多线程(五)】volatile关键字、原子性问题、AtomicInteger内存分析与源码分析、悲观锁和乐观锁

文章目录5.原子性5.1 volatile-问题2.2 volatile解决5.3 synchronized 解决5.4 原子性5.5 volatile关键字不能保证原子性5.6 原子性 AtomicInteger5.7 AtomicInteger-内存解析5.8 AtomicInteger-源码解析5.9 悲观锁和乐观锁小结5.原子性 5.1 volatile-问题 代码分析 package…

五道LeetCode《中等难度》的单链表题

五道单链表中等难度题型1. 剑指 Offer II 021. 删除链表的倒数第 n 个结点第一种解法&#xff08;单指针&#xff09;&#xff1a;第二种解法(栈)&#xff1a;第三种解法&#xff08;双指针&#xff09;&#xff1a;2. 删除排序链表中的重复元素 II&#xff08;重点&#xff09…

利用VGG16网络模块进行迁移学习实现图像识别

​ ImageNet虽然带有”Net“&#xff0c;但他不是一种深度神经网络模型&#xff0c;它是个数据集&#xff0c;斯坦福大学教授李飞飞带头建立&#xff0c;是目前图像分类、检测、定位的最常用数据集之一。该数据集含大量数据1500万图片&#xff0c;2.2万类别&#xff0c;真彩图&…

PPT免费放送|Zabbix峰会结束了?还有件儿事!

精彩的Zabbix峰会成功举办&#xff0c;这并不意味着学习交流结束&#xff0c;还有件儿事——17份PPT免费获取&#xff0c;网盘见文末。干货满满细细品味。也欢迎你留言评价&#xff01; 值得一提的是&#xff1a;峰会中有理有据说明&#xff1a;Zabbix支持信创。开源免费的Zab…

IBDP学生如何申请中国香港的大学?

作为世界上最具竞争力的城市之一&#xff0c;香港拥有一些亚洲乃至世界上最好的大学。当然&#xff0c;这也使得香港成为内地学生以及国际留学生最喜爱的留学目的地之一。中国香港的教育在很大程度上是模仿英国的教育体系&#xff0c;但本科课程通常是英国和美国体系的混合体。…

Android 中的广播机制

一、Android广播概念&#xff1a; 在Android中&#xff0c;有一些操作完成以后&#xff0c;会发送广播&#xff0c;Android系统内部产生这些事件后广播这些事件&#xff0c;至于广播接收对象是否关心这些事件&#xff0c;以及它们如何处理这些事件&#xff0c;都由广播接收对象…

(附源码)ssm日语学习系统 毕业设计 271621

基于ssm日语学习系统 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对日语学习等问题&#…

MySQL——表的内容增删查改

文章目录表的增删改查一、Create1、单行全列插入2、多行数据指定列插入3、插入否则更新4、替换二、Retrieve&#x1f60a;(重点)2.1 select 列2.1.1 全列查询2.1.2 指定列查询2.1.3 查询字段为表达式2.1.4 为查询结果指定别名2.1.5 结果去重2.2 where查询2.3 结果排序2.4 筛选分…

【VC7升级VC8】将vCenter Server 7.X 升级为 vCenter Server 8 (下)—— 升级步骤说明

目录前文说明3. 第一阶段升级&#xff08;1&#xff09;点击【升级】&#xff08;2&#xff09;升级介绍&#xff08;3&#xff09;最终中用户许可协议&#xff08;4&#xff09;连接到源设备&#xff08;5&#xff09;VC7与ESXi 证书警告&#xff08;6&#xff09;vCenter Ser…

【Vue】各种loader的基本配置与使用

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 目录webpack中的loader  loader概述  打包处理css文件  打包处理less文件  打包处理图片  …

LWIP框架

目录 协议栈分层思想 1. 网络接口层 2. 网络层 3. 传输层 4. 应用层 进程模型 单进程模型 协议栈编程接口 1、Raw/Callback API 2、Netconn API 3、Socket API 协议栈分层思想 TCP/IP协议完整的包含了一系列构成互联网基础的网络协议&#xff0c;TCP/IP协议的开发出…

HTTP Digest Authentication 使用心得

简介 浏览器弹出这个原生的对话框&#xff0c;想必大家都不陌生&#xff0c;就是 HTTP Baisc 认证的机制。 这是浏览器自带的&#xff0c;遵循 RFC2617/7617 协议。但必须指出的是&#xff0c;遇到这界面&#xff0c;不一定是 Basic Authentication&#xff0c;也可能是 Dige…

墨门云终端行为趋势报表,泄密风险提前预警

事件响应滞后&#xff0c;事后再补救&#xff0c;为时晚矣&#xff0c;据IBM的数据泄露成本报告显示&#xff0c;加强风险监测可更快发现数据泄露行为&#xff0c;有效降低企业的数据泄露成本&#xff0c;可见建立完善的风险预警响应机制&#xff0c;可以避免更大的损失&#x…

5G无线技术基础自学系列 | NSA组网场景下移动性管理

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 NSA组网场景下移动性管理涉及的相关概念…

js操作二进制数据

使用ArrayBuffer对象保存二进制数据&#xff0c;使用TypedArray和DataView 视图来读写数据。 ArrayBuffer代码内存中的一段数据 const buff new ArrayBuffer(4)这样就创建了一个4(byte)字节的长度的内存判断&#xff0c;初始值都为0 注&#xff1a;一般中文占2个字节&#xff…

葡聚糖修饰Hrps共价三聚肽|葡聚糖修饰CdSe量子点

葡聚糖修饰Hrps共价三聚肽|葡聚糖修饰CdSe量子点 葡聚糖修饰Hrps共价三聚肽 中文名称&#xff1a;葡聚糖修饰Hrps共价三聚肽 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 外观:固体或粘性液体 包装&#xff1a;瓶装/袋装 溶解性&am…

爆火的 ChatGPT 会让客服岗位消失吗?

近日&#xff0c;由 OpenAI 推出的 ChatGPT 在全球互联网爆火。具体有多火呢&#xff1f;根据 OpenAI 的 CEO Sam Altman 的说法&#xff1a;上周三才上线的 ChatGPT&#xff0c;短短几天&#xff0c;用户数已突破 100 万大关。 那么&#xff0c;ChatGPT 是什么呢&#xff1f;…

无线充电智能车的制作

本文素材来源于宁夏大学 作者&#xff1a;白二曹、王瑞、穆琴、王童兵 指导老师&#xff1a;康彩 一、项目简介 1.功能介绍 无线充电智能车由无线充电、自动控制、红外遥控、网页显示四部分组成。 &#xff08;1&#xff09;流程描述 用户端浏览器访问http://127.0.0.1页面…

Cy5.5 Tyramide,Cyanine5.5 Tyramide,花青素Cy5.5 酪酰胺化学试剂供应

一&#xff1a;产品描述 1、名称 英文&#xff1a;Cy5.5 Tyramide&#xff0c;Cyanine5.5 Tyramide 中文&#xff1a;花青素Cy5.5 酪酰胺 2、CAS编号&#xff1a;N/A 3、所属分类&#xff1a;Cyanine 4、分子量&#xff1a;738.4 5、分子式&#xff1a;C48H52CIN3O2 6、…

如何用DOS命令设置ip地址及DNS

用DOS命令设置ip地址及DNS 设置/修改IP地址&#xff0c;子网掩码&#xff0c;网关的格式&#xff1a; netsh interface ip set address "本地连接" static 10.25.35.35 255.255.255.0 10.25.35.7 auto[more] 命令的意思是将“本地连接” ip地址设置成 10.25.35.3…