CMake中if的使用

news2024/10/7 16:15:33

      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

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

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

相关文章

HTML5期末大作业:旅游网页设计与实现——旅游风景区网站HTML+CSS (1)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游景点介绍 | 旅游风景区 | 家乡介绍 | 等网站的设计与制作 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结构 CSS&…

【项目实战:核酸检测平台】第一章 逆向工程

引言 准备做个项目实战系列&#xff0c;选一些比较有代表性&#xff0c;难度适中、规模合适的项目&#xff0c;从不同的角度&#xff0c;不同的深度去解析。很多初学者都抱怨没有实战项目&#xff0c;而学校/机构里大量用烂的学生管理、图书管理、电子商城等项目实在没有什么新…

LeetCode--230. 二叉搜索树中第K小的元素(C++描述)

// Source :https://leetcode.cn/problems/kth-smallest-element-in-a-bst/ // Date : 2022-11-19 /************************************************************************************** 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计…

Nginx 快速入门

一、简述 1.1 介绍 传统的 Web 服务器&#xff0c;每个客户端连接作为一个单独的进程或线程处理&#xff0c;需在切换任务时将 CPU 切换到新的任务并创建一个新的运行时上下文&#xff0c;消耗额外的内存和 CPU 时间&#xff0c;当并发请求增加时&#xff0c;服务器响应变慢&…

修改xml文件

一、前言 本节是修改xml;同样方法也可修改arxml文件&#xff1b;主要使用LET.Element创建节点&#xff1b; 二、知识点 1、专门用于格式化处理xml文件使其具有层级分明的缩进函数 #专门用于格式化处理xml文件使其具有层级分明的缩进 def indent( elem, level0): i "\n&…

基于51单片机的全自动智能洗衣机控制系统Proteus仿真

资料编号&#xff1a;108 下面是相关功能视频演示&#xff1a; 108-基于51单片机的全自动智能洗衣机控制系统Proteus仿真&#xff08;仿真源码全套资料&#xff09;设计功能&#xff1a; 1、对水温实时显示 2、显示滚筒转速 3、显示运行倒计时 4、能通过按钮分别设置洗涤时间…

一文带你深入理解【Java基础】· 常用类(上)字符串相关类

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

[附源码]java毕业设计社区私家车位共享收费系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

基于51单片机的八路电压表采集Proteus仿真

资料编号&#xff1a;110 下面是相关功能视频演示&#xff1a; 110-基于51单片机的八路电压表采集Proteus仿真&#xff08;源码仿真原理图全套资料&#xff09;功能如下&#xff1a; 利用单片机及其外围器件&#xff08;A/D转换器等&#xff09;实现一款简易电压表&#xff0…

(免费分享)基于springboot医药进销存系统

源码获取&#xff1a;关注文末gongzhonghao&#xff0c;输入014领取下载链接 开发工具&#xff1a;IDEA,数据库mysql 技术&#xff1a;springbootmybatis 系统主要分两个角色&#xff0c;客户和员工 package cn.tedu.drug.controller;import java.io…

【Pytorch with fastai】第 18 章 :使用 CAM 进行 CNN 解释

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

Design a Facebook NewsFeed

title: Notes of System Design No.06 — Design a Facebook’s Newsfeed description: Design a Facebook’s Newsfeed ’ date: 2022-05-13 18:01:58 tags: 系统设计 categories: 系统设计 00. What is News Feed? 01.Functional Requirement 02. Non-Functional Requireme…

面试刷题---计算机网络部分(一)

1 请描述 TCP/IP 协议中主机与主机之间通信的三要素 答&#xff1a; IP 地址&#xff08;IP address&#xff09; 子网掩码&#xff08;subnet mask&#xff09; IP 路由&#xff08;IP router&#xff09; 扩展&#xff1a; TCP/IP定义&#xff1a;TCP/IP是基于TCP和IP这两个…

iHRM 人力资源管理系统_第11章_刷脸登录

iHRM 人力资源管理系统_第11章_刷脸登录 文章目录iHRM 人力资源管理系统_第11章_刷脸登录第11章 刷脸登录1 浅谈人工智能1.1 人工智能的概述1.2 人工智能的应用领域1.3 基于人工智能的刷脸登录介绍2 百度云AI概述2.1 概述2.2 百度云AI的开发步骤2.3 百度云AI的注册与认证3 百度…

web大作业 静态网页(地下城与勇士 10页 带视频)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游戏官网 | 游戏网站 | 电竞游戏 | 游戏介绍 | 等网站的设计与制作 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结构 …

开源免费的对象存储Minio

什么是Minio&#xff1f; Minio是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合存储大容量、非结构化的数据。例如&#xff0c;图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是…

机器学习:卷积神经网络

卷积神经网络卷积神经网络的结构及原理卷积层池化层激活函数全连接层反馈运算使用MNIST数据集进行代码解析数据介绍实现流程代码实现卷积神经网络的结构及原理 卷积层 卷积运算一个重要的特点就是&#xff1a;通过卷积运算&#xff0c;可以使原信号特征增强&#xff0c;并且降…

服务器常用的异常及性能排查

服务器常用的异常及性能排查 使用 top 命令查看性能指标 top 命令使用详细介绍&#xff1a;传送门 查看Tasks total 进程数 正常我们在使用过程中对每天的一个进程数大概是有一个谱的&#xff0c;比如正常就是1百多个&#xff0c;突然暴增几百&#xff0c;那就很明显这里有…

计算机网络:运输层

运输层 运输层主要解决了应用进程之间的通信&#xff0c;称之为端到端协议 1.运输层概述 计算机网-------络体系结构的角度 AP:应用进程之间的简称 2. 运输层端口号、复用与分用的概念 2.1 端口号 2.2 发送方的复用&#xff08;multiplexing&#xff09;和接收方的分用&…

【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day10

大家好&#xff0c;我是陶然同学&#xff0c;软件工程大三明年实习。认识我的朋友们知道&#xff0c;我是科班出身&#xff0c;学的还行&#xff0c;但是对面试掌握不够&#xff0c;所以我将用这100多天更新Java面试题&#x1f643;&#x1f643;。 不敢苟同&#xff0c;相信大…