CMake中if的使用

2023-11-12

      CMake中的if命令用于有条件地执行一组命令,其格式如下:

if(<condition>)
  <commands>
elseif(<condition>) # optional block, can be repeated
  <commands>
else()              # optional block
  <commands>
endif()

      根据Condition syntax评估if子句的条件参数(<condition>)。如果结果为true,则执行if块(block)中的命令。否则,以相同方式处理可选的elseif块.最后,如果没有条件为true,则执行可选else块中的命令。

      Condition Syntax:以下语法适用于if、elsif和while子句的条件参数。
      复合条件(compound condition)按以下优先顺序进行评估
      (1).括号(Parentheses).
      (2).一元测试(unary tests),例如EXISTS、COMMAND和DEFINED。
      (3).二元测试(binary tests),例如EQUAL,LESS,LESS_EQUAL,GREATER,GREATER_EQUAL,STREQUAL,STRLESS,STRLESS_EQUAL,STRGREATER,STRGREATER_EQUAL, VERSION_EQUAL,VERSION_LESS,VERSION_LESS_EQUAL,VERSION_GREATER,VERSION_GREATER_EQUAL, PATH_EQUAL和MATCHES.
      (4).一元逻辑运算符(unary logical operator):NOT
      (5).二元逻辑运算符(binary logical operators):AND和OR,从左到右,没有任何短路(without any short-circuit)。

      1.Basic Expressions:
      (1).if(<constant>):如果常量为1, ON, YES, TRUE, Y或非零数(包括浮点数),则为true。如果常量为0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, 空字符串或以后缀-NOTFOUND结尾,则为false.命名布尔常量不区分大小写。如果参数不是这些特定常量之一,则将其视为变量或字符串,并适用以下两种形式之一。
      (2).if(<variable>):如果给定一个定义非false常量的值的变量,则为true。否则为false,包括变量未定义时。注意:宏参数不是变量。环境变量也不能以这种方式测试,例如if(ENV{some_var})将始终评估为false.
      (3).if(<string>):带引号的字符串始终评估为false,除非:字符串的值是真正的常量之一,或者Policy CMP0054为设置为NEW,并且字符串的值恰好是受CMP0054行为影响的变量名称。

if(ON)
    message("on") # print
endif()
if(OFF)
    message("off") # won't print
endif()

if(YES)
    message("yes") # print
endif()
if(NO)
    message("no") # won't print
endif()

if(true)
    message("true") # print
endif()
if(TRUE)
    message("TRUE") # print
endif()
if(FALSE)
    message("FALSE") # won't print
endif()

set(ENV{CMAKE_PREFIX_PATH} "github/fengbingchun")
if(ENV{CMAKE_PREFIX_PATH})
    message("env") # won't print
endif()

if("csdn")
    message("csdn") # won't print
endif()

      2.Logic Operators:
      (1).if(NOT <condition>):如果条件不为ture,,则为true.
      (2).if(<cond1> AND <cond2>):如果这两个条件都被单独被认为是true,则为true.
      (3).if(<cond1> OR <cond2>):如果任一条件单独被认为是true,则为true.
      (4).if((condition) AND (condition OR (condition))):首先评估括号内的条件,然后像其它示例一样评估其它条件。在有嵌套括号的地方,最里面的小括号作为条件的一部分被评估。

set(var "csdn")

if(NOT var2)
    message("not var2") # print
endif()

if(var OR var2)
    message("var OR var2") # print
endif()
if(var AND var2)
    message("var AND var2") # won't print
endif()

      3.Existence Checks:
      (1).if(COMMAND command-name):如果给定的name是可以调用的命令、宏或函数,则为true.
      (2).if(POLICY policy-id):如果给定的name是存在的policy(形式为CMP<NNNN>),则为true.
      (3).if(TARGET target-name):如果给定的name是通过调用(在任何目录中)add_executable, add_library, 或add_custom_target命令创建的现有逻辑目标名称(existing logical target name),则为true.
      (4).if(TEST test-name):如果给定的name是由add_test命令创建的现有测试名称(existing test name),则为true.
      (5).if(DEFINED <name>|CACHE{<name>}|ENV{<name>}):如果定义了给定<name>的变量、缓存变量或环境变量,则为true.变量的值无关紧要。注意:宏参数不是变量。无法直接测试<name>是否为非缓存变量。如果存在缓存或非缓存变量someName,则表达式if(DEFINED someName)将评估为true.相比之下,表达式if(DEFINED CACHE{someName})仅在缓存变量someName存在时才为true。如果你需要知道是否存在非缓存变量,则需要测试两个表达式:if(DEFINED someName AND NOT DEFINED CACHE{someName})
      (6).if(<variable|string> IN_LIST <variable>):如果给定元素包含在命名列表变量(named list variable)中,则为true.

