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多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业,入选图谱中技术服务板块。…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
