【Linux杂学】CMake:编写 CMakeLists

2023-11-13

【CMake官网】:掌握CMake

1、变量

CMake 变量名称区分大小写,且只能包含字母数字字符和下划线
CMAKE_ 变量【存储均为字符串】是CMake 自定义变量,命名应避开

set 可设变量值,第一参数是变量名,其余参数是值
多个参数被打包到 分号分隔的列表 中,并作为字符串存储在变量中

set(Foo "")      	# 1 quoted arg -> value is ""
set(Foo a)       	# 1 unquoted arg -> value is "a"
set(Foo "a b c") 	# 1 quoted arg -> value is "a b c"
set(Foo a b c)   	# 3 unquoted args -> value is "a;b;c"

变量 VAR 可通过 ${VAR} 引用
若变量未设值,则引用替换为空字符串,否则为变量值
替换是在扩展未引用的参数之前执行的,因此 含分号的变量值 被拆分为0~n个参数 来代替原始未引用参数

set(Foo a b c)    	# 3 unquoted args -> value is "a;b;c"
command(${Foo})   	# unquoted arg replaced by a;b;c
                  	# and expands to three arguments
command("${Foo}") 	# quoted arg value is "a;b;c"


set(Foo "")       	# 1 quoted arg -> value is empty string
command(${Foo})   	# unquoted arg replaced by empty string
                  	# and expands to zero arguments
command("${Foo}") 	# quoted arg value is empty string

CMake 可直接访问 环境变量、Windows注册表值
环境变量:$ ENV{VAR}
注册表项: [HKEY_CURRENT_USER\Software\path1\path2;key] 【路径是从注册表树和键构建】

2、变量范围

CMake 中变量作用域略有不同
1、设变量时,对当前及任何子目录的 CMakeLists文件或函数,乃至include包含的文件均可见
2、当处理新子目录或调新函数时,建新变量范围,并使其内所有变量值初始化
3、在子作用域中,对新变量或现有变量更改,均不影响父作用域

// 不影响父作用域:
function(foo)
	message(${test}) 	# test is 1 here
	set(test 2)
  	message(${test}) 	# test is 2 here, but only in this scope
endfunction()

set(test 1)
foo()
message(${test}) 	 	# test will still be 1 here

在子作用域中,让变量影响父作用域:PARENT_SCOPE

function(foo)
  	message(${test}) 	# test is 1 here
  	set(test 2 PARENT_SCOPE)
  	message(${test}) 	# test still 1 in this scope
endfunction()

set(test 1)
foo()
message(${test}) 	 	# test will now be 2 here

变量是按 set 执行顺序定义的

# FOO is undefined

set(FOO 1)
# FOO is now set to 1

set(FOO 0)
# FOO is now set to 0

变量范围:

set(foo 1)

# process the dir1 subdirectory
add_subdirectory(dir1)		//foo

# include and process the commands in file1.cmake
include(file1.cmake)		//foo

set(bar 2)
# process the dir2 subdirectory
add_subdirectory(dir2)		//foo、bar

# include and process the commands in file2.cmake
include(file2.cmake)		//foo、bar
3、命令

虽命令名称不区分大小写,但command命名最佳,其和 ( 在同一行,内容就可跨多行
命令参数以空格分隔且区分大小写,"开始"结尾则只表示一参数

值中含 " 须用 \ 转义,可考虑对需要转义的参数可用方括号
值还可用分号来自动扩展参数

command("")          # 1 quoted argument
command("a b c")     # 1 quoted argument
command("a;b;c")     # 1 quoted argument
command("a" "b" "c") # 3 quoted arguments
command(a b c)       # 3 unquoted arguments
command(a;b;c)       # 1 unquoted argument expands to 3
4、基本命令

set 设变量,unset 取消变量
string、list、separate_arguments 提供对字符串和列表的基本操作
add_executable、add_librarycommands 定义要构建的可执行文件和库,以及包含它们的源文件

Visual Studio 项目,显示源文件的同时,若要显示头文件,需将它们添加到可执行文件或库的源文件列表中

5、流量控制

流控制结构:
1、条件语句【if】
2、循环结构【foreach、while】
3、程序定义【macro、function】

6、条件语句

条件语句【if】:

if(FOO)
  	# do something here
else()
  	# do something else
endif()

elseif 顺序测试多条件:

if(MSVC80)
  	# do something here
elseif(MSVC90)
  	# do something else
elseif(APPLE)
  	# do something else
endif()
7、循环构造

循环结构【foreach】:

foreach(tfile		//变量名
        TestAnisotropicDiffusion2D	//值列表
        TestButterworthLowPass
        TestButterworthHighPass
        TestCityBlockDistance
        TestConvolve
        )
	add_test(${tfile}-image ${VTK_EXECUTABLE}	//循环主题
		${VTK_SOURCE_DIR}/Tests/rtImageTest.tcl
    	${VTK_SOURCE_DIR}/Tests/${tfile}.tcl
    	-D ${VTK_DATA_ROOT}
    	-V Baseline/Imaging/${tfile}.png
    	-A ${VTK_SOURCE_DIR}/Wrapping/Tcl
    	)
endforeach()

每次循环 tfile 顺序变更值,直到处理完所有值
foreach 可嵌套,还可用循环变量构造变量名:

if(${${tfile}}_TEST_RESULT} MATCHES FAILED)
  	message("Test ${tfile} failed.")
