一篇文章搞懂CMake(gcc、g++、cmake解释)

news2024/12/21 6:52:39

一篇文章搞懂CMake (gcc、g++、cmake解释)

这里写目录标题

  • 一篇文章搞懂CMake (gcc、g++、cmake解释)
    • gcc
    • g++
    • cmake
      • 1. CMake 流程
      • 如何使用cmake?
        • 简单的CMake.txt文件
    • 参考

gcc

gcc命令来自英文词组“GNU Compiler Collection”的缩写,其功能是用于C/C++语言编译器。原文链接:https://www.linuxcool.com/gcc

GCC 的编译流程包括以下几个阶段:

  • 预处理(Preprocessing):对源代码进行宏替换、头文件展开等操作,生成预处理文件(.i 文件)。
  • 编译(Compilation):将预处理文件转换为汇编代码(.s 文件)。
  • 汇编(Assembly):将汇编代码转换为目标文件(.o 文件)。
  • 链接(Linking):将目标文件与库文件等链接起来,生成可执行文件。

下面是一个简单的示例,以 C 语言为例:

#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}

我们可以使用以下命令编译:

gcc hello.c -o hello

这个命令将进行以下几个步骤:

  1. 预处理,还是c语言文件,但是对头文件(<stdio.h>)和宏会进行展开
gcc -E hello.c > hello.i # 和 gcc -E hello.c -o hello.i 效果是一样的
  1. 编译,由c文件变成汇编文件
gcc -S hello.i -o hello.s
  1. 汇编,生成目标文件,即二进制文件,但是此时的文件是没有链接的,不可以执行
gcc -c hello.s -o hello.o
  1. 链接,生成可执行文件
gcc hello.o -o hello

运行该文件会输出 “Hello, world!”。

g++

gcc和g++是两个不同的编译器,gcc主要用于编译C语言代码,g++则主要用于编译C++代码

虽然gcc也可以编译C++代码,但是使用g++更为方便。因为g++可以自动链接C++标准库,而gcc需要手动链接C++标准库。此外,g++还能够自动识别C++代码,并调用相应的编译器。

在使用g++编译C++代码时,需要使用“.cpp”作为文件扩展名。如果使用“.c”作为文件扩展名,g++会将代码识别为C语言代码进行编译,而不是C++代码。

参考: https://www.cnblogs.com/lulipro/p/6661763.html

编译流程和 gcc 是一样的,只需要把 gcc 换成 g++ 即可

  • -save-temps 保留编译产生的中间文件,使用这个参数,就没必要将前面的参数 -E -S -c 一个一个地使用了
g++ -save-temps -o hello hello.cpp 
  • 优化器
g++ -O2 hello.cpp -o hello

-O0: 不进行优化,编译速度最快,但是生成的可执行文件执行速度最慢。
-O1: 开启一些简单的优化,会消耗更多的编译时间,但是可以稍微提高可执行文件的执行速度。
-O2: 开启更多的优化,可以提高可执行文件的执行速度,但是编译时间也会更长。
-O3: 开启大部分优化,可以极大地提高可执行文件的执行速度,但是编译时间也会非常长。
-Os: 优化可执行文件的大小,尽可能减小生成的可执行文件的体积。

一般用O2就够了,可以看到下面的这段代码,写的非常不合理,但是经过优化之后效率高了很多

  • -w
    编译时,不显示任何警告消息。

  • -Wall
    编译时,显示所有出现的警告消息。

cmake

CMake是一个跨平台的自动化构建系统,可以根据不同的平台、不同的编译器,生成相应的构建文件(如Makefile或Visual Studio项目文件等),以便进行编译、链接等操作。CMake通过CMakeLists.txt 文件来描述项目的构建过程,用户可以在这个文件中定义源代码、库、头文件、编译选项等信息,从而让CMake自动生成相应的构建文件。

