GCC简介

article/2025/10/24 16:33:46

一. GCC简介

GCC(GNU C Compiler)原名GNU C语言编译器,是由GNU开发的编程语言译器,只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。GCC 编译器是 Linux 系统下最常用的 C/C++ 编译器,大部分 Linux 发行版中都会默认安装。GCC 编译器通常以gcc命令的形式在终端(Shell)中使用。对于要学习Linux的朋友来说,可以在Windows上做一个过渡。

gcc识别的文件扩展名如下

.c C 语言文件

.i 预处理后的 C 语言文件(包括将头文件加入,将宏展开等操作)

.C、.cc、.cp、.cpp、.c++、.cxx C++语言文件

.ii 预处理后的 C++ 语言文件

.S 汇编文件(用户自己新建的汇编文件)

.s 预处理后的汇编文件

.o 编译后的目标文件

.a 目标文件的静态链接库(链接时使用)

.so 目标文件的动态链接库(链接、运行时使用)

gcc 和 g++ 编译器的编译过程

1、预处理(preprocessing)

# -E 选项指示编译器仅对输入文件进行预处理
g++ -E test.cpp -o test.i //.i文件

2、编译(compilation)

# -S 编译选项告诉 g++ 在为 C++ 代码产生了汇编语言文件后停止编译
# g++ 产生的汇编语言文件的缺省扩展名是 .s //.s文件
g++ -S test.i -o test.s

3、汇编(assembly)

# -c 选项告诉 g++ 仅把源代码编译为机器语言的目标代码
# 缺省时 g++ 建立的目标代码文件有一个 .o 的扩展名。 //.o文件
g++ -c test.s -o test.o

4、链接(link)

# -o 编译选项来为将产生的可执行文件用指定的文件名
g++ test.o -o test //bin文件

文件名后缀说明

.c C 语言文件

.i 预处理后的 C 语言文件

.s 预处理后的汇编文件

.o 编译后的目标文件

程序编译成功后,通过“./”运行这个可执行程序。

常用编译(还是经过:预处理、编译、汇编、链接的过程):

gcc hello.c -o demo

如果是 C++ 代码,只需改用 g++ 编译器即可。如果没有 g++ 编译器,在线安装即可。

使用 g++ 编译 c++ 程序:

gcc重要编译参数

-g 编译带调试信息的可执行文件(gdb)

# -g 选项告诉 GCC 产生能被 GNU 调试器GDB使用的调试信息,以调试程序。
# 产生带调试信息的可执行文件test
g++ -g test.cpp

-O[n] 优化源代码

## 所谓优化,例如省略掉代码中从未使用过的变量、直接将常量表达式用结果值代替等等,这些操作会缩减目标文件所包含的代码量,提高最终生成的可执行文件的运行效率。
# -O 选项告诉 g++ 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。 -O2 选项告诉 g++ 产生尽可能小和尽可能快的代码。 如-O2,-O3,-On(n 常为0–3)
# -O 同时减小代码的长度和执行时间,其效果等价于-O1
# -O0 表示不做优化
# -O1 为默认优化
# -O2 除了完成-O1的优化之外,还进行一些额外的调整工作,如指令调整等。
# -O3 则包括循环展开和其他一些与处理特性相关的优化工作。
# 选项将使编译的速度比使用 -O 时慢, 但通常产生的代码执行速度会更快。
# 使用 -O2优化源代码,并输出可执行文件
g++ -O2 test.cpp

-l 和 -L 指定库文件 | 指定库文件路径(library)

# -l参数(小写)就是用来指定程序要链接的库,-l参数紧接着就是库名
# 在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接
# 链接glog库
g++ -lglog test.cpp
# 如果库文件没放在上面三个目录里,需要使用-L参数(大写)指定库文件所在目录
# -L参数跟着的是库文件所在的目录名
# 链接mytest库,libmytest.so在/home/bing/mytestlibfolder目录下
g++ -L/home/bing/mytestlibfolder -lmytest test.cpp

-I 指定头文件搜索目录(include)