function(func)
    message("hello func")
endfunction()

if(COMMAND func)
    message("func") # print
endif()

if(POLICY CMP0010)
    message("policy") # print
endif()

find_package(OpenCV 3.4.2) # -- Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.4.2")
if(TARGET opencv_core)
    message("opencv_core") # print
endif()

set(var OFF) # 变量的值无关紧要
if(DEFINED var)
    message("defined var") # print
endif()

set(var2 )
if(DEFINED var2)
    message("defined var2") # won't print
endif()

      4.File Operations:
      (1).if(EXISTS path-to-file-or-directory):如果指定的文件或目录存在,则为true仅针对显式完整路径(Behavior is well-defined only for explicit full paths).解析符号链接,如果符号链接的目标存在,则为true.
      (2).if(file1 IS_NEWER_THAN file2):如果file1比file2新,或两个文件中的一个不存在,则为true。仅针对完整路径。如果文件时间戳完全相同,则IS_NEWER_THAN比较返回true,这包括为file1和file2传递相同文件名的情况。
      (3).if(IS_DIRECTORY path-to-directory):如果给定name是目录,则为true。仅针对完整路径
      (4).if(IS_SYMLINK file-name):如果给定name是符号链接,则为true.仅针对完整路径
      (5).if(IS_ABSOLUTE path):如果给定路径是绝对路径,则为true。注意以下特殊情况:空路径评估为false。在windows主机上,任何以驱动器号和冒号(例如 C:)、正斜杠或反斜杠开头的路径都将评估为true.这意味着像C:no\base\dir这样的路径将评估为true.在非windows主机上,任何以波浪号(~)开头的路径都为true.

if(EXISTS /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage)
    message("exists messy_usage") # print
endif()
if(EXISTS ../../Samples_Make)
    message("exists samples_make") # won't print
endif()

if(/home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/test_find_package.cmake IS_NEWER_THAN /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/test_xxxx.cmake)
    message("is newer") # print
endif()

if(IS_DIRECTORY /home/spring/GitHub)
    message("is directory")
endif()

if(IS_SYMLINK /usr/bin/gcc) # /usr/bin/gcc -> gcc-11*
    message("is symlink") # print
endif()

if(IS_ABSOLUTE ~/.bashrc)
    message("is absolute") # print
endif()

      5.Comparisons:
      (1).if(<variable|string> MATCHES regex):如果给定的字符串或变量的值与给定的正则表达式匹配(matches),则为true.
      (2).if(<variable|string> LESS <variable|string>):如果给定的字符串或变量的值是有效数字且小于右侧的数字,则为true.
      (3).if(<variable|string> GREATER <variable|string>):如果给定的字符串或变量的值是有效数字且大于右侧的数字,则为true.
      (4).if(<variable|string> EQUAL <variable|string>):如果给定的字符串或变量的值是有效数字且等于右侧的数字,则为true.
      (5).if(<variable|string> LESS_EQUAL <variable|string>):如果给定的字符串或变量的值是有效数字且小于或等于右侧的数字,则为true.
      (6).if(<variable|string> GREATER_EQUAL <variable|string>):如果给定的字符串或变量的值是有效数字且大于或等于右侧的数字,则为true.
      (7).if(<variable|string> STRLESS <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)小于右侧的字符串或变量,则为true.
      (8).if(<variable|string> STRGREATER <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)大于右侧的字符串或变量,则为true.
      (9).if(<variable|string> STREQUAL <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)等于右侧的字符串或变量,则为true.
      (10).if(<variable|string> STRLESS_EQUAL <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)小于或等于右侧的字符串或变量,则为true.
      (11).if(<variable|string> STRGREATER_EQUAL <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)大于或等于右侧的字符串或变量,则为true.

