GCC编译过程及基本命令总结

article/2025/10/5 16:46:04

一、GCC简介

GCC即GNU Compiler Collection,原本只是针对C语言的编译工具,现在已经变成了一个工具集,包含了C、C++、JAVA等语言的集合体。

管理和维护:由GNU项目负责。

二、GCC对C、C++的编译流程

(1) 预处理(Preprocessing) 

--宏替换;

--删除注释;

--处理预处理指令,如#include,#ifdef,头文件都被展开,拼接所有头文件到一个文件中。

(2) 编译(Compilation)        

--词法分析,识别单词,确认词类;比如 int i;知道 int 是一个类型,i是一个关键字以及判断i的名字是否合法

--语法分析,识别短语和句型的语法属性;

--语义分析,确认单词、短语和句型的语义特征;

--代码优化,修辞、文本编辑;

--代码生成,生成译文(.s文件,统一代码在不同系统中的.s文件不一致)。

(3)汇编(Assemby)             

--把汇编语言代码翻译成目标机器指令(生成目标文件,.o文件)。

编译器把一个cpp编译为目标文件的时候,除了要在目标文件里写入cpp里包含的数据和代码,还要至少提供3个表:未解决符号表,导出符号表和地址重定向表。

未解决符号表,提供了所有在该编译单元里引用但是定义并不在本编译单元里的符号及其出现的地址。

导出符号表,提供了本编译单元具有定义,并且愿意提供给其他编译单元使用的符号及其地址。

地址重定向表,提供了本编译单元所有对自身地址的引用的记录。

(4) 链接(Linking)                 

--将所有.o文件及引用到的动态链接库文件中的函数链接到一起,生成可执行文件(.out文件)。

三、GCC的基本使用(以下选项在g++中同样试用,一般c程序就用gcc编译,c++程序就用g++编译

基本使用格式 :    $ gcc  [选项]  <文件名>

(1) -o 设置gcc处理结果的文件名为<文件名>

如 gcc main.c -o main  ,即为将编译结果的文件名设置为main,如果不使用-o命令,则编译结果是默认的文件名(假如被处理的源文件为source.suffix,若省略了-o选项,则生成的可执行文件默认为a.out,目标文件默认名为source.o,汇编文件默认为source.s)。

例如对于这个main.c

-- 执行 gcc main.c (输出默认文件名)

-- 执行 gcc main.c -o main (指定gcc处理结果的文件名为main)

(2) -c 只编译,不链接

执行 gcc -o main.c (结果为.o文件) 

一般对于包含对个.c文件的大工程,首先把每个.c文件编译成独立的.o文件,然后把所有.o文件进行链接生成可执行文件。 

(3) -E 预编译 (将所有的头文件和宏都拼接到一个.c文件中)

 执行 gcc -E main.c (可见在main()函数之前,所有的头文件和宏定义都被包含进来(先把头文件copy过来,然后对宏进行替换))

 也就是说对于一个程序,预编译会把所有的头文件和宏定义都拼接到一个文件中,因为其实一个程序就算其包含了很多子文,但是最终都是编译一个文件。

(4) -S 只编译不汇编

执行 gcc -S main.c (生成.s文件,同意程序在不同体系下的计算机中生成的汇编文件是不一致的)

(5) -g 生成调试信息(debug版本)

执行 gcc -g main.c -o main_d ,生成带调试信息的版本,并令生成的文件名为“main_d”。可见加了-g的版本比普通版本所占空间更大,因为debug版本加入了调试信息,会把代码编进去,后面可以使用GDB工具进行调试跟进


【多目录编译】

(6) -I 添加头文件路径(多文件目录下)

例如有如下目录:

--person

        --person/person.h

        --person/person.cpp

--test

         --test/main.cpp

main.cpp如下

person.h如下 

person.cpp如下

 编译过程如下:

(a). 执行 g++ -c person.cpp ,首先单独编译person.cpp生成目标文件person.o 。

(b). 执行 g++ main.cpp ../person/person.o -o main -I ../person,编译person.o和main.cpp,-I添加头文件目录。


【静态编译】

(7)  -static 静态编译(若指定为静态编译,则会把所有引用到的系统文件都指定成静态库,全部编译到这个可执行文件中)

使用ldd可以查看程序所引用到的动态库。

执行 ldd main ,可见一个简单的程序都引用了很多库。

执行  g++ main.cpp ../person/person.o -o main_static -I ../person -static ,将程序进行静态编译(使用个g++是因为gcc编译c++找不到库文件)。

然后再使用ldd main_static查看调用的动态库,可以发现它不调用任何动态库。

 而且可执行文件的大小变得非常大。

注:大部分情况下不建议使用静态方式进行编译,因为其最大的问题就是编译时间太长,稍微大点的项目编译要几分钟,但是它在其他环境下运行比较简单,不需要配置环境依赖。


【动态编译】

(8) -fpic -shared  前者指定函数和代码位置不相关,设置之后可以使用-shared将其设置为动态链接库动态链接库在linux中的命名规则为 lib+name+.so,引用的时候只要使用name就行了)。