# -I 
# /usr/include目录一般是不用指定的,gcc知道去那里找,但 是如果头文件不在/usr/icnclude里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude 参数了,如果不加你会得到一个”xxxx.h: No such file or directory”的错误。-I参数可以用相对路径,比如头文件在当前 目录,可以用-I.来指定。上面我们提到的–cflags参数就是用来生成-I参数的。
g++ -I/myinclude test.cpp

-Wall 打印警告信息(warning all)

# 打印出gcc提供的警告信息
g++ -Wall test.cpp

-w 关闭警告信息

# 关闭所有警告信息
g++ -w test.cpp

-werror 把所有的告警信息转化为错误信息,并在告警发生时终止编译过程

-std=c++11 设置编译标准(standard)

# 使用 c++11 标准编译 test.cpp
g++ -std=c++11 test.cpp

-o 指定输出文件名(out)

# 指定即将产生的文件名
# 指定输出可执行文件名为test
g++ test.cpp -o test

-D 定义宏(Define)

# 在使用gcc/g++编译的时候定义宏
# 常用场景:
# -DDEBUG 定义DEBUG宏,可能文件中有DEBUG宏部分的相关信息,用个DDEBUG来选择开启或关闭DEBUG

-v 打印出编译器内部编译各过程的命令行信息和编译器的版本

-static 链接静态库

-llibrary 连接名为 library 的库文件

-ansi 支持符合 ANSI 标准的 C 程序

-pedantic 允许发出 ANSI C 标准所列的全部警告信息

-pedantic-error 允许发出 ANSI C 标准所列的全部错误信息

示例代码:

// -Dname 定义宏name,默认定义内容为字符串“1”#include <stdio.h>int main()
{#ifdef DEBUGprintf("DEBUG LOG\n");#endifprintf("in\n");
}// 1. 在编译的时候,使用gcc -DDEBUG main.cpp
// 2. 第七行代码可以被执行

注: man gcc命令可以查看gcc英文使用手册

3.3、【实战】g++命令行编译

案例:最初目录结构:2 directories,3 files

# 最初目录结构
.
├── include
│   └── Swap.h
├── main.cpp
└── src└── Swap.cpp2 directories, 3 files

3.3.1、直接编译

最简单的编译,并运行

# 将 main.cpp src/Swap.cpp 编译为可执行文件
g++ main.cpp src/Swap.cpp -Iinclude
# 运行a.out
./a.out

增加参数编译,并运行

# 将 main.cpp src/Swap.cpp 编译为可执行文件 附带一堆参数
g++ main.cpp src/Swap.cpp -Iinclude -std=c++11 -O2 -Wall -o b.out
# 运行 b.out
./b.out

3.3.2、生成库文件并编译

链接静态库生成可执行文件①:

## 进入src目录下
$cd src# 汇编,生成Swap.o文件
g++ Swap.cpp -c -I../include
# 生成静态库libSwap.a
ar rs libSwap.a Swap.o## 回到上级目录
$cd ..# 链接,生成可执行文件:staticmain
g++ main.cpp -Iinclude -Lsrc -lSwap -o staticmain

链接动态库生成可执行文件②:

## 进入src目录下
$cd src# 生成动态库libSwap.so
g++ Swap.cpp -I../include -fPIC -shared -o libSwap.so
## 上面命令等价于以下两条命令
# gcc Swap.cpp -I../include -c -fPIC
# gcc -shared -o libSwap.so Swap.o## 回到上级目录
$cd ..# 链接,生成可执行文件:sharemain
g++ main.cpp -Iinclude -Lsrc -lSwap -o sharemain

编译完成后的目录结构

最终目录结构:2 directories, 8 files

# 最终目录结构.├── include│   └── Swap.h├── main.cpp├── sharemain├── src│   ├── libSwap.a│   ├── libSwap.so
1│   ├── Swap.cpp
1│   └── Swap.o
1└── staticmain
1
12 directories, 8 files

3.3.3 运行可执行文件

运行可执行文件①

