当前位置: 首页 > news >正文

Linux GCC 编译详解

文章目录

    • 一、GCC 编译器简介
    • 二、GCC 工作流
      • 编程语言的发展
      • GCC 工作流程
      • gcc 和 g++ 的区别
    • 三、使用 GCC 编译
      • GCC 编译格式
      • GCC 编译流程
      • 多个源文件编译

一、GCC 编译器简介

首先,什么是编译器呢?
我们可以使用编辑器(如 linux 下的 vi、windows 下的记事本)来写程序(编辑代码)。但是我们写的程序中的代码语句,电脑是看不懂的,我们需要把它转成电脑能懂的语句,编译器就是这样的转化工具。就是说,我们用编辑器编写程序,由编译器编译后才可以运行!编译器是将易于编写、阅读和维护的高级计算机语言翻译为计算机能解读、运行的低级机器语言的程序

那什么是 GCC 编译器?

  1. gcc(GNU Compiler Collection,GNU 编译器套件),是由 GNU 开发的编程语言编译器。gcc 作为GNU操作系统的官方编译器,现已被大多数类 Unix 操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,gcc 同样适用于微软的 Windows。
  2. gcc 最初用于编译 C 语言,随着项目的发展 gcc 已经成为了能够编译 C、C++、Java、Ada、fortran、Object C、Object C++、Go 语言的编译器大家族。
  3. GCC 常用来编译 C/C++ 语言:
    1. 它不仅支持 C 的许多“方言”,也可以区别不同的 C/C++ 语言标准;
    2. 也可以使用命令行选项来控制编译器在翻译源代码时应该遵循哪个 C/C++ 标准。例如,当使用命令行参数 -std=c99 启动 GCC 时,则编译器支持 C99 标准。

如何安装使用 GCC 呢?
linux ubuntu 下,可以通过 sudo apt install gcc g++ 安装命令安装
查看版本 gcc/g++ -v/–version:

yxm@192:~$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【注意】如果需要支持 c++11,gcc 版本需要 > 4.8.5。

二、GCC 工作流

编程语言的发展

计算机语言的发展 总体分三个阶段

  • 第一代机器语言:机器语言是微处理器理解和使用的,用于控制它的操作二进制代码。
    • 优点:直接执行,速度快,资源占用少
    • 缺点:可读性、可移植性差,编程繁杂
  • 第二代汇编语言 :一种面向机器的低级语言,通常是为特定的计算机或系列计算机专门设计的。汇编语言是机器指令的符号化表示,故不同的机器就有不同的汇编语言。使用汇编语言能面向机器并较好地发挥机器的特性,得到质量较高的程序。汇编语言虽然能编写高效率的程序,但是学习和使用都不是易事,并且很难调试。
  • 第三代高级语言:高级语言主要是相对于汇编语言而言的,它是较接近自然语言和数学公式的编程,基本脱离了机器的硬件系统,用人们更易理解的方式编写程序。编写的程序称之为源程序

GCC 工作流程

从上面的编程语言的发展过程可以知道,我们现在常说的编程语言一般都是高级语言,编写的程序称之为源程序。编译器其实就相当于一个翻译器,将高级语言翻译成机器语言以便机器可以识别。

gcc 编译器从拿到一个c 源文件到生成一个可执行程序,中间一共经历了四个步骤:
四个步骤并不是 gcc 独立完成的,而是在内部调用了其他工具,从而完成了整个工作流程:
【注意】头文件展开:其实就是把头文件中的内容复制到 .c/.c++ 源代码文件中。

gcc 和 g++ 的区别

理解了 GCC 的工作流程,接下来说一下 gcc 和 g++ 的区别,相信你会有更加深刻的了解。

首先,gcc 和 g++都是GNU(组织)的一个编译器。

