Java转C之CMake
对于一位从 Java 转到 C 或 C++ 的工程师,理解 CMake 和其指令非常重要,因为 CMake 是目前 C/C++ 项目中最常用的构建工具。CMake 本质上是一个跨平台的自动化构建系统,它通过 CMakeLists.txt
文件来管理和配置项目的构建过程。在学习 CMake 的过程中,理解常用的 CMake 指令是非常关键的。
下面我会详细介绍 CMake 中常见的指令,并结合表格和解释帮助你更好地理解它们。
CMake 指令概述
CMake 指令大致可以分为以下几类:
- 变量定义和赋值
- 添加和管理源文件
- 设置编译选项和链接
- 指定目标和生成输出
- 模块和文件操作
CMake 常用指令详解
1. set
— 设置变量
用于定义一个变量,并赋予它一个值。
指令 | 描述 | 示例 |
---|---|---|
set(VAR VALUE) | 设置一个变量 VAR 的值为 VALUE | set(CMAKE_CXX_STANDARD 11) |
set(VAR ${VAR} VALUE) | 将已有变量的值与新的值组合 | set(SOURCE_FILES main.cpp ${ADDITIONAL_SOURCES}) |
- 用途:
- 用于设置项目、编译器、工具链等的变量。
- 可以设置路径、文件列表、编译选项等。
2. add_executable
和 add_library
— 添加目标
指令 | 描述 | 示例 |
---|---|---|
add_executable(TARGET_NAME SOURCES...) | 创建一个可执行文件目标,并指定源文件。 | add_executable(my_program main.cpp) |
add_library(TARGET_NAME TYPE SOURCES...) | 创建一个库目标,类型可以是 STATIC 或 SHARED 。 | add_library(my_library STATIC src/foo.cpp src/bar.cpp) |
- 用途:
add_executable
用于添加一个可执行文件目标。add_library
用于添加一个库文件目标(静态库或动态库)。
3. include_directories
— 添加头文件路径
指定项目或目标的头文件搜索路径。
指令 | 描述 | 示例 |
---|---|---|
include_directories(DIR...) | 设置 C++ 或 C 编译器的头文件搜索路径 | include_directories(${PROJECT_SOURCE_DIR}/include) |
- 用途:
- 将头文件路径添加到编译器的搜索路径中,使得源代码能够找到外部的头文件。
4. link_directories
— 添加库路径
指定库文件的搜索路径。
指令 | 描述 | 示例 |
---|---|---|
link_directories(DIR...) | 添加库文件搜索路径 | link_directories(${PROJECT_SOURCE_DIR}/lib) |
- 用途:
- 设置链接器查找库的路径,告诉链接器去哪里查找依赖的库文件。
5. target_link_libraries
— 链接库文件
将库文件链接到目标(可执行文件或库)。
指令 | 描述 | 示例 |
---|---|---|
target_link_libraries(TARGET LIBRARY...) | 将目标与库文件链接 | target_link_libraries(my_program my_library) |
- 用途:
- 指定某个目标(可执行文件或库)依赖于哪些库,链接这些库以便正确构建目标。
6. include
— 引入外部 CMake 文件
引入外部的 CMake 配置文件。
指令 | 描述 | 示例 |
---|---|---|
include(FILENAME) | 包含一个外部的 CMake 配置文件或模块 | include(${PROJECT_SOURCE_DIR}/cmake/config.cmake) |
- 用途:
- 引入外部的 CMake 配置文件,使得当前的构建脚本可以复用这些外部的配置和逻辑。
7. add_definitions
— 添加编译器宏定义
为所有的源文件添加编译时宏定义。
指令 | 描述 | 示例 |
---|---|---|
add_definitions(DEFINITION...) | 为编译器添加宏定义,影响所有的编译单元 | add_definitions(-DUSE_DEBUG) |
- 用途:
- 用于定义编译器的预处理宏,例如定义调试宏、配置宏等。
8. message
— 输出信息
向控制台输出信息,常用于调试和输出状态信息。
指令 | 描述 | 示例 |
---|---|---|
message([<mode>] "message") | 向终端输出信息,mode 用于指定消息的级别 | message(STATUS "Configuring my_project...") |
- 用途:
- 向控制台输出调试信息、警告信息或错误信息,
mode
可以是STATUS
、WARNING
、ERROR
等。
- 向控制台输出调试信息、警告信息或错误信息,
9. if
/ else
/ endif
— 条件语句
用于在 CMake 文件中做条件判断。
指令 | 描述 | 示例 |
---|---|---|
if(CONDITION) | 判断条件是否成立 | if(WIN32) |
else() | 条件不成立时执行 | else() |
endif() | 结束条件语句块 | endif() |
- 用途:
- 根据不同的条件执行不同的构建逻辑,可以在项目配置中做平台检测、编译选项配置等。
10. project
— 设置项目名称和语言
用于定义项目的名称、版本及支持的编程语言。
指令 | 描述 | 示例 |
---|---|---|
project(PROJECT_NAME [LANGUAGES]) | 定义项目名称和支持的语言(如 C、C++) | project(MyProject LANGUAGES C CXX) |
- 用途:
- 定义项目的名称,设置支持的编程语言(例如 C、C++ 等)。
CMake 语法规则总结
语法组件 | 说明 | 示例 |
---|---|---|
变量定义 | 使用 set() 来定义和设置变量。 | set(MY_VAR 10) |
函数 | 使用 function() 和 endfunction() 来定义函数。 | function(my_function) ... endfunction |
条件语句 | 使用 if() 、else() 和 endif() 来判断条件。 | if(WIN32) ... endif() |
循环 | 使用 foreach() 和 endforeach() 来进行循环。 | foreach(file IN LISTS FILES) ... endforeach() |
注释 | 使用 # 来添加注释。 | # This is a comment |
如何理解 CMake 中的指令
-
变量和函数:
CMake 脚本本质上是一种声明式语言,它通过变量来存储值、路径、文件列表等信息。你可以使用set()
来定义变量,使用get()
来获取变量值。通过function()
和macro()
来定义自定义的函数或宏,以简化配置过程。 -
条件和逻辑:
if()
、else()
、elseif()
、endif()
等指令用于执行基于条件的操作,类似于其他编程语言中的条件语句。它们在配置中非常常用,用于判断平台、配置和编译选项。 -
模块化构建:
使用include()
来将模块化的 CMake 配置文件引入到主构建脚本中,方便代码复用。add_subdirectory()
用于包含子目录,这使得大项目的管理更加清晰。 -
构建目标:
add_executable()
和add_library()
指令用来创建目标(可执行文件或库),并指定源文件。这是构建项目的核心步骤。
总结
CMake 是一个强大的工具,通过其指令可以灵活地配置 C 或 C++ 项目的构建过程。你可以定义变量、设置编译选项、添加目标、管理源文件、条件编译等等。对 Java 工程师而言,CMake 提供的构建管理方式类似于 Maven 或 Gradle,但它更侧重于底层的构建控制。理解这些指令
相关文章:

Java转C之CMake
对于一位从 Java 转到 C 或 C 的工程师,理解 CMake 和其指令非常重要,因为 CMake 是目前 C/C 项目中最常用的构建工具。CMake 本质上是一个跨平台的自动化构建系统,它通过 CMakeLists.txt 文件来管理和配置项目的构建过程。在学习 CMake 的过…...

如何自己创建database.js文件来初始化本地sqlite数据库
如何自己创建database.js文件来初始化本地sqlite数据库!下面是一个案例展示,帮助大家,快速的视线,本地sqlite数据库信息初始化。 为了使用 database.js 文件初始化 SQLite 数据库并存储解签内容,你需要按以下步骤操作。…...

【汇编语言】内中断(三) —— 中断探险:从do0到特殊响应的奇妙旅程
文章目录 前言1. do01.1 do0程序1.2 存放字符串,得到完整的程序1.3 分析初步完成的程序1.4 正确的完整程序1.5 分析正确的完整程序 2. 设置中断向量3. 单步中断3.1 什么是单步中断?3.2 CPU为什么要提供单步中断3.2.1 思考一下Debug功能3.2.2 Debug是如何…...

0006.基于SpringBoot+element付费问答系统
适合初学同学练手项目,部署简单,代码简洁清晰; 愿世界和平再无bug 一、系统架构 前端:vue| elementui 后端:springboot | mybatis-plus 环境:jdk1.8 | mysql | maven 二、登录角色 1.管理员 2.用户 …...