# 运行可执行文件
./staticmain

运行可执行文件②

# 运行可执行文件
LD_LIBRARY_PATH=src ./sharemain

转自:GCC简介 - 知乎


http://chatgpt.dhexx.cn/article/U5kUSUxL.shtml

相关文章

一张图学会python递归函数

递归函数属于那种“难者不会&#xff0c;会者不难”的事情&#xff0c;回想自己大学时学习递归函数的经历&#xff0c;简直是痛不欲生&#xff0c;代码里没有一行是看不懂的&#xff0c;但就是理解不了它是怎样运行的。 等到自己悟通了原理&#xff0c;就又会觉得这东西太简单了…

【Python递归练习】

1.出售金鱼问题第一次卖出全部金鱼的一半加二分之一条金鱼&#xff1b;第二次卖出乘余金鱼的三分之一加三分之一条金鱼&#xff1b;第三次卖出剩余金鱼的四分之一加四分之一条金鱼&#xff1b;第四次卖出剩余金鱼的五分之一加五分之一条金鱼&#xff1b;现在还剩下11条金鱼。问…

python 递归函数详解

在 python中&#xff0c;有一种非常神奇的函数&#xff1a;递归函数&#xff0c;它可以让你的程序实现自顶向下的递归调用&#xff0c;从而实现程序的无限循环。这是一种非常神奇的语言&#xff0c;可以让你使用一种语言实现另一种语言。它还有一个很酷的名字&#xff1a; shel…

python函数递归求和详解_Python递归函数详细分析

什么是递归? 递归,就是在函数运行中自己调用自己 代码示例: def recursion(n): # 定义递归函数 print(n) # 打印n recursion(n1) # 在函数的运行种调用递归 recursion(1) # 调用函数 这个函数在不断的自己调用自己,每次调用n1,看下运行结果: 1 2 ..... 998Tracebac…

Python递归思想与代码实现

1&#xff0c; 递归思想 递归算法:递归(Recursion)&#xff0c;在数学与计算机科学中&#xff0c;是指在函数的定义中使用函数自身的方法。 这是官方的解释&#xff0c;翻译成人话就是&#xff1a; 函数内部自己调用自己函数必须有出口 函数自己调用自己很好理解&#xff0c…

python函数递归调用时对深度没有限制_python递归深度

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 今天在写爬虫的时候,发现了一个事情,使用str方法强制转换一个beautifulsoup对象成字符串的时候报错了,提示是“maximum recursion depth exceeded while cal…

python递归函数详解

python递归函数是指一个函数从一个状态开始&#xff0c;然后返回另一个状态。递归函数是在实现过程中遇到的最基本的一类函数。比如&#xff0c; int i0; int j0; int c1;等等都是一类递归函数&#xff0c;但是我们知道&#xff0c;它们在实现过程中需要执行多次&#xff0c;并…

Python 递归的优化

文章目录 前言一、递归实现斐波那契二、优化后的斐波那契总结 前言 递归&#xff0c;很常见的一种算法&#xff0c;在初学的时候我们都会用递归来解决斐波那契数列&#xff0c;但递归本身有非常大的缺陷&#xff0c;就是时间和空间占用都非常大&#xff0c;在进阶学习后&#…

Python 递归实现乘法

Python定义函数:使用递归求乘积&#xff08;x*y&#xff09; 1 当作x个y相加或者y个x相加 2 当其中一数&#xff08;以x为例&#xff09;不为1时&#xff0c;返回y加上该函数&#xff0c;同时每次x-1&#xff0c;直至x1为止&#xff0c;此过程实现了x个y相加 具体代码如下:

python递归遍历查询文件 文件夹

文章目录 &#x1f357;先看运行效果&#x1f354; 具体思路&#x1f35f; 一、主要使用的模块以及方法&#x1f32d; 二、主要思路以及代码&#x1f37f; 1、开始位置&#x1f9c2; 2、关键位置&#x1f953; 3、结果输出 &#x1f9c7; 完整源码&#x1f95e; 结尾&#x1f9…