endif()

循环结构【while】:

#####################################################
# run paraview and ctest test dashboards for 6 hours
#
while(${CTEST_ELAPSED_TIME} LESS 36000)
  	set(START_TIME ${CTEST_ELAPSED_TIME})
  	ctest_run_script("dash1_ParaView_vs71continuous.cmake")
  	ctest_run_script("dash1_cmake_vs71continuous.cmake")
endwhile()
8、过程定义

macro、function 支持分散 CMakeLists 中的重复性任务
调函数将建新变量范围,对变量修改仅存于函数内,出函数将释放

function 第一参数是函数名,后续参数均是函数形参

function(DetermineTime _time)	//_time 用于传递返回变量的名称
  	# pass the result up to whatever invoked this
  	set(${_time} "1:23:45" PARENT_SCOPE)	// 影响父作用域
endfunction()

# now use the function we just defined
DetermineTime(current_time)

if(DEFINED current_time)
  	message(STATUS "The time is now: ${current_time}")
endif()

宏定义和调用方与函数相同
主要区别在于宏不推送和弹出新变量范围,且宏的参数不被视为变量,而是在执行之前就被替换为字符串

第一个参数是宏名,后续参数均是宏形参

# define a simple macro
macro(assert TEST COMMENT)
  	if(NOT ${TEST})
    	message("Assertion failed: ${COMMENT}")
  	endif()
endmacro()

# use the macro
find_library(FOO_LIB foo /usr/local/lib)
assert(${FOO_LIB} "Unable to find library foo")

macro 还支持 可变参数列表,变量参数可用 ARGC 和 ARGV0、ARGV1 等来引用,而非形参
混合形参和可变参数:

# define a macro that takes at least two arguments
# (the formal arguments) plus an optional third argument
macro(assert TEST COMMENT)
  	if(NOT ${TEST})
    	message("Assertion failed: ${COMMENT}")

    	# if called with three arguments then also write the
    	# message to a file specified as the third argument
    	if(${ARGC} MATCHES 3)
      		file(APPEND ${ARGV2} "Assertion failed: ${COMMENT}")
    	endif()

  	endif()
endmacro()

# use the macro
find_library(FOO_LIB foo /usr/local/lib)
assert(${FOO_LIB} "Unable to find library foo")

若要将参数作为列表处理,可用 ARGV 和 ARGN
ARGV【与 ARGV0、ARGV1 等相反】是宏的所有参数的列表,而 ARGN 是形参之后的所有参数的列表

return 从函数、目录或文件返回
宏不同于函数,在原地展开,因此无法处理返回

9、正则表达式

if、string,可用正则表达式作参数【指定正则有几种不同约定】,如搜索字符串
用基于 Texas Instruments 的开源正则表达式类 可解析 正则表达式

10、高级命令

add_dependencies 可在两个目标之间创建依赖关系【至少一目标是自定义目标】
include_regular_expression 可控制 用于跟踪源代码依赖关系的正则表达式【如限制处理某些包含文件】

以前缀 foo 开头,指定正则 ^foo.*$ 以将依赖项检查 限制为仅对项目的文件检查

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

【Linux杂学】CMake:编写 CMakeLists 的相关文章

