CMake笔记——二

news/2025/1/24 17:35:39/文章来源:https://www.cnblogs.com/gwzz/p/18689855

# 1 IF NOT和IF NOT DEFINED的区别?

# 2 环境变量

# 3 .cmake脚本

# 4 if (NOT EXISTS有什么用?

# 5 CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT

# 6 CMAKE_CXX_FLAGS

# 7 execute_process

1 IF ( NOT和IF ( NOT DEFINED的区别?

在CMake脚本中,IF (NOT ...) 和 IF (NOT DEFINED ...) 是两种用于条件判断的结构,但它们检查的内容不同。

1.1 IF (NOT ...):

这个结构用于检查某个条件是否为假(即“非”该条件)。这里的条件可以是一个布尔表达式、一个变量是否存在且非空(在CMake中,未定义的变量被视为假),或者是一个比较表达式的结果。

例如:SET(MY_VAR "some_value")IF (NOT MY_VAR)# 这部分代码不会被执行,因为MY_VAR已被定义且非空ENDIF()# 或者检查一个比较表达式的结果IF (NOT (MY_VAR STREQUAL "expected_value"))# 如果MY_VAR的值不等于"expected_value",则执行这部分代码ENDIF()

在这个上下文中,NOT 是逻辑非操作符,用于反转条件的真假值

1.2 IF (NOT DEFINED ...):

这个结构专门用于检查一个变量是否未被定义。如果变量未定义,则条件为真;如果变量已定义(无论其值是什么),则条件为假。

IF (NOT DEFINED MY_UNDEFINED_VAR)# 这部分代码会被执行,因为MY_UNDEFINED_VAR未被定义
ENDIF()SET(MY_DEFINED_VAR "any_value")
IF (NOT DEFINED MY_DEFINED_VAR)# 这部分代码不会被执行,因为MY_DEFINED_VAR已被定义
ENDIF()

在这个上下文中,NOT DEFINED 是一个特殊的检查,用于确定变量是否存在。

1.3

总结来说,IF (NOT ...) 是一个更通用的条件判断结构,可以用于检查各种条件的真假值(包括变量是否存在且非空),而 IF (NOT DEFINED ...) 是一个专门用于检查变量是否未定义的结构。选择使用哪一个取决于你想要检查的具体条件。

2 环境变量

    SET(ROS_ROOT $ENV{ROS_ROOT})

从环境变量中读取 ROS_ROOT 的值,并将这个值赋给 CMake 变量 ROS_ROOT。

这里有几个关键点需要注意:

  • 环境变量:$ENV{...} 是 CMake 中访问环境变量的语法。它允许你从操作系统的环境变量中读取值,并在 CMake 配置过程中使用这些值。
  • envprintenv:可以查看ubuntu下的环境变量

3 .cmake脚本

INCLUDE(${PROJ_SOURCE_DIR}/orocos-rtt.cmake OPTIONAL)

在CMake中,INCLUDE 命令用于包含另一个CMake脚本文件,这样可以将一些通用的配置或函数定义等放入单独的文件中,然后在多个CMakeLists.txt中重用。OPTIONAL 关键字是CMake 3.12及更高版本中引入的,用于处理包含文件时可能遇到的情况,特别是当包含的文件不存在时。

使用OPTIONAL可以使你的CMake配置更加健壮,特别是在处理可选的组件或插件时。这样,即使某些可选的CMake脚本文件不存在,整个项目的构建过程也不会因此中断。

例如,在你的项目中,orocos-rtt.cmake 可能包含了一些与Orocos RTT(Robot Control Middleware)相关的配置。如果Orocos RTT不是项目必需的,或者只在某些特定的构建配置中才需要,那么使用OPTIONAL就可以确保当Orocos RTT不可用或未配置时,项目的其他部分仍然可以正常构建。

4 if (NOT EXISTS有什么用?

在CMake中,if 语句用于基于某些条件执行不同的代码块。NOT EXISTS 是一个条件表达式,用于检查指定的文件或目录是否不存在。

if (NOT EXISTS <some_file_or_directory>)# 如果文件或目录不存在,则执行这里的命令
endif()

这里的 <some_file_or_directory> 应该被替换为你想要检查的文件或目录的路径。如果该文件或目录在CMake运行时不存在,那么if 语句内的命令将被执行。

例如,你可能想要在项目中包含一些可选的库或组件,而这些库或组件的CMake配置文件可能不是总是存在的。你可以使用if (NOT EXISTS ...)来检查这些配置文件是否存在,如果不存在,则跳过包含它们的命令或执行一些替代的命令。

    # 假设我们有一个可选的库,其配置文件可能不存在set(OPTIONAL_LIB_CONFIG "${CMAKE_SOURCE_DIR}/optional-lib-config.cmake")# 检查配置文件是否存在if (NOT EXISTS ${OPTIONAL_LIB_CONFIG})message(STATUS "Optional library config file not found, skipping...")# 这里可以执行一些替代的命令,或者什么都不做else()# 如果配置文件存在,则包含它include(${OPTIONAL_LIB_CONFIG})endif()

在这个例子中,如果optional-lib-config.cmake文件不存在,CMake将输出一条状态消息,并跳过包含该文件的命令。如果文件存在,则正常包含并执行其中的命令。

请注意,if 语句在CMake中有时可能会因为条件表达式的复杂性而变得难以阅读和维护。因此,尽量保持条件简单明了,并在可能的情况下使用变量来简化表达式。

5 CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT

CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 在 CMake 中是一个用于判断 CMAKE_INSTALL_PREFIX 变量是否被设置为默认值的标志。CMAKE_INSTALL_PREFIX 是 CMake 的一个内置变量,它定义了安装目标(如可执行文件、库文件等)时的前缀路径。这个前缀路径决定了安装目标在系统中的最终位置。

具体来说,CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 的作用如下:

  • 判断默认值:在 CMake 配置过程中,CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 可以被用来检查 CMAKE_INSTALL_PREFIX 是否被用户显式设置过,还是仍然保持着其默认值。这通常用于在 CMakeLists.txt 或其他 CMake 脚本中做出条件性的配置决策。
  • 提供灵活性:通过检查这个标志,CMake 脚本可以根据 CMAKE_INSTALL_PREFIX 是否被修改过,来执行不同的安装逻辑。例如,如果 CMAKE_INSTALL_PREFIX 保持默认值,脚本可能会选择一个特定的安装目录;如果它被修改了,则使用用户指定的目录。
  • 增强可移植性:在跨平台的项目中,CMAKE_INSTALL_PREFIX 的默认值可能因操作系统而异(例如,在 UNIX 系统上通常是 /usr/local,在 Windows 上则可能是一个基于 Program Files 的路径)。通过检查 CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT,CMake 脚本可以更加智能地处理这些平台差异,从而增强项目的可移植性。

在 CMake 脚本中使用 CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 的一个典型场景是,在项目配置阶段根据 CMAKE_INSTALL_PREFIX 是否被设置为默认值来设置一些额外的配置参数或执行一些特定的安装逻辑。例如:

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)# 如果 CMAKE_INSTALL_PREFIX 保持默认值,则设置一个新的安装前缀set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/install" CACHE PATH "${PROJECT_SOURCE_DIR}/install" FORCE)
endif()

在这个例子中,如果 CMAKE_INSTALL_PREFIX 没有被用户显式设置过,那么它将被设置为项目源代码目录下的 install 子目录。这提供了一种方便的方式来为用户提供一个默认的安装位置,同时仍然允许用户通过命令行参数或 CMake GUI 来覆盖这个默认值。

6 CMAKE_CXX_FLAGS

CMAKE_CXX_FLAGS 是一个在 CMake 中使用的变量,它用于指定编译 C++ 代码时传递给编译器的标志(flags)。这些标志可以控制编译器的行为,比如优化级别、警告级别、是否生成调试信息等。

在 CMakeLists.txt 文件中设置 CMAKE_CXX_FLAGS 变量,可以为整个项目设置默认的编译器标志。例如,如果你想增加编译时的警告级别,可以这样设置:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")

这里 -Wall 和 -Wextra 是 GCC 和 Clang 编译器用来增加警告级别的标志。

此外,CMake 还支持为不同的构建类型(如 Debug 和 Release)设置不同的编译器标志。这可以通过设置 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_CXX_FLAGS_RELEASE 等变量来实现。例如

# 为 Debug 构建类型设置编译器标志
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0")# 为 Release 构建类型设置编译器标志
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG")

在这个例子中,-g 标志用于生成调试信息,-O0 表示不进行任何优化,适用于 Debug 构建;而 -O2 表示进行中等级别的优化,-DNDEBUG 用于定义 NDEBUG 宏,通常用于禁用断言,适用于 Release 构建。

通过设置这些变量,开发者可以灵活地控制项目的编译行为,以满足不同的需求和目标。

7 execute_process

if (NOT IS_SYMLINK ${CMAKE_CURRENT_SOURCE_DIR}/install )# Note: we use WORKING_DIRECTORYexecute_process ( COMMAND ${CMAKE_COMMAND} -E remove_directory installCOMMAND ${CMAKE_COMMAND} -E create_symlink ../install installWORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}OUTPUT_QUIET ERROR_QUIET)
endif()

在 CMake 脚本中,您提供的代码段旨在检查 ${CMAKE_CURRENT_SOURCE_DIR}/install 是否为一个符号链接(symlink),如果不是,则执行两个命令:首先删除 install 目录(如果存在),然后创建一个指向 ../install 的符号链接。这里有几个要点需要注意:

  • 检查符号链接:

    CMake 本身没有直接的命令来检查一个路径是否是符号链接。通常,这种检查需要在脚本中使用平台特定的命令或脚本语言特性来完成。不过,在您的代码中,IF (NOT IS_SYMLINK ${CMAKE_CURRENT_SOURCE_DIR}/install) 这一行实际上是有问题的,因为 CMake 的标准语法中并没有 IS_SYMLINK 这样的判断。这意味着这行代码在 CMake 中不会按预期工作。

  • 删除目录和创建符号链接:

    execute_process 命令用于执行外部命令或脚本。在您的例子中,它用于执行 CMake 自带的 -E remove_directory 和 -E create_symlink 命令。这些命令分别用于删除目录和创建符号链接。

    WORKING_DIRECTORY
    此选项指定了 execute_process 命令的工作目录。在您的例子中,它被设置为 ${CMAKE_CURRENT_SOURCE_DIR},即当前 CMake 源目录。

    OUTPUT_QUIET ERROR_QUIET
    这些选项用于抑制命令的标准输出和错误输出。这意味着即使命令执行失败,用户也不会在 CMake 的配置输出中看到任何错误信息。

由于 IS_SYMLINK 不是 CMake 的有效命令或变量,您需要找到另一种方法来检查 install 是否为符号链接。这通常涉及到调用平台特定的命令(如 Unix 上的 test -L 或 Windows 上的 cmd /c dir /AL)并通过 execute_process 来捕获其结果。

以下是一个在 Unix 系统上检查符号链接的示例(注意,这只是一个概念验证,可能需要根据您的具体需求进行调整):

    execute_process(COMMAND test -L "${CMAKE_CURRENT_SOURCE_DIR}/install"RESULT_VARIABLE IS_SYMLINK_RESULTOUTPUT_QUIET ERROR_QUIET)if (NOT IS_SYMLINK_RESULT EQUAL 0)# Not a symlink or test command failed (not likely in this context)execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_SOURCE_DIR}/install"COMMAND ${CMAKE_COMMAND} -E create_symlink "../install" "${CMAKE_CURRENT_SOURCE_DIR}/install"WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}OUTPUT_QUIET ERROR_QUIET)endif()

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BUUCTF刷题-Web方向1~5wp

[极客大挑战 2019]EasySQL 一个sql注入登录框,直接万能密码登录拿到flag[极客大挑战 2019]Havefun 打开环境,没有任何信息,查看源码,发现这么一段代码GET方式传入一个cat请求,并且变量值为dog,即?cat=dog,得到flag[HCTF 2018]WarmUp 打开环境,是一张图片,查看源码发现…

99%的人不知道,桥接模式失败的真正原因是它!

前言 大家好,我是VoltCary 最近做一些基础设施的部署工作,以手上的kali linux作为集群的节点,因为用到的是虚拟机,且本机网络为无线wifi,现在希望虚拟机像正常独立主机存在网络中,因此不能像正常本地主机一样直接加入网段节点,虚拟机还需要进行网络的配置。 让虚拟机成为…

Orleans框架升级指南(3.6.5--8.0.0)

升级指南 官方升级指南 https://learn.microsoft.com/zh-cn/dotnet/orleans/migration-guide?source=recommendations主要涉及以下几个改动点ConfigureApplicationParts3.6.5版在Silo初始化的时候,会通过这个方法将指定目录下的Grain加载进来.ConfigureApplicationParts(part…

AtCoder Beginner Contest 386

A - Full House 2 题意给\(4\)个整数,问能否添加一个整数使得恰有\(3\)个整数\(a\)和\(2\)个整数\(b\)思路模拟代码点击查看代码 #include <bits/stdc++.h> using namespace std; #define int long long typedef pair<int, int> pii;const int mxn = 1e6 + 5;void…

Iceberg治理服务Amoro---配置Prometheus + Grafana看板

一、基础资料 1、mac安装Prometheus + Grafana https://www.cnblogs.com/robots2/p/18689540 2、配置文档 https://amoro.apache.org/docs/0.7.1/deployment/#configure-metric-reporter 3、Grafana配置内容 https://github.com/apache/amoro/blob/master/grafana/dashboard.js…

【Python】查找两个表格是否存在相同元素

其实就是字典的应用,把其中一个表格做成字典(将需要查询的元素设为字典的键),然后读取另一个表格逐个在字典中查找 表1:表2:import openpyxlwb1 = openpyxl.load_workbook(r"C:\Users\Lenovo\Desktop\表1.xlsx") ws1 = wb1["Sheet1"] wb2 = openpyxl…

git分支提交,提PR

远程分支xxx,临时分支tmp_xxx git checkout -b tmp_xxx   #创建并进入临时分支 git pull origin xxx      #更新本地code git add .          git commit -m "test pr" git push --set-upstream origin tmp_xxx #github上现在能看到这个临时…

Hibernate Validator 国际化开启快速校验配置

这里默认你已经配置好了国际化,如需配置可以参考 网上其他配置,这里只做快速失败国际化配置@Configuration public class ValidConfig {@Beanpublic Validator validator() {     // 这里是读取你的国际化配置文件做缓存MessageInterpolator messageInterpolator = new R…

AQS学习笔记

一、使线程进入等待状态和唤醒状态的三种方法 1、使用Object中的wait()方法让线程等待,使用Object中的notify()方法唤醒线程,需配合synchronized关键字使用 2、使用JUC包中的Condition的await()方法让线程等待,使用signal()方法唤醒线程 3、LockSupport类可以阻塞当前线程以…

Oracle安装指南 Xming远程桌面

安装Xming然后使用Oracle用户连接登录,设置DISPLAY环境变量(IP地址为你的windows客户端IP地址) export DISPLAY=192.168.111.155:0.0然后执行dbca就会弹出数据库配置界面了参考链接:https://www.cnblogs.com/iancloud/p/15015683.html

P4070 [SDOI2016] 生成魔咒

P4070 [SDOI2016] 生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符 \(1,2\) 拼凑起来形成一个魔咒串 \([1,2]\)。 一个魔咒串 \(S\) 的非空字串被称为魔咒串 \(S\) 的生成魔咒。 例如 \(S=[1,2,1]\) 时,它的生成魔咒有 \([1],[2],[1…

深入探讨触发器的创建与应用:数据库自动化管理的强大工具

title: 深入探讨触发器的创建与应用:数据库自动化管理的强大工具 date: 2025/1/24 updated: 2025/1/24 author: cmdragon excerpt: 触发器是一种强大的数据库对象,它能够在特定事件发生之前或之后自动执行一组SQL语句。作为一种自动化管理工具,触发器在许多数据库管理场景…