if("cSdN" MATCHES [A-Za-z])
    message("matches") # print
endif()

set(var1 4.1)
set(var2 4.2)
if(var1 LESS var2)
    message("less") # print
endif()
if(var2 GREATER var1)
    message("greater") # print
endif()
if(var1 EQUAL var1)
    message("equal") # print
endif()

set(var3 "abc")
set(var4 "ABC")
if(var4 STRLESS var3)
    message("strless") # print
endif()
if(var4 STRLESS_EQUAL var3)
    message("strelss equal") # print
endif()
if(var3 STRGREATER var4)
    message("strgreater") # print
endif()

      6.Version Comparisons:按组件的整数版本号比较(版本格式为major[.minor[.patch[.tweak]]],省略的组件被视为零)。任何非整数版本组件或版本组件的非整数结尾部分都会在该点有效截断字符串。
      (1).if(<variable|string> VERSION_LESS <variable|string>):如果给定的字符串或变量的值小于右侧的值,则为true.
      (2).if(<variable|string> VERSION_GREATER <variable|string>):如果给定的字符串或变量的值大于右侧的值,则为true.
      (3).if(<variable|string> VERSION_EQUAL <variable|string>):如果给定的字符串或变量的值等于右侧的值,则为true.
      (4).if(<variable|string> VERSION_LESS_EQUAL <variable|string>):如果给定的字符串或变量的值小于或等于右侧的值,则为true.
      (5).if(<variable|string> VERSION_GREATER_EQUAL <variable|string>):如果给定的字符串或变量的值大于或等于右侧的值,则为true.

set(cv_version1 4.2.1)
set(cv_version2 4.2.5)

if(cv_version1 VERSION_LESS cv_version2)
    message("version less") # print
endif()
if(cv_version2 VERSION_GREATER cv_version1)
    message("versoin greater") # print
endif()

      7.Path Comparisons:if(<variable|string> PATH_EQUAL <variable|string>),逐个组件比较两个路径。只有当两条路径的每个组件都匹配时,两条路径比较的结果才为true.多个路径分隔符有效折叠成一个分隔符,但注意反斜杠不会转换为正斜杠。
      由于对多个路径分隔符的处理,基于组件的比较优于基于字符串的比较。

      执行上述测试代码需要3个文件:build.sh, CMakeLists.txt, test_if.cmake

      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)

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

     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_if.cmake:为上面的所有示例代码

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

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

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