举个例子: 比如说有一个项目需要跨平台,windows 下用 VS 编译,linux 下用 makefiles 或者 xcode 编译。如果这时候需要添加一个 bar.cpp 文件,一般做法就是每个IDE的项目文件中依次添加,但是如果工程太大,这种做法就很麻烦了,因此引入cmake就是为了方便,只需要把 bar.cpp 添加到 CMakeLists.txt 文件中即可。

1. CMake 流程

在 gcc小节 中给出了程序生成可执行文件的流程,但是如果程序很多的时候,这种方式就显得太繁琐了。因此就需要用到 makefile,makefile 是一种能够自动化构建和编译项目的文本文件。简单来说只要存在 makefile文件, make 一下就能完成项目的编译工作。

但是夸平台的话,新的矛盾就会显现出来,makefile 通常依赖于当前的编译平台,而且编写 makefile 的工作量比较大,解决依赖关系时也容易出错。

因此 CMake 能够解决该问题,它能跟据不同的编译平台,自动生成 Makefile 文件,流程如下:

如何使用cmake?

简单的CMake.txt文件

CMake 最基本的步骤是以下三步:

# 最低 CMake 版本要求:指定项目所需的最低 CMake 版本
cmake_minimum_required(VERSION 3.12)

# 项目名称:使用 project() 命令设置项目的名称
project(MyProject)

# 将源文件添加到项目中
add_executable(myapp main.cpp)

举个例子

创建以下几个文件

add.c

#include <stdio.h>
#include "head.h"

int add(int a, int b)
{
    return a+b;
}

div.c

#include <stdio.h>
#include "head.h"

double divide(int a, int b)
{
    return (double)a/b;
}

head.h

#ifndef _HEAD_H
#define _HEAD_H
// 加法
int add(int a, int b);
// 减法
int subtract(int a, int b);
// 乘法
int multiply(int a, int b);
// 除法
double divide(int a, int b);
#endif

main.c

#include <stdio.h>
#include "head.h"

int main()
{
    int a = 20;
    int b = 12;
    printf("a = %d, b = %d\n", a, b);
    printf("a + b = %d\n", add(a, b));
    printf("a - b = %d\n", subtract(a, b));
    printf("a * b = %d\n", multiply(a, b));
    printf("a / b = %f\n", divide(a, b));
    return 0;
}

head.h

#include <stdio.h>
#include "head.h"

int multiply(int a, int b)
{
    return a*b;
}

sub.c

#include <stdio.h>
#include "head.h"

// 你好
int subtract(int a, int b)
{
    return a-b;
}

建立相关文件并保存

在同一目录下新建一个 CMakeLists.txt 文件
输入下面内容并保存:

# 最小版本
cmake_minimum_required(VERSION 3.0)
# 工程名
project(Test)
# 将所有相关文件都添加进来,用于编译
add_executable(myapp add.c div.c main.c mult.c sub.c)

文件结构如下:

我们在当前文件下执行下面的操作:

1.建立一个文件夹,因为cmake之后会生成很多文件

mkdir bulid

2.进入到新建文件夹中

cd bulid

3.执行 cmake 生成 Makefile

cmake ..

cmake指令需要在和 CMakeLists.txt 文件同一个目录下执行,因此需要…

cmake之后我们发现在build文件夹下多了 Makefile 以及其他文件

4.执行 make 指令生成可执行文件

make

5.执行文件,测试是否编译成功

至此一个简单的 cmake 编译过程就结束了。

参考

[1] https://subingwen.cn/cmake/CMake-primer/?highlight=cmake

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.C++多线程-- unique_lock(类模板)

1.unique_lock 1. unique_lock<mutex> myUniLock(myMutex); 完全可以取代lock_guard 2. unique_lock 也可以使用----std::adopt_lock 3.使用adopt_lock&#xff0c;之前要先使用lock. 4.std::chrono::milliseconds my_sleepTime(20000)//20000毫秒 std::this_thread:…