执行 gcc person.cpp -fpic -shared -o libperson.so ,将person.cpp编译成动态链接库 libperson.so。

(9) -L -l(小写的L) 前者指定动态链接库的所在目录,后者指定需要链接的动态链接库(不加lib 和.so)

执行 g++ main.cpp -o main -I../person -L../person -lperson ,在编译main时使用-I(大写的i)指定头文件目录,使用-L指定董涛链接库目录,使用-lperson指定需要在编译时链接libperson.so这个动态链接库文件。

 注意:执行通过动态链接而编译生成的可执行文件main时,需要指定动态链接库文件libperson.so的路径,否则运行数失败。

解决方法有两种:

(a) 将需要链接的动态链接库文件libperson.so拷贝到系统的path路径下。

(b) 写执行脚本export LD_LIBRARY_PATH=../person,添加临时路径。

 使用ldd命令查看main依赖,可见确实在../person目录下找到的。

 


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

相关文章

Linux 下的 gcc 编译常用命令

gcc&#xff1a;Linux下的一款编译器。 gcc工作流程&#xff1a; 完整编译流程&#xff1a; 创建一个c语言源文件&#xff1a; gcc -E hello.c -o hello.i&#xff08;头文件展开&#xff0c;进行源文件中的宏替换&#xff0c;注释过滤&#xff09; gcc -S hello.i -o hello.…

GCC命令编译

1.GCC编译过程&#xff08;原理如下&#xff0c;使用命令请见2&#xff09; 从 hello.c 到 hello(或 a.out)文件&#xff0c; 必须历经 hello.i、 hello.s、 hello.o&#xff0c;最后才得到 hello(或a.out)文件&#xff0c;分别对应着预处理、编译、汇编和链接 4 个步骤&#…

gcc 命令详解及最佳实践

介绍 GCC&#xff08;英文全拼&#xff1a;GNU Compiler Collection&#xff09;是 GNU 工具链的主要组成部分&#xff0c;是一套以 GPL 和 LGPL 许可证发布的程序语言编译器自由软件&#xff0c;由 Richard Stallman 于 1985 年开始开发。 GCC 原名为 GNU C语言编译器&#…

使用GCC编译程序常用命令

一、编译器驱动程序 首先梳理一下源文件到可执行文件的整个过程&#xff0c;下面是两个源文件的组成main.c和sum.c // main.c int sum(int *a, int n); int array[2] { 1, 2 }; int main() {int val sum(array, 2);return val; }// sum.c int sum(int *a, int n) {int i, s…

matlab 反向二值化,MATLAB:图像二值化、互补图(反运算)(im2bw,imcomplement函数)...

图像二值化、反运算过程涉及到im2bw&#xff0c;imcomplement函数&#xff0c;反运算可以这么理解&#xff1a;原本黑的区域变为白的区域&#xff0c;白的区域变为黑的区域。 实现过程如下&#xff1a; close all;%关闭当前所有图形窗口&#xff0c;清空工作空间变量&#xff0…

图像处理Matlab阈值的设置imadjust(),graythresh(),im2bw()函数使用

