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多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业,入选图谱中技术服务板块。…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
