一篇文章搞懂CMake(gcc、g++、cmake解释)_cmake和gcc-程序员宅基地

技术标签: C/C++  c++  Linux  linux  Ububtu  开发语言  

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

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011895157/article/details/131052194

智能推荐

mysql dwith boost_linux下Mysql 8.0.19 编译安装-程序员宅基地

文章浏览阅读951次。1 前言linux下安装MySQL的方式有很多种,包括以仓库的方式安装(yum,apt,zypper),以包的方式安装(rpm,deb),以docker方式安装,从压缩包解压安装,从源码编译安装,这里使用的是最后一种,从源码编译安装。编译安装需要大量的耐心与时间,而且还会遇到非常多奇奇怪怪的问题,因此,需要极大的毅力,很有可能一万次失败也换不来一次的成功,请做好心理准备。2 准备工作下面是安装要求..._mysql dwith boost

mysql 高级(进阶学习)_mysql高级进阶-程序员宅基地

文章浏览阅读1.4k次,点赞2次,收藏8次。视图就是将某个查询语句存储在数据中,并为其命名,视图中并不存储数据,数据还是在基本表中存储。定义视图使用视图删除视图存储过程就是把一段处理逻辑存入到数据库中,使用是就由 JDBC 调用即可。调用存储过程可以减少应用程序和数据库交互次数,在数据库内部执行,执行效率高。存储事先需要定义,有三种参数类型:in 入参(接收调用者传入的数据)out 返回(向调用者返回数据)inout (既可以接收调用者传入的数据,也可以向调用者返回数据)函数是一个特殊的存储过程。存储过程不仅有输入参数,还有输出参数,但是没有返回值,_mysql高级进阶

goquery php,golang:Goquery简单爬虫实例-程序员宅基地

文章浏览阅读189次。Selection类型提供的方法,这些方法是页面解析最重要,最核心的方法1)类似函数的位置操作-Eq(indexint)*Selection//根据索引获取某个节点集-First()*Selection//获取第一个子节点集-Last()*Selection//获取最后一个子节点集-Next()*Selection..._goquery获取tbody的数据

计算机资源库在哪,电脑的资源管理在哪里-程序员宅基地

文章浏览阅读2.7k次。语音内容:大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。电脑的资源管理的位置:1、单击开始菜单,在弹出的快捷菜单中选择文件资源管理器。2、按组合键Win+R打开运行窗口。3、在运行窗口中输入命令:explorer按回车键执行命令即可以打开资源管理器窗口。4、在桌面的任务栏上右击鼠标,在弹出的快捷菜单中选择“任务管理器。5、在任务管理器的菜单栏中选择文件中运行新任务。6、在运行..._计算机库到哪里找

适合新手的CTF靶场合集-程序员宅基地

文章浏览阅读3.4w次,点赞42次,收藏344次。前言我整理得没有那么全,这里的合集主要还是面对新手。做题贵精不在多,好好练习每一题,学习每个知识点,不懂的百度或者 Google 即可。记住,你是为了提高自己而去打 CTF 。CTF 比赛时间表CTFwiki(入门必看wiki): https://ctf-wiki.github.io/ctf-wiki/#/introduction XCTF社区: https://time.xctf...._ctf靶场

彻底理解位运算——左移、右移_左移和右移-程序员宅基地

文章浏览阅读6.2w次,点赞168次,收藏598次。相信大家在各种语言各种框架中都能看到二进制的操作。左移、右移、&、|、^等等操作。那么这篇帖子让各位彻底弄懂左移、右移。首先先区分那个是左移、那个是右移,这很简单,从箭头指向的方向来区分。右移左移:很简单的来说就是把当前的二进制,整体往左边移动N个单位,N取决于你的表达式。那么用一个例子,和画图来理解一下吧。32 ..._左移和右移

随便推点

对于以太坊的反思,美链,课程总结_学习以太坊感受-程序员宅基地

文章浏览阅读2k次。反思与总结_学习以太坊感受

Docker安装MySQL、nginx并且部署SpringBoot项目前后端(超详细版)_docker desktop 整合 nginx 和spring-程序员宅基地

文章浏览阅读1.4k次,点赞24次,收藏16次。超级详细的Docker部署Springboot项目的步骤,大家只需要按照文档一步一步的复制粘贴即可。_docker desktop 整合 nginx 和spring

Freescale I.mx 6 Android 4.2.2源码编译环境搭建(基于ubuntu12.04 LTS)_note, selecting 'lib32z1-dev' instead of 'lib32z-d-程序员宅基地

文章浏览阅读2.9k次。Freescale I.mx 6 Android 4.2.2源码编译环境搭建 1 安装必要的第三方工具:$ sudo apt-get install git gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \ x11proto-_note, selecting 'lib32z1-dev' instead of 'lib32z-dev

大数据存储架构详解:数据仓库、数据集市、数据湖、数据网格、湖仓一体_数据仓库 数据集市 数据湖-程序员宅基地

文章浏览阅读1.3w次,点赞7次,收藏75次。本文以文字+思维导图+表格的形式详解了数据库、数据仓库、数据集市、数据湖、数据网格、湖仓一体之间的区别。_数据仓库 数据集市 数据湖

如何运用python多线程threading实现程序的并发_python 如何实现并发获取数据-程序员宅基地

文章浏览阅读443次。每次技术的进步都是面对问题解决问题,有了现实中需要解决的问题了我们才能想各种方法解决他也就成就了技术的跃迁。_python 如何实现并发获取数据

柴天佑pdf 自适应控制_串讲:控制理论:自适应控制(APC)-程序员宅基地

文章浏览阅读4k次,点赞3次,收藏21次。自适应控制 (APC)说道自适应控制(APC),也要追溯到5年前第一次接触,当时还只会应用下面的自适应律公式来求解,这里结合自己的一些想法来对自适应控制进行深入剖析,希望可以帮助到大家。APC的历史:在早期的二十世纪五十年代,APC被开始研究,当时应用在飞机的自动导航装置上。简而言之,APC是一种带有在线参数识别的控制方法,主要可以被分为模型参考自适应控制(MRAC)、自校正控制器(STC)、参数..._自适应控制 柴天佑pdf

推荐文章

热门文章

相关标签