SpringBoot feign基于HttpStatus重试
场景 基于springboot开发的项目,对接第三方,第三方的接口有限流策略,某个时间段内有调用频率限制,返回的状态码HttpStatus不是200,而HttpStatus是429。现基于HttpStatus我们发起的重试。 技术点 springbootfeign fe…...

【记录49】vue2 vue-office在线预览 docx、pdf、excel文档
vue2 在线预览 docx、pdf、excel文档 docx npm install vue-office/docx vue-demi0.14.6 指定版本 npm install vue-office/docx vue-demi <template><VueOfficeDocx :src"pdf" style"height: 100vh;" rendere"rendereHandler" error&…...

正则表达式中^的用法
正则表达式中^的用法 1.用法一: 限定开头 文档上给出了解释是匹配输入的开始,如果多行标示被设置成了true,同时会匹配后面紧跟的字符 比如 /^A/会匹配"An e"中的A,但是不会匹配"ab A"中的A 比如(\s|^)表示空字符串或字…...

WPF 关于界面UI菜单权限(或者任意控件的显示权限)的简单管理--只是简单简单简单简单
1.定义你的User类 public class User{public User(){ID ObjectId.NewObjectId().ToString();}public string? ID { get; set; }public string? Account { get; set; }public string? Password { get; set; }public string? PasswordMD5 { get; set; }public AccountType?…...

Https身份鉴权(小迪网络安全笔记~
附:完整笔记目录~ ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正! 5.2 Https&身份鉴权 引子:上一篇主要对Http数据包结构、内容做了介绍,本篇则聊聊Https、身份鉴权等技术。 …...

AngularJS 输入验证
AngularJS 输入验证 AngularJS 是一个强大的 JavaScript 框架,它允许开发者构建动态的、高性能的 Web 应用程序。在处理用户输入时,确保数据的准确性和完整性至关重要。AngularJS 提供了一套内置的输入验证机制,可以帮助开发者轻松地实现这一目标。 为什么需要输入验证? …...

【网络安全】WIFI WPA/WPA2协议:深入解析与实践
WIFI WPA/WPA2协议:深入解析与实践 1. WPA/WPA2 协议 1.1 监听 Wi-Fi 流量 解析 WPA/WPA2 的第一步是监听 Wi-Fi 流量,捕获设备与接入点之间的 4 次握手数据。然而,设备通常不会频繁连接或重新连接,为了加速过程,攻…...

前端使用xlsx-js-style导出Excel,带样式,并处理合并单元格边框显示不全和动态插入表头解决
一、在学习之前,先给出一些学习/下载地址: xlsx-js-style下载地址 https://github.com/gitbrent/xlsx-js-style 或者 https://www.npmjs.com/package/xlsx-js-style SheetJS中文教程: https://xlsx.nodejs.cn/docs/csf/cell 二、先看样…...

自动化工具ansible部署和实践
1 介绍和部署 1.1 介绍 ansible的功能 我爱你在当今的IT自动化领域,Ansible无疑是一个无法被忽视的重要角色。其便利性和高效性受到了广大开发者和系统管理员的一致好评,成为了配置管理和应用部署的首选工具。然而,对于一些初学者来说&#…...

无人机推流直播平台EasyDSS视频技术如何助力冬季森林防火
冬季天干物燥,大风天气频繁,是森林火灾的高发期。相比传统的人力巡查,无人机具有更高的灵敏度和准确性,尤其在夜间或浓雾天气中,依然能有效地监测潜在火源。 无人机可以提供高空视角和实时图像传输,帮助巡…...

React Fiber
React Fiber 是 React 16 引入的全新重写的协调(Reconciliation)算法的实现,旨在改善 React 的更新机制和性能,尤其是在复杂应用和大量更新的场景下。它使得 React 更加灵活、可调度,能够实现优先级控制和中断更新等特…...

【前端】JavaScript 中的 map() 方法:高级解析与应用
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯map() 方法的定义与核心特性1.1 方法定义1.2 主要特性 💯map() 方法的语法与高级用法2.1 基本语法2.2 简化写法与箭头函数2.3 结合链式操作 💯ma…...

《智能体开发实战(高阶)》四、系统化的日志周报智能体开发计划
智能体扩展与完善规划 为了将前几个章节的智能体逐步扩展为支持整个公司团队使用的高效工具,以下是分阶段的完善与扩写规划。每个阶段旨在提升功能覆盖范围、处理能力和用户体验,并为企业提供实际价值。 阶段一:基础功能完善 目标:巩固现有功能,提升健壮性和适用性。 支…...

什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球最受欢迎的Web服务器软件,支持约30.2%的所有活跃网站。凭借其可靠性、灵活性和强大的功能,Apache数十年来一直是互联网的中坚力量。 一、Apache Web服务器的工作原理 Apache Web服务器的工作原理如下: 接收HTTP请求࿱…...

Mybatis——(2)
2.2 Mybatis 工具类(了解) 为了简化MyBatis的开发,可将MyBatis进一步封装。 import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apa…...

景联文科技入选中国信通院发布的“人工智能数据标注产业图谱”
近日,由中国信息通信研究院、中国人工智能产业发展联盟牵头,联合中国电信集团、沈阳市数据局、保定高新区等70多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业,入选图谱中技术服务板块。…...

修改浏览器地址栏参数
Vue 修改当前页面地址栏参数 function updateUrlParameter(param: string, value: string) {const url new URL(window.location.href); // 获取当前页面的 URL// 解析哈希部分const hash url.hash ? url.hash.slice(1) : "";const [path, queryString] hash.sp…...

Spring Boot教程之二十五: 使用 Tomcat 部署项目
Spring Boot – 使用 Tomcat 部署项目 Spring Boot 是一个基于微服务的框架,在其中创建可用于生产的应用程序只需很少的时间。Spring Boot 建立在 Spring 之上,包含 Spring 的所有功能。如今,它正成为开发人员的最爱,因为它是一个…...

解决 Git 默认不区分文件名大小写的问题
不得不说 Git 默认不区分文件名大小写真是一个大坑,由于之前的项目目录比较乱,项目下的文件夹命名都不规范,这两天一直在整理,然后今天从服务器将项目重新 clone 下来后发现,之前将所有文件名首字母改成大写的改动全部…...

python学opencv|读取图像(十二)BGR图像转HSV图像
【1】引言 前述已经学习了opencv中图像BGR相关知识,文章链接包括且不限于下述: python学opencv|读取图像(六)读取图像像素RGB值_opencv读取灰度图-CSDN博客 python学opencv|读取图像(七)抓取像素数据顺利…...

信息安全工程师-选择题考点总结
密码理论知识 基础理论 一个密码系统至少由明文、密文、加密算法、解密算法和密钥五个部分组成,而其安全性是由密钥决定的。 按照密钥特征的不同,密码体制分为:对称密码体制和非对称密码体制。 按照对明文加密方式的不同,密码体制分为:流密码和分组密码。 非对称密码体…...

重学SpringBoot3-WebClient配置与使用详解
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-WebClient配置与使用详解 1. 简介2. 环境准备2.1 依赖配置 3. WebClient配置3.1 基础配置3.2 高级配置3.3 retrieve()和exchange()区别 4. 使用示例4.1 …...

springBoot中的日志级别在哪里配置
在Spring Boot中,日志级别的配置可以通过多种方式来实现,主要包括在配置文件中设置、使用自定义的logback配置文件,以及在代码中动态配置等。以下是一些具体的配置方法: 一、在配置文件中设置日志级别 Spring Boot默认使用appli…...

统一身份安全管理体系的业务协同能力
随着集团企业数字化组织转型深化,各组织机构间业务协同程度提升。研发业务协同、数据驱动生产决策等数字化生产协作工作体系得以展开,企业内数据流转加快。企业对统一身份安全管理体系的业务协同管理和支撑能力要求提升: 统一身份管理流程需…...

JAVA课堂笔记23(IO流 (java.io包中))
第五章:IO流 (java.io包中) 三、字符流 1. 字符流的父类(抽象类): Reader:字符输入流 对应的操作为读操作 功能方法:read方法 Writer:字符输出流 对应的操作为写操作 功能方法:write方法 …...

C# DLT645 97/07数据采集工具
电表模拟器 97协议测试 07协议测试 private void btnSend_Click(object sender, EventArgs e) {string addr txtAddr.Text.Trim();string data txtDataFlg.Text.Trim();byte control 0x01;switch (cmbControl.SelectedIndex){case 0: control (byte)0x01; break;// 97协议c…...