CMake中if的使用 的相关文章

  • CMake中configure_file的使用

    CMake中的configure file命令用于将一个文件拷贝到另一个位置并修改其内容 其格式如下 configure file
  • CMake中define_property的使用

    CMake中的define property命令用于定义和记录自定义属性 其格式如下 define property
  • CMake中list的使用

    CMake中的list命令用于列表操作 其格式如下 Reading list LENGTH
  • Vcpkg介绍及使用

    Vcpkg用于在Windows Linux Mac上管理C和C 库 极大简化了第三方库的安装 它由微软开源 源码地址 https github com Microsoft vcpkg 最新发布版本为2023 04 15 Release 它的
  • CMake中add_definitions/add_compile_definitions的使用

    CMake中的add definitions命令用于在源文件的编译中添加 D定义标志 其格式如下 add definitions DFOO DBAR 将当前目录中的target的定义添加到编译器命令行 compiler command li
  • 图像处理库(fbc_cv):源自OpenCV代码提取

    在实际项目中会经常用到一些基本的图像处理操作 而且经常拿OpenCV进行结果对比 因此这里从OpenCV中提取了一些代码组织成fbc cv库 项目fbc cv所有的代码已放到GitHub中 地址为 https github com feng
  • Ubuntu下通过CMake文件编译CUDA+OpenCV代码操作步骤

    在 CUDA Test 工程中 CUDA测试代码之前仅支持在Windows10 VS2013编译 今天在Ubuntu 14 04下写了一个CMakeLists txt文件 支持在Linux下也可以通过CMake编译CUDA Test工程 C
  • CMake中aux_source_directory的使用

    CMake中的aux source directory命令用于查找目录中的所有源文件 其格式如下 aux source directory
  • 在Ubuntu14.04 64位上编译CMake源码操作步骤

    在Ubuntu上通过apt get install安装CMake并不是最新版的 这里记录下在Ubuntu上通过源码安装CMake的操作步骤 1 卸载旧版CMake 执行以下命令 apt get autoremove cmake 如果卸载不掉
  • CMake中option和cmake_dependent_option的使用

    CMake中的option命令为用户提供可以选择的布尔选项 boolean option 其格式如下 option
  • Linux下遍历指定目录的C++实现

    之前在 https blog csdn net fengbingchun article details 51474728 给出了在Windows遍历指定文件夹的C 实现 这里给出在Linux下遍历目录的实现 Windows和Linux下的
  • CMake中set_target_properties/get_target_property的使用

    CMake中的set target properties命令用于为targets设置属性 targets can have properties that affect how they are built 其格式如下 set target
  • GCC编译选项参数介绍

    gcc和g 分别是gnu的c和c 编译器 下面是整理的常用编译选项参数 1 x 设定文件所使用的语言 使文件后缀名无效 如下 执行完后生成test o gcc c x c test jpg 2 c 只编译生成目标文件即 o 只编译不链接生成
  • C++中插件使用举例

    插件并不是在构建时链接的 而是在运行时发现并加载的 因此 用户可以利用你定义好的插件API来编写自己的插件 这样他们就能以指定方式扩展API的功能 插件库是一个动态库 它可以独立于核心API编译 在运行时根据需要显示加载 不过插件也可以使用
  • CMake中if的使用

    CMake中的if命令用于有条件地执行一组命令 其格式如下 if
  • CMake中while/continue/break的使用

    CMake中的while命令用于在条件为true时评估 evaluate 一组命令 其格式如下 while
  • CMake中cmake_minimum_required的使用

    CMake中的命令cmake minimum required用于设定需要的最低版本的CMake 其格式如下 cmake minimum required VERSION
  • Ubuntu14.04下配置OpenGL及测试代码

    ubuntu14 04 64位下 默认是没有安装OpenGL相关依赖库的 若安装 则依次执行如下几条命令即可 sudo apt get update sudo apt get install build essential sudo apt
  • CMake中target_compile_definitions的使用

    CMake中的target compile definitions命令用于向target添加编译定义 其格式如下 target compile definitions
  • CMake中include的使用

    CMake中的include命令用于从文件或模块 file or module 加载并运行CMake code 其格式如下 include

