(三)CMake为什么几乎一统C++跨平台构建?

2024-01-13 21:52

本文主要是介绍(三)CMake为什么几乎一统C++跨平台构建?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

先看几个简单的例子再回头来看这个问题
回想一下当我们用windows写C++第一个Hello World!的步骤,先用VS IDE 创建一个控制台的工程,IDE 会自动生成一个 cpp 文件,里面有一句 输出"Hello World!" 代码,这个时候按下F5 就可以启动调试,一个黑乎乎的控制台窗口上显示了"hello world"

#include <iostream>
int main()
{std::cout << "Hello World!\n";
}

所有人都把注意力放在了这个cpp文件上,几乎不会有人关注工程文件,无论是VS 生成的工程还是 XCode生成的工程。那这个工程文件有什么作用呢?

组织代码文件

工程文件定义了项目的结构,包括项目中的源文件、头文件、资源文件等的组织方式们,我们可以在IDE 上查看和管理项目的所有文件,组织代码文件的结构

配置项目属性

工程文件中包含了项目的配置选项,如编译器选项、链接器选项、预处理器选项,头文件包含选项等。

编译和构建项目

工程文件定义了项目的编译和构建过程。源代码文件只有加入到了工程中才能参与编译, 可以在工程中指定项目中的源文件、库文件、依赖项等,并设置编译器和构建工具的参数,从而进行项目的编译和构建。

调试

所有的开发者一定会用到的核心功能,有了工程文件我们才能用IDE来打开工程,然后一键方便调试。当然不使用IDE 也能调试,但是极其的麻烦,对于客户端开发来说调试是基础技能。

所以工程文件有巨大的作用,特别是项目大的时候。谈到了这么多工程文件的作用,那和CMake 有什么关系呢?

再继续说一下跨平台的C++ 开发,C++一个巨大特点 一次编写多个平台编译。既然要编译那就需要有“规则”,无论是以前的makefile 文件还是工程文件都是在制定这个规则并且按照规则来编译。在CMake 之前也有很多的制定“规则“的工具,而CMake和他们最大的不同是可以生成各个 IDE 的工程文件,然后使用IDE 软件打开工程文件就可以一站式编写代码,调试代码。CMake 的语法非常简单,可以直接在CMake 中制定各种规则,然后生成各个IDE 的工程。
当有多个人共同开发项目的时候工程文件是最容易冲突的,并且工程文件一般都会比较大,格式很复杂,当出现冲突的时候解决起来也是非常的麻烦。而CMake 可以消除工程文件的冲突,因为使用CMake 根本不需要将工程文件push到代码仓库中,各个开发者将代码pull到本地之后执行一下CMake脚本就可以生成工程文件。 虽然CMakeLists.txt 文件本身也会存在冲突,但是这个就非常容易解决。

2 CMake 特点

2.1 生成不同的IDE 工程文件

CMake 可以根据用户的操作系统和目标平台生成不同的构建系统文件,如 Makefile、Ninja 等,VS 的project, XCode 工程,QT 也支持CMake导入工程。

2.2 支持丰富的IDE

CMake 会根据操作系统列出所有支持的IDE以及工程文件,并且还可以自定义编译交叉编译工具链。在这里插入图片描述

2.3 提供跨平台的命令和变量

CMake 的语法很简单,CMake 提供了丰富的命令和变量来制定编译链接规则,可以使用这些命令和变量来描述项目的构建过程和依赖关系,而不需要关心具体的平台细节。这样一来,开发者可以使用相同的 CMake 配置文件在不同的操作系统上进行构建,实现跨平台统一构建。

自动化依赖管理

CMake 能够自动管理项目的依赖关系,包括库文件、头文件、编译选项等。我们只需要在 CMake 配置文件中指定依赖,并在项目中引用这些依赖。

3 CMake 示例

以下是一个使用CMake生成一个C++ helloworld示例的步骤:

  1. 创建一个文件夹用于存放项目文件,例如helloworld_project
  2. helloworld_project文件夹中创建一个CMakeLists.txt文件,内容如下:
cmake_minimum_required(VERSION 3.10)project(helloworld)add_executable(helloworld main.cpp)
  1. helloworld_project文件夹中创建一个main.cpp文件,内容如下:
#include <iostream>int main() {std::cout << "Hello, World!" << std::endl;return 0;
}
  1. 打开命令行,cd 到 helloworld_project 目录下,执行命令就可以生成vs2022 的工程文件了。
cmake . -G"Visual Studio 17 2022" -B./build

如果需要将上面的工程放到其他平台编译,也只需要在其他平台执行一下CMake 命令就可以了。

这篇关于(三)CMake为什么几乎一统C++跨平台构建?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/602917

相关文章

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python利用PySpark和Kafka实现流处理引擎构建指南

《Python利用PySpark和Kafka实现流处理引擎构建指南》本文将深入解剖基于Python的实时处理黄金组合:Kafka(分布式消息队列)与PySpark(分布式计算引擎)的化学反应,并构建一... 目录引言:数据洪流时代的生存法则第一章 Kafka:数据世界的中央神经系统消息引擎核心设计哲学高吞吐

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c