误区一:gcc 只能编译 c 代码,g++ 只能编译 c++ 代码。其实两者都可以编译,请注意:

  • 后缀为 .c 的,gcc 把它当作是 C 程序,而 g++ 当作是 c++ 程序;
  • 后缀为 .cpp 的,两者都会认为是 C++ 程序,C++ 的语法规则更加严谨一些。
  • 编译阶段,g++ 会调用 gcc,对于 C++ 代码,两者是等价的,但是因为 gcc 命令不能自动和 C++ 程序使用的库联接,所以通常用 g++ 来完成链接,为了统一起见,干脆编译/链接统统用 g++ 了,这就给人一种错觉,好像 cpp 程序只能用 g++ 似的。

误区二:gcc 不会定义 __cplusplus 宏,而 g++ 会

  • 实际上,这个宏只是标志着编译器将会把代码按 C 还是 C++ 语法来解释
  • 如上所述,如果后缀为 .c,并且采用 gcc 编译器,则该宏就是未定义的,否则,就是已定义

误区三:编译只能用 gcc,链接只能用 g++

  • 严格来说,这句话不算错误,但是它混淆了概念,应该这样说:编译可以用 gcc/g++,而链接可以用 g++ 或者 gcc -lstdc++。
  • gcc 命令不能自动和C++程序使用的库联接,所以通常使用 g++ 来完成联接。但在编译阶段,g++ 会自动调用 gcc,二者等价

总结:看到上面的误区,你可能能够理解了,但是使用起来比较晕,那么不妨给自己一个规则:gcc 编译 c 代码,g++ 编译 c++ 代码

三、使用 GCC 编译

GCC 编译格式

首先,了解一下,GCC 编译命令的格式:
命令 选项 输出可执行文件的文件名 文件名
gcc [options] [file] file…
g++ [options] [file] file…

  • 命令、选项和源文件之间使用空格分隔;
  • 一行命令中可以有零个、一个或多个选项;
  • 文件名可以包含文件的绝对路径,也可以使用相对路径;
  • 如果命令中不包含输出可执行文件的文件名,可执行文件的文件名会自动生成一个默认名,Linux平台为a.out,Windows平台为 a.exe

GCC 常用选项

选项作用
-o指定生成的输出文件名为file
【注意】除了上面的编译格式,-o 还可以使用另外一种编译格式,如下所示:
命令 文件名 选项 输出可执行文件的文件名
gcc file… [options] [file]
g++ file… [options] [file]
-E只进行预处理
-S(大写)只进行预处理和编译
-c(小写)只进行预处理、编译和汇编
-v / --version查看gcc版本号
-g包含调试信息,该程序可以被调试器调试
-On n=0~3编译优化,n越大优化得越多。n的取值范围:0~3。编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-Wall提示更多警告信息
-D编译时定义宏
-L指定编译的时候,搜索的库的路径。
-I directory即指定 include 包含文件的搜索目录
-w不生成任何警告信息
-l在程序编译的时候,指定使用的库
-std指定C方言,如:-std=c99,gcc默认的方言是GNU C
-shared生成共享目标文件,通常用在建立共享库时

【注意】上表中仅列出了常用的一些指令选项,事实上这仅是冰山一角,GCC 编译器提供有大量的指令选项,可满足我们在大部分场景下的编译需求。有关更多的编译指令,感兴趣的读者可自行查看 GCC 手册。

GCC 编译流程

如上面的文章所讲,C 或者 C++ 程序从源代码生成可执行程序的过程,需经历 4 个过程,分别是预处理、编译、汇编和链接。同样,使用 GCC 编译器编译 C 或者 C++ 程序,也必须要经历这 4 个过程。下面以运行 C 语言程序为例,给大家演示如何使用 gcc 快速获得对应的可执行程序。如下就是一段 C 语言程序:

// test.c 文件
#include <stdio.h>
#define PI 3.14
int main() 
{int sum = PI + 10;printf("Hello World\n");return 0;
}
# 第一步: 进行预处理
yxm@192:~$ gcc -E test.c  -o test.i
yxm@192:~$ ls
company_project  install  myshare  test.c  test.i# 第二步: 生成汇编文件
yxm@192:~$ gcc -S test.i  -o test.s
yxm@192:~$ ls
company_project  install  myshare  test.c  test.i  test.s# 第三步: 生成目标代码
yxm@192:~$ gcc -c test.s  -o test.o
yxm@192:~$ ls
company_project  install  myshare  test.c  test.i  test.o  test.s# 第四步: 生成可以执行文件
yxm@192:~$ gcc test.o  -o test
yxm@192:~$ ls
company_project  install  myshare  test  test.c  test.i  test.o  test.s# 第五步: 执行 
yxm@192:~$ ./test
Hello World

但考虑在实际使用中,我们可能并不关心程序的执行结果,只想快速得到最终的可执行程序,因此 gcc 和 g++ 都对此需求做了支持,可以直接将源文件生成一个可以执行文件

yxm@192:~$ gcc test.c  -o test
yxm@192:~$ ls
company_project  install  myshare  test  test.c
yxm@192:~$ ./test
Hello World

可以看到,GCC 编译器支持使用 gcc(g++)指令“一步编译”指定的 C(C++)程序。【注意】虽然我们仅编写了一条 gcc 或者 g++ 指令,但其底层依据是按照预处理、编译、汇编、链接的过程将 C 、C++ 程序转变为可执行程序的。而本应在预处理阶段、编译阶段、汇编阶段生成的中间文件,此执行方式默认是不会生成的,只会生成最终的 a.out 可执行文件。

如果不指定输出文件名字,gcc 编译器会生成一个默认的可以执行文件 a.out

yxm@192:~$ gcc test.c 
yxm@192:~$ ls
a.out  company_project  install  myshare  test.c
yxm@192:~$ ./a.out 
Hello World

gcc -D 选项:下面以运行 C 语言程序为例,给大家演示如何使用 gcc -D 选项的使用。如下就是一段 C 语言程序:

// test.c 
#include <stdio.h>
int main(void)
{int a = 3;
#ifdef DEBUGprintf("hello itcast\n");
#endifprintf("hello world\n");return 0;
}
yxm@192:~$ gcc test.c -DDEBUG
yxm@192:~$ ls
a.out  company_project  install  myshare  test.c
yxm@192:~$ ./a.out 
hello itcast
hello world

我们在工作的时候,软件一般有两个版本,一个发行版本(release 版本),一个是调试版本(debug 版本),如果在编译时指定-D参数(如上所示)就相当于是调试版本,可以打印调试信息;如果在编译时不指定-D参数就相当于发行版本。【补充】release 版本,一般要求我们把调试信息、log 信息等输出信息都删除掉,因为频繁的输出会大大降低程序的执行效率。

我们还可以通过 -D 选项设置宏的值,如下例所示:

// test.c
#include <stdio.h>
int main(void)
{printf("SIZE: %d\n", SIZE);return 0;
}
deng@itcast:~/test$ gcc 2test.c -DSIZE=10
deng@itcast:~/test$ ./a.out
SIZE: 10

多个源文件编译

如果需要编译多个源文件,基本上有两种编译方法,假设有两个源文件为 file1.c 和 file2.c:

  1. 多个文件一起编译
    用法:gcc file1.c file2.c -o file
    作用:将 file1.c 和 file2.c 分别编译后链接成 file 可执行文件。

【注意】此时 file1.c、file2.c 这两个文件没有先后关系,位置随意放置。

  1. 分别编译各个源文件,之后对编译后输出的目标文件进行链接。
    # 用法
    gcc -c file1.c 						# 将file1.c编译成file1.o
    gcc -c file2.c 						# 将test.c编译成file2.o
    gcc -o file1.o file2.o -o file 		# 将file1.o和file2.o链接成file
    # gcc -o *.o -o file 	# 简洁写法,等价于 gcc -o file1.o file2.o -o file
    

总结:以上两种方法相比较,第一种方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译

相关文章:

Linux GCC 编译详解