随机推荐

  • 一个合格(优秀)的前端都应该阅读这些文章

    的确 有些标题党了 起因是微信群里 有哥们问我 你是怎么学习前端的呢 能不能共享一下学习方法 一句话也挺触动我的 我真的不算是什么大佬 对于学习前端知识 我也不能说是掌握了什么捷径 当然 我个人的学习方法这篇文章已经在写了 预计这周末会在我
  • The overload Pattern

    最近研究有关C 17的书和博客文章时 偶然发现了这种访问模式std variant 使用overload模式 您可以 访问 提供单独的lambda include
  • 如何查看端口占用

    1 Win R 打开 运行 在 运行 中输入cmd 然后按电脑的回车进入命令行 2 输入命令 netstat ano 即可查出所有的端口占用信息 3 netstat ano findstr 端口 可查看具体的端口占用信息 4 查看有效会话
  • 关于B/S结构系统的会话机制(session机制)

    关于B S结构系统的会话机制 session机制 什么是会话 用户打开浏览器 进行一系列操作 最后关闭浏览器 这个整个过程叫做一次会话 真正意义上 会话是session对象的创建到结束的过程 一个session对应一个会话 在服务器端有一个
  • 虚拟机如何进行备份和迁移?

    文章目录 一 虚拟机的备份 方式一 使用VMvare自带的克隆功能 方式二 手动复制 二 虚拟机的迁移 本文以Ubuntu18 04为例 使用的工具是VMware Workstation 16 Pro 即VMware 最新版 Ubuntu1
  • 谷歌直链下载云盘数据集,使用谷歌云盘生成直接下载的url,示例: NeRFStudio-nerfacto默认训练数据集poster下载,nerfstudio 数据集下载链接

    1 如何生成谷歌直链下载云盘数据集的url 谷歌云盘 NeRFStudio nerfacto默认训练数据集poster下载链接 https drive google com uc export download confirm id 1dm
  • 差分与微分

    差分与微分 差分和微分都是数学中的一些基本概念 它们在数学 物理学 经济学和其他领域中都有广泛的应用 1 差分 差分可以理解为函数值之间的差别 特别地 如果一个函数 f f f 在两个相邻点 x 0
  • 【Qt教程】2.6 - Qt5 自定义控件封装

    自定义控件是将原有控件组合 封装 并填入自定义功能 留出适当的函数接口 方便其他控件的调用 设计窗口时 可以将控件拖入 方便模块化设计 GitHub代码仓库 Qt学习例程 1 建立工程 新建自定义控件 创建widget工程 新建控件 Add
  • 青龙面板打不开解决办法

    原因是cdn 自己修改一下就可以了 进入文件夹etc找到hosts etchosts 把这二个添加 104 16 88 20 cdn js delivr net 直接复制在最后一行 就可以解决问题了 或者 1 登陆linux 2 进入青龙容
  • alter database open resetlogs

    问题解决 先要弄清楚alter database open resetlogs是什么意思 为什么要用resetlogs打开数据库 这个命令发出后oracle都做了什么 alter database open resetlogs是要打开数据时
  • pytorch——torch.squeeze() 和torch.unsqueeze()的用法

    torch squeeze torch squeeze 这个函数主要对数据的维度进行压缩 去掉维数为1的的维度 比如是一行或者一列这种 一个一行三列 1 3 的数去掉第一个维数为一的维度之后就变成 3 行 torch squeeze a 就
  • 项目答辩PPT(一)

    以 运动APP 为例展开 1 项目整体介绍 定位和需求 在银行工作的王小姐是个健身爱好者 从制订健身计划 到约人一起跑步 再到周末预订场地和家人打一场羽毛球赛 她用一部手机轻松搞定 现在有了手机APP 运动方便多了 王小姐的运动方式是如今都
  • QT创建右键快捷菜单

    0 目标 在Qcommbobox右键出来菜单 点击BCC校验 自动算出校验值填入编辑框 1 UI界面选择Action editor 新建action 记住对象名 actionBCC 右键action 点击转到槽 选择triggered 点击
  • 指针(一)——指针与二级指针

    一 指针理解 指针是一个变量 用来存放地址的变量 指针变量 是一个变量 是指有一个存储空间 里面放的是指针 变量指针 变量的地址 指针的存在是为了方便计算机的内存管理 经过计算和权衡 我们发现 一个字节给一个地址是比较合适的 在32位的机器
  • 给wangeditor添加上标、下标功能

    我使用的wangeditor没有上标和下标功能 以下是自己添加功能的方法 1 设计功能的函数和原型 Sup menu 构造函数 function Sup editor this editor editor this elem div cla
  • 高性能MySQL实战(一):表结构

    最近因需求改动新增了一些数据库表 但是在定义表结构时 具体列属性的选择有些不知其所以然 索引的添加也有遗漏和不规范的地方 所以我打算为创建一个高性能表的过程以实战的形式写一个专题 以此来学习和巩固这些知识 1 实战 我使用的 MySQL 版
  • 【深度学习】 Python 和 NumPy 系列教程(七):Python函数

    目录 一 前言 二 实验环境 三 Python函数基础 1 定义函数 2 参数传递 3 函数调用 4 返回值 5 函数文档字符串 四 将函数存储在模块中 1 创建模块 2 导入模块 a import 模块名 b from 模块名 impor
  • github.io出现的问题及解决方案

    github io出现的问题及解决方案 个人博客 github io出现的问题及解决方案 1 你的连接不是专用连接 放假回家后打开自己的博客 发现无法打开博客 一开始以为是调样式时不小心搞坏了 打开别人的githunb io博客发现都会出问
  • Python删除字符串中连续重复字符,保留所有去重后字符

    看了很多攻略 但都是全部去除字符串中所有的重复字符或者全部去除字符串所有相邻的重复字符 如果希望得到字符串中相邻字符去重后的全部字符 比如字符串a abbcccd222aaabbbddfff6e 去重后能得到 abcd2abdf6e 那可以
  • CMake中if的使用

    CMake中的if命令用于有条件地执行一组命令 其格式如下 if