1、imadjust()函数调节图像的对比度(若图像较暗&#xff0c;可用imadjust函数命令来调节图像的对比度) I1imadjust(I,stretchlim(I),[0;1]); % stretchlim(I2)自适应找到一个分割阈值向量来改变一幅图像的对比度 figure,imshow(I1); 2、matlab中DIP工具箱函数im2bw使用阈值&…

MATLAB--对于im2bw函数的优化

由于我在研究的是uint8图像&#xff0c;所以对于优化im2bw函数的形式为&#xff1a;im2bw(uint8[], T)&#xff0c;不过其它形式也可以由类似思想导出。 测试代码&#xff1a;遍历8个图像得出时间 for n1:8cchar(str(n));fimread(c);testtime3%要测试的代码 end 算法一 tic fR…

MATLAB中将图像转换为二值图像im2bw

在MATLAB中将图像转换为二值图像&#xff0c;主要运用im2bw函数&#xff0c;涉及到一个灰度门槛的数值。 对于灰度图像 bwim2bw(I,level); level空着的话&#xff0c;默认是0.5。level一般使用graythresh函数来计算&#xff0c;至于graythresh函数中运用到的Otsus method&am…

matlab函数im2bw_图像分割之阈值分割(matlab)(转载)

转载自&#xff1a;https://blog.csdn.net/weixin_39824223/article/details/112249214 matlab函数im2bw_图像分割之阈值分割&#xff08;matlab&#xff09; weixin_39824223 2021-01-02 06:21:09 373 收藏 2 文章标签&#xff1a; matlab函数im2bw 图像分割是一种重要的…

MATLAB中im2bw函数-将图像转换为二值图像

matlab中DIP工具箱函数im2bw使用阈值&#xff08;threshold&#xff09;变换法把灰度图像&#xff08;grayscale image&#xff09;转换成二值图像。所谓二值图像&#xff0c; 一般意义上是指只有纯黑&#xff08;0&#xff09;、纯白&#xff08;255&#xff09;两种颜色的图像…

4、im2bw 和 imbinarize 的区别与图像分割的综合应用

1. im2bw 和 imbinarize 的区别 将图片转换为二值图有两个函数&#xff0c;分别为&#xff1a; bw imbinarize(g); 与 bw im2bw(g);在 matlab2018 中建议用 imbinarize 来将图片转换为二值图&#xff0c;其参数必须为灰度图。 在 matlab2016 中&#xff0c;只有 im2bw 函…

理解Kalman滤波的使用

Kalman滤波简介 Kalman滤波是一种线性滤波与预测方法&#xff0c;原文为&#xff1a;A New Approach to Linear Filtering and Prediction Problems。文章推导很复杂&#xff0c;看了一半就看不下去了&#xff0c;既然不能透彻理解其原理&#xff0c;但总可以通过实验来理解其具…

卡尔曼滤波(Kalman Filtering)——(6)MATLAB仿真(保姆级)

MATLAB仿真 一、卡尔曼滤波的实际应用二、流程图三、执行过程四、程序代码五、仿真结果参考文献 一、卡尔曼滤波的实际应用 在这里依旧以前面提到的测量硬币为例进行MATLAB仿真。现有一枚硬币为了这枚硬币的直径&#xff0c;我们进行了多次测量&#xff0c;但是所使用的的尺子存…

Kalman Filter 遇到 Deep Learning : 卡尔曼滤波和深度学习有关的论文

突然心血来潮&#xff0c;想到卡尔曼滤波器是否能和深度学习结合。于是从谷歌学术上搜了一下&#xff0c;发现现在这方面的工作还没有太多结合。Top 期刊 TNNLS 2021 有一篇最新工作。ICLR 2020 出现一篇 Kalman Filter Is All You Need 的文章&#xff0c;但目前从开源的审稿意…

目标跟踪:卡尔曼滤波(Kalman Filter)到底是怎么工作的?

Kalman filter到底是怎么工作的&#xff1f; 本文主要参考的文章&#xff1a;https://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/&#xff0c;图片也基本来自上述博客 其实接触KF已经很久了&#xff0c;听过对应的课程&#xff0c;也对着公式进行过推导&#x…

卡尔曼滤波(kalman)

卡尔曼&#xff08;kalman&#xff09;滤波原理 kalman滤波器可以看做状态变量在由观测生成的线性空间上的射影。 如下状态空间模型描述的动态系统&#xff1a; (1) ​​​​​​​ ​​​​​​​ (2) 式中&#xff0c;k为离散时间&#xff…

卡尔曼滤波(Kalman filter)及预测

参考文章&#xff1a;https://blog.csdn.net/baidu_38172402/article/details/82289998; https://www.jianshu.com/p/2768642e3abf kalman滤波的作用&#xff1a;1.数据 滤波&#xff1b;2.数据预测 3.数据融合。其基本原理&#xff1a;是通过协方差 来进行加权。 1.什么是…

【Kalman】卡尔曼滤波Matlab简单实现

本节卡尔曼滤波Matlab实现是针对线性系统估计的&#xff0c;仅为简单仿真。 1.离散时间线性动态系统的状态方程 线性系统采用状态方程、观测方程及其初始条件来描述。线性离散时间系统的一般状态方程可描述为 其中&#xff0c;X(k) 是 k 时刻目标的状态向量&#xff0c;V(k)…

学习OpenCV——Kalman滤波

背景&#xff1a; 卡尔曼滤波是一种高效率的递归滤波器(自回归滤波器), 它能够从一系列的不完全及包含噪声的测量中&#xff0c;估计动态系统的状态。卡尔曼滤波的一个典型实例是从一组有限的&#xff0c;包含噪声的&#xff0c;对物体位置的观察序列&#xff08;可能有偏差&a…

卡尔曼滤波Kalman Filtering:介绍

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 控制理论(control theory&#xff09;是工程学的分支之一&#xff0c;主要应对工程系统控制的问题。比如控制汽车发动机的功率输出&#xff0c;稳定电动机的转速&#xff0c;控制“反应速率”&#x…