文章目录一、GCC 编译器简介二、GCC 工作流编程语言的发展GCC 工作流程gcc 和 g 的区别三、使用 GCC 编译GCC 编译格式GCC 编译流程多个源文件编译一、GCC 编译器简介 首先&#xff0c;什么是编译器呢&#xff1f; 我们可以使用编辑器&#xff08;如 linux 下的 vi、windows 下…...

谁说程序员不懂了浪费,女神节安排

Python的PyQt框架的使用一、前言二、女神节文案三、浪漫的代码四、官宣文案一、前言 个人主页: ζ小菜鸡大家好&#xff0c;我是ζ小菜鸡&#xff0c;特在这个特殊的日子献上此文&#xff0c;希望小伙伴们能讨自己的女神欢心。 二、女神节文案 1.生活一半是柴米油盐&#xff0c…...

上市公司管理层短视指标(2007-2020)

1、数据说明&#xff1a;将研发⽀出的减少量&#xff08;∆R&D&#xff09;作为管理层短视⾏为的度量指标&#xff0c;即∆R&D为公司t年的研发⽀出减去t-1年的研发⽀出并除以t-1年末的总资产再乘以100。2、数据来源&#xff1a;自主整理3、时间跨度&#xff1a;2007-20…...

IDDPM 和 DDIM 对比

IDDPM 和 DDPM 对比IDDPMDDIMIDDPM IDDPM&#xff1a;Improved Denoising diffusion probabilistic models learning Σθ\Sigma_{\theta}Σθ​&#xff0c; 即Σθ(xt,t)exp⁡(vlog⁡βt(1−v)log⁡β~t)\Sigma_{\theta}\left(x_{t}, t\right)\exp \left(v \log \beta_{t}(1…...

链表OJ题(上)

✅每日一练&#xff1a;876. 链表的中间结点 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 定义快慢指针&#xff0c;让快指针走2步&#xff0c;慢指针走1步&#xff0c;当fast或者fast.next为空时&#xff0c;走完链表&#xff0c;此时slow就是中间位置 pub…...

【题解】百度2021校招Web前端工程师笔试卷(第一批):单选题、多选题

题目来源&#xff1a;牛客网公司真题_免费模拟题库_企业面试|笔试真题 (nowcoder.com) 若有错误请指正&#xff01; 单选题 1 某主机的 IP 地址为 212.212.77.55&#xff0c;子网掩码为 255.255.252.0。若该主机向其所在子网发送广播分组&#xff0c;则目的地址可以是&…...

论文解读:SuperPoint: Self-Supervised Interest Point Detection and Description

发表时间: 2018年 项目地址&#xff1a;https://arxiv.org/abs/1712.07629 论文地址&#xff1a;https://github.com/magicleap/SuperPointPretrainedNetwork 本文提出了一种用于训练计算机视觉中大量多视点几何问题的兴趣点检测器和描述符的自监督框架。与patch-based的神经网…...

游戏玩的多,陪玩你了解的多吗?用Python来采集陪玩数据,看看行情和美照