轻松搞懂Python递归函数的原理与应用

递归: 在函数的定义中&#xff0c;函数内部的语句调用函数本身。 1、递归的原理 学习任何计算机语言过程中&#xff0c;“递归”一直是所有人心中的疼。不知你是否听过这个冷笑话&#xff1a;“一个面包&#xff0c;走着走着饿了&#xff0c;于是就把自己吃了”。 常理推断&…

python递归如何理解

最近在做递归一些相关的东西&#xff0c;发现递归入门很容易&#xff0c;但要具体了解其实现过程&#xff0c;比较难以理解&#xff0c;在这里将自己这几天的摸索记录一下&#xff0c;写知乎的主要目的是为了给自己做笔记&#xff0c;在做笔记的同时&#xff0c;帮助后来人少走…

【Python函数的递归】

递归的定义 函数作为一种代码封装&#xff0c;可以被其他程序调用&#xff0c;当然&#xff0c;也可以被函数内部代码调用。这种函数定义中调用函数自身的方式称为递归。就像一个人站在装满镜子的房间中&#xff0c;看到的影像就是递归的结果。递归在数学和计算机应用上非常强大…

H3C 交换机S5130S软件版本升级

1.通过官网下载软件包 升级的包名为 S5130S_HI-CMW710-R6330.ipe 2. 查看FLASH空间是否足够 <H3C>dir /all Free的空间需要是软件包的2倍大小&#xff0c;例如S5130S_HI-CMW710-R6330.ipe软件包大小为54MB&#xff0c;那么交换机Free的空间需要108M。 空间如果…

H3C 交换机S6520X软件版本升级

1.通过官网下载软件包 升级的包名为 S6520X-CMW710-R6312P02.zip 压缩包里有很多特性包&#xff0c;我们目前就使用 S6520X-CMW710-R6312P02.ipe 2. 查看FLASH空间是否足够 <H3C>dir /all Free的空间需要是软件包的2倍大小&#xff0c;例如S6520X-CMW710-R6312P0…

H3c服务器升级硬盘固件,H3C交换机升级固件版本

二、进入产品支持与服务&#xff0c;找到适配的交换机固件进行下载 三、下载时要求提供用户名密码 用户名&#xff1a;yx800 密码&#xff1a;01230123 四、H3C官方升级说明案例 1.1 实验拓扑(假设SW1上 VLAN 1 的虚地址为10.10.10.1&#xff0c;PC配置同网段地址10.10.10.…

博途V16 更改PLC的型号和固件版本

在线访问&#xff0c;查看硬件PLC的固件版本。 右键&#xff0c;选择更改设备。 选择PLC型号和版本号。

TIA博途_如何更新程序中的指令版本和CPU固件版本?

TIA博途_如何更新程序中的指令版本和CPU固件版本? TIA博途STEP7从V14SP1版本增加新功能:“更新程序”,可以将当前CPU中的程序版本更新至能够使用的最高版本,对于通讯、运动控制等版本经常升级的程序非常适用, 以下进行举例说明: TIA博途STEP7 V13 SP1中组态S7-1200 V4.1版…

TIA PORTAL西门子PLC的CPU固件版本兼容问题

TIA PORTAL西门子PLC的CPU固件版本兼容问题 以S7-1200为例&#xff0c;现在新出的PLC的固件都是V4.4的版本了&#xff0c;而原来的软件如V15.0组态不到V4.4&#xff0c;只能组态到V4.2&#xff0c;在想继续使用V15.0的情况下&#xff0c;这个PLC还可以用吗&#xff1f; 答案是可…

如何在TIA博途中在线更新PLC的CPU固件版本?

如何在TIA博途中在线更新PLC的CPU固件版本? S7-1200PLC最新的V4.6.0版本的固件出来了,本次就以V4.6版本的固件为例,演示如何在博途中对PLC的固件版本进行更新。 (为防止更新过程中出现意外,强烈建议对PLC的程序进行备份!备份!备份!) 如下图所示,打开某个项目,选中PL…