随机推荐

  • 实现单层神经网络

    在前面 我们分别使用逻辑回归和 softmax 回归实现了对鸢尾花数据集的分类 逻辑回归能够实现线性二分类的任务 他其实就是最简单的神经网络 感知机 而softmax回归则实现的是多分类任务 它也可以看做是输出层有多个神经元的单层神经网络
  • Flink之IntervalJoin介绍

    InterValJoin算子 间隔流 一条流去join另一条流去过去一段时间内的数据 该算子将keyedStream与keyedStream转化为DataStream 再给定的时间边界内 默认包含边界 相当于一个窗口 按指定的key对俩个K
  • (ESP32学习13)驱动TFTLCD(SPI接口)

    本篇博文教大家ESP32 驱动TFT SPI驱动 本文给大家的库直接适用于2寸 240 320 的SPI TFT 但实际上这种驱动移植适用于所有的SPI驱动的TFT屏幕 底层代码把LCD初始化里面的寄存器参数改一改就适用了 这些寄存器参数在
  • 基于STM32F103循迹小车

    本人小白一个 利用暑假时间在家做一些小东西 我这次想要跟大家分享的是基于STM32F103的循迹小车的制作 两个轮子 主要硬件 板子 L298N 电机 4个循迹模块等 话不多说 先上干货 XJ c include XJ h 循迹文件 inc
  • KEIL下载报错——TRACE HW not present

    使用st link调试遇到烧写完成之后不能进入调试状态 提示TRACE HW not present 点击确认 提示错误 Erron target DLL has been cancelled Debugger aborted 解决办法 第
  • 何在python里面用tkinter模块做一个GUI界面,实现button点击之后弹出新页面,新页面是一些文字内容

    首先弹出新页面需要用到callback函数 代码编写如下 import scapy from tkinter import root tk Tk root wm geometry 600x400 root title tk def call
  • ShinyApp中的表格:第三天笔记

    shiny中的表格 除了在shinyapp中生成图片 有时还需要生成表格 用于查看数据 以及保存下载 表格分为两类 动态和静态 静态的表格更有利于打印和输出pdf 而动态的表格提供了更多的交互式选项 还会响应屏幕的大小来进行缩放 静态表格
  • 从材质到外观(待续)

    很多地方都只有材质 然后shader中 最终肯定是到片元着色器 也就是appearance 后处理是单独的poststage var appearance new Ceisum MaterialAppearance Cesium Mater
  • 一次ORA-39083,ORA-01917的问题解决过程

    一次ORA 39083 ORA 01917的问题解决过程 今天到导数据的时候遇到了一个问题 也不知道有没有其他小伙伴也遇到过 按照要求导出一个用户下指定表的部分数据 此时使用了expdp的tables参数指定要导出的表这里我导出的是BKG
  • hdu 6311 Cover

    无向图的最小路径覆盖 找出联通块里所有的奇度点 然后两个两个的点互相连边 构造成所有点都是偶度数 然后就找联通块里有多少条欧拉回路 如果回路中有新加的边则答案 include
  • 分析结果循环写入csv

    30户的暖气的分析结果复制粘贴下来发给队友 好像是有点多了一个对话框都过不去 被嫌弃了 你就不能给我打包个excel 好吧 import csv with open result csv w as csvfile writer csv wr
  • Docker 安装运行 ElasticSearch 遇到的问题!

    在创建 6 4 3版本的 ES 以后启动发现过了一会 ES 自动退出了 原因好像是 ES 的默认分配的内存太大了 进程被自动杀死了 所以以下我来记录下这坑 使用ES工具类索引时运行测试方法时报错 org elasticsearch tran
  • 【linux--------基础Apache配置】

    这里写目录标题 关于Apache介绍 部署简单的Apache静态网站 常见问题 关于Apache介绍 Apache是一个开源的Web服务器软件 它是世界上最流行的Web服务器之一 Apache的全称为Apache HTTP Server 它
  • cublas 实战

    导言 搞了一段时间的CUDA程序 虽然也不是写不出复杂程序 但是写个矩阵乘法都要搞个半天 还要担心各种性能瓶颈 不过 还好有cublas 实现了非常多的数学运算 这下子可以好好利用一番 以后再也不用担心自己写的CUDA效率不高了 入门 cu
  • 查看ssh端口号_更改centos系统ssh连接端口号

    由于本人平时爱折腾 之前趁着阿里云和腾讯云搞活动期间分别搞了台服务器 刚开始的时候 服务器的防护措施没有做好 陆陆续续服务器被黑了好几次 最惨的一次是搭建的知识库的服务器被黑 导致所有的数据丢失 黑客在服务器留言需要0 25个比特币赎回数据
  • 记2016.10.15百度面试经历,软件研发工程师

    9月参加的网上笔试 选择主要做了一些行测的题 头一次做行测题 后面有三道编程题 做出来一道 卡在第二道了50 感觉自己水水的 百度也一直没通知面试 以为被刷了就没抱什么希望 后来13号竟然发来了面试通知还是有点小激动 要求9 00 并且提前
  • Quartz.NET简明示例

    下面是一个 Quartz NET 的简单例子 初始化调度器工厂 ISchedulerFactory sf new StdSchedulerFactory 获取默认调度器 IScheduler scheduler sf GetSchedule
  • Linux 反引号、单引号、双引号简析

    文章目录 一 引号的作用 二 反引号 三 单引号 四 双引号 五 引号解释顺序 一 引号的作用 1 将多个因为空格或者回车等分隔符隔开的字符串合在一起 避免被命令行解析分开 例如 a b c 是一个字符串 而不会像 a b c 这样会被解析
  • 6.基于STM32C8T6的四旋翼无人机的飞控制作----实践操作1,AD电路板绘制-前期准备

    飞控的各种芯片是焊接在电路板上的 电路板是各种传感器和接口的载体 电路板的设计过程也是极其考验耐心和仔细程度的 在大公司里都是每个部门负责其中的一部分工作 如原理图设计 布局布线 测试等等 在小公司和大学生的设计中 经常需要一个人走完全部的
  • 【Linux杂学】CMake:编写 CMakeLists

    CMake官网 掌握CMake 1 变量 CMake 变量名称区分大小写 且只能包含字母数字字符和下划线 CMAKE 变量 存储均为字符串 是CMake 自定义变量 命名应避开 set 可设变量值 第一参数是变量名 其余参数是值 多个参数被