前言 (&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨 大家好 现在应该每个人都玩过游戏吧&#xff0c;有些的上瘾&#xff0c;天天玩停不下来&#xff0c;有些的倒是没啥感觉 有游戏就肯定有陪玩啊&#xff0c;毕竟当朋友忙的时候&#xff0c;自己一个…...

React框架创建项目详细流程-项目的基本配置-项目的代码规范

文章目录React创建项目流程与规范项目规范项目配置目录结构样式重置Router配置Redux状态管理axios配置React创建项目流程与规范 项目规范 项目规范: 在项目中都会有一些开发规范和代码风格, 下面介绍一下我采用的规范与风格 文件夹、文件名称统一小写、多个单词以连接符(-)连…...

nnunet入门之一 (CT图像分割)

目录安装环境数据处理预处理训练测试MIC-DKFZ/nnUNet 选择Linux环境运行该项目&#xff0c;Windows环境需要更改较多的参数&#xff0c;暂不支持。 安装环境 安装cuda, cudnn&#xff0c;已安装的检测cuda版本 检测cuda版本&#xff1a; nvcc -v cd /usr/local nvidia-smi&…...

从0到1_批量下载视频

简介&#xff1a;真实从0到1&#xff0c;童叟无欺&#xff5e; 目标&#xff1a;用python批量下载搜索视频&#xff0c;以“CG 服装”为例 搜索图片就不放啦&#xff0c;不能过审 本章主要介绍如何用python把搜索到的视频直接下载到自己的本地文件夹中&#xff5e; 介绍一下工作…...

CNCF x Alibaba云原生技术公开课 第十二章 可观测性:监控与日志

1、监控 监控类型 资源监控&#xff1a;cpu、内存、网络等。性能监控&#xff1a;apm监控&#xff0c;一般是通过一些 Hook 的机制在&#xff0c;在虚拟机层、字节码执行层通过隐式调用&#xff0c;或者是在应用层显示注入&#xff0c;获取更深层次的一个监控指标&#xff0c…...

C语言宏定义几个问题

1.#define Ant A虽说做的是将代码中Ant替换成A&#xff0c;但是是整体的替换&#xff0c;不能将整体分离替换。 不带宏参定义一般形式如下&#xff1a; 格式&#xff1a; #define 标识符 字符串 其中“标识符”为所定义的宏名&#xff0c;“字符串”可以是常数、表达式、格式串…...

王道计算机组成原理课代表 - 考研计算机 第二章 数据的表示和运算 究极精华总结笔记

本篇博客是考研期间学习王道课程 传送门 的笔记&#xff0c;以及一整年里对 计算机组成 知识点的理解的总结。希望对新一届的计算机考研人提供帮助&#xff01;&#xff01;&#xff01; 关于对 数据的表示和运算 章节知识点总结的十分全面&#xff0c;涵括了《计算机组成原理…...

springboot集成mahout实现简单基于协同过滤算法的文章推荐算法

文章目录前言1.建表并且生成一些数据首先&#xff0c;建立一个用户文章操作表&#xff08;user_article_operation&#xff09;使用case when语句简单分析数据2. 代码与测试只需要根据表生成相应实体类&#xff08;注意要加一个value属性来存储分数&#xff09;主要代码如下&am…...

自动驾驶介绍系列 ———— 看门狗

文章目录硬件看门狗软件看门狗差异分析延申窗口看门狗硬件看门狗 硬件看门狗的本质上是一个定时器电路。通常存在一个输入&#xff0c;输入到MCU的RST端。在正常工作状态下&#xff0c;MCU每隔固定时间间隔会输出一个信号给RST端&#xff0c;实现对看门狗端清零。如果在指定的时…...

今天打开个税APP,我直接人麻了!

点击上方“码农突围”&#xff0c;马上关注这里是码农充电第一站&#xff0c;回复“666”&#xff0c;获取一份专属大礼包真爱&#xff0c;请设置“星标”或点个“在看这是【码农突围】的第 432 篇原创分享作者 l 突围的鱼来源 l 码农突围&#xff08;ID&#xff1a;smartyuge&…...

javascript进阶学习笔记(含AJAX)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、JS变量&#xff08;var、let和const&#xff09;二、for/in循环三、正则表达式语法&#xff1a;正则表达式修饰符&#xff1a;正则表达式模式字符串方法&…...

今年没有金三银四

最近好几个铁子咨询目前的大环境如何&#xff0c;甚至还有几个CTO和总监级别的大佬想跳槽问有没有对应的岗位。 又到了每年金三银四的时间点&#xff0c;往年&#xff08;去年除外&#xff09;这个时候用工市场都是一遍火热&#xff0c;大家跳槽涨薪好不快活。 面对这些咨询我…...

NFS - Network FileSystem网络文件系统的实现原理

文章目录PreNFS简介NFS共享数据结构图NFS服务器的实现原理是否安装nfs安装配置NFSPre NFS - MIPS架构下构建NFS共享目录服务 NFS简介 NFS的全称是Network FileSystem&#xff0c;即网络文件系统 NFS最初是由 Sun Microsytem 公司开发出来的&#xff0c;主要实现的功能是让网络…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...