运维小白必学篇之基础篇第十一集:系统进程实验

系统进程实验 实验作业&#xff1a; 1、利用top命令查看当前系统进程&#xff0c;要求没5秒刷新一次&#xff0c;分别按照CPU使用率&#xff0c;内存使用量&#xff0c;CPU使用时间&#xff0c;PID分别排序一次 每5秒刷新一次&#xff1a;top -d 5 按照CPU使用率排序&#xf…

【python】如何入门python?

文章目录 前言一、为什么学习Python&#xff1f;二、学习Python的前置条件三、入门Python的步骤3.1 安装Python3.2 安装Python开发环境3.3 学习Python基础语法3.4 编写你的第一个Python程序3.5 学习Python的高级特性3.6 使用Python库和框架 四、Python入门的资源五、常见的Pyth…

allure报告中如何让测试步骤更清晰

一、allure step测试用例步骤说明 allure step编写测试用例有两种方式 1、with allure.step()用在测试用例中 公共方法代码&#xff1a; # common_fucntion.py import allure import pytest from common.tools.log_util import LoggerrunlogLogger().get_log流程性的用例&a…

【FMC129】 基于JESD204B接口的8通道125MSPS 16位AD采集FMC子卡

板卡概述 FMC129是一款8通道125MHz采样率16位AD采集FMC子卡&#xff0c;符合VITA57.1规范&#xff0c;可以作为一个理想的IO模块耦合至FPGA前端&#xff0c;8通道AD通过高带宽的FMC连接器&#xff08;HPC&#xff09;连接至FPGA从而大大降低了系统信号延迟。 该板卡支持板上可编…

git commit之前,没有pull最新代码,导致无法push代码如何解决?——git三板斧

一、报错&#xff1a; 如果在 git commit 之前没有 pull 最新代码&#xff0c;再进行 push 操作可能会出现冲突&#xff0c;导致无法 push 代码。此时&#xff0c;git 会提示类似以下的错误信息&#xff1a; error: failed to push some refs to gitgithub.com:username/repo…

OSSIM进行主机漏洞扫描(03)

OSSIM进行主机漏洞扫描方式 按照如图选择&#xff0c;ENVIRONMENT–SCAN JOBS–NEW SCAN JOB进入新增页面 其中各选项含义如下 Job Name:扫描任务名称。 Select Sensor:扫描的嗅探器。 Profile:扫描的类型&#xff0c;包括Deep- Non destructive Full and Slow scan(深入)、D…

【完整版】2023二级建造师《建筑实务》真题答案解析(2天考3科)

2023二级建造师考试将在6月3日、4日举行&#xff0c;2023二建《市政实务》考试时间&#xff08;2天考3科&#xff09;&#xff1a;6月4日 9:00-12:00&#xff0c; 考后甘建二将及时发布2023年二建市政实务真题及答案解析&#xff0c;敬请关注 2天考3科地区&#xff1a;四川、山…

1个月1000家店,库迪起飞

5月30日最新消息&#xff0c;库迪咖啡第3000家门店在北京开业。 从2022年10月到4月&#xff0c;半年开了2000家。4月到5月更夸张&#xff0c;1个月开了一千家店。 这就是库迪速度&#xff0c;线下疯狂扩张&#xff0c;线上也没闲着。 今天在抖音本地生活热销榜&#xff0c;大…

华为OD机试题【导师请吃火锅】【2023 B卷 100分】

文章目录 &#x1f3af; 前言&#x1f3af; 题目描述&#x1f3af; 解题思路&#x1f4d9; Python实现代码&#x1f4d7; Java实现代码&#x1f4d8; C语言实现&#xff1a; &#x1f3af; 前言 &#x1f3c6; 《华为机试真题》专栏含2023年牛客网面经、华为面经试题、华为OD机…

5 从Win32过度到MFC

文章目录 配置设置建立MFC工程的三部曲1.建立CWinApp 类的派生类2.重写CWinApp3.定义CWinApp派生类的全局变量全部代码 添加对话框资源创建窗口类继承CDialog 导入资源文件修改资源文件ID加载资源文件 全部代码 配置设置 建立MFC工程的三部曲 1.建立CWinApp 类的派生类 class…

四、初探[ElasticSearch]集群架构原理与搜索技术

目录 一、浅析Elasticsearch架构原理1.Elasticsearch的节点类型1.1 Master节点1.2DataNode节点 二、分片和副本机制2.1分片2.2副本2.3指定分片、副本数量2.4查看分片、主分片、副本分片 三、Elasticsearch工作流程3.1Elasticsearch文档写入原理3.2Elasticsearch检索原理 四、El…

Java开发手册中为什么要求三目运算符必须要注意类型对齐

场景 java开发手册中对于三目运算符的使用要求如下: 【强制】三目运算符 condition? 表达式 1 : 表达式 2 中&#xff0c;高度注意表达式 1 和 2 在类型对齐时&#xff0c; 可能抛出因自动拆箱导致的 NPE 异常。 说明&#xff1a;以下两种场景会触发类型对齐的拆箱操作&am…

华为路由器 NAT 配置

拓扑图 静态 NAT 静态地址转换是指外部网络和内部网络之间的地址映射关系由配置确定&#xff0c;该方式适用于内部网络与外部网络之间存在固定访问需求的组网环境。静态地址转换支持双向互访&#xff1a;内网用户可以主动访问外网&#xff0c;外网用户也可以主动访问内网。 一…

2023国际管理会计教育联盟发展论坛在沪成功召开

2023年5月7日&#xff0c;由教育部中外人文交流中心、国际管理会计教育联盟&#xff08;下称“联盟”&#xff09;主办&#xff0c;中国商业会计学会、上海交通大学安泰经济与管理学院承办的2023国际管理会计教育联盟发展论坛&#xff08;下称“发展论坛”&#xff09;在上海成…

第4章:SpringMVC的域对象共享数据

1、使用ServletAPI向request域对象共享数据 ①控制器 Controller public class HelloController {RequestMapping("/test")public String index(HttpServletRequest request){request.setAttribute("test","test666");return "index"…

避坑之网上下单的手机流量卡为什么老是失败!

最近有一些小伙伴们反应&#xff1a;在网上下单的手机流量卡&#xff0c;经常提示下单失败&#xff0c;不是这问题就是那问题的。 对于小伙伴们的诉求&#xff0c;小编向来是来者不拒的。今天就为大家整理一下下单失败的四大原因。 失败原因一&#xff1a;下单信息填写错误 下…

javax.validation常用注解

javax.validation 提供了一系列的注解&#xff0c;用于在 Java Bean 中对属性进行验证&#xff0c;主要有以下几种&#xff1a; NotNull&#xff1a;验证对象不可为 null&#xff1b;NotEmpty&#xff1a;验证字符串&#xff0c;数组&#xff0c;Collection&#xff0c;Map不可…

软件工程期末题目分析

一、软件工程概论 1.当你准备参与开发一个系统的时候&#xff0c;如果你对这个系统的问题领域不是很熟悉&#xff0c;那么最好不要采用以下哪种系统开发模型&#xff1f;&#xff08;A&#xff09; A、瀑布模型B、原型模型C、螺旋模型D、喷泉模型 瀑布模型模型要求用户需求明…

Selenium浏览器自动化怎么上传文件

Selenium 封装了现成的文件上传操作。但是随着现代前端框架的发展&#xff0c;文件上传的方式越来越多样。而有一些文件上传的控件&#xff0c;要做自动化控制会更复杂一些&#xff0c;这篇文章主要讨论在复杂情况下&#xff0c;如何通过自动化完成文件上传。 1. input 元素上传…