使用GCC编译程序常用命令

article/2025/10/5 17:34:07

一、编译器驱动程序

首先梳理一下源文件到可执行文件的整个过程,下面是两个源文件的组成main.csum.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 = 0;for (i = 0; i < n; i++) {s += a[i];}return s;
}

使用命令:gcc -Og -o prog main.c sum.c调用GCC的驱动程序。下图是静态链接,链接器将可重定位的目标文件组合起来,形成一个可执行目标文件prog。这个链接的过程可以分为三个步骤:

  • 它首先运行C预处理器cpp,将C源程序main.c翻译成一个ASCII码的中间文件main.i
  • 接下来,C编译器cc1main.i翻译成一个ASCII汇编语言文件main.s
  • 最后,汇编器asmain.s翻译成一个可重定位目标文件main.o,此时的目标文件还不能执行,需要通过链接器将其与所依赖的函数(如sum.o)链接到一块才可以生成可执行文件
    在这里插入图片描述
    在运行可执行文件prog时,shell调用操作系统中一个叫做加载器的函数,他将可执行文件prog中的代码和数据复制到内存,然后将控制转移到这个程序的开头。

二、预处理

2.1 -E 只激活预处理

GCC不会保留预处理文件(.i文件),但可以通过-E选项在预处理阶段完毕后停止编译,将预处理信息保存到一个文件。

gcc -E main.c -o main.i
gcc -E main.c > main.i

2.2 -C 保留注释信息

在预处理的时候,不删除注释信息,一般和-E搭配使用。

2.3 -D 在编译的时候定义宏的。

  • -D后面直接跟宏名,相当于定义这个宏,默认这个宏的内容是1,如gcc -DDEBUG
  • -D后面跟 key=value 表示定义key这个宏,它的内容是value,如gcc -DNAME=Peter
#include<stdio.h>
int main()  {   int value = VALUE;  printf("value = %d\n", value);  return 0;  
} 
gcc -DVALUE=12 define.c 
输出:value = 12

2.4 -o 选项

指定生成目标的名称,gcc main.c sum.c -o main,整个编译阶段都可以用。

三、编译

3.1 -S 只激活预处理和编译

只激活预处理和编译,把源文件编译成为汇编文件后停止,源文件可以是.c文件,也可以是.i文件。

gcc main.c -o main.s -S
gcc main.i -o main.s -S

3.2 -save-temps 输出中间代码

输出编译过程中所有的中间代码。

loongson@loongson-pc:~/workspace/cpptest$ ls
main.c  sum.c
loongson@loongson-pc:~/workspace/cpptest$ gcc main.c sum.c -o main -save-temps
loongson@loongson-pc:~/workspace/cpptest$ ls
main  main.c  main.i  main.o  main.s  sum.c  sum.i  sum.o  sum.s

3.3 -O# 编译优化

根据不同等级进行编译优化:

  • -O0:不进行优化处理。
  • -O1(-O):对编译出的代码进行优化。
  • -O2:进行比-O高一级的优化。
  • -O3:产生更高级别的优化。

3.4 -I 指定额外的头文件搜索路径

先在指定的路径中搜索要包含的头文件,若找不到,则在标准路径(/usr/include/usr/lib及当前工作目录)上搜索。

gcc luacallc.c -o luacallc -g -I /home/loongson/workspace/luajit/src/ -lluajit-5.1 -L /home/loongson/workspace/luajit/lib -Wl,-rpath,/home/loongson/workspace/luajit/lib

3.5 -funsigned-char-fno-signed-char-fsigned-char-fno-unsigned-char设置char类型

这四个参数是对 char 类型进行设置, 决定将 char 类型设置成 unsigned char(前两个参数)或者 signed char(后两个参数)。

#include<stdio.h>int main()  {   char value = -8;  printf("value = %d\n", value);  return 0;  
}loongson@loongson-pc:~/workspace/cpptest$ gcc define.c -o define
loongson@loongson-pc:~/workspace/cpptest$ ./define 
value = -8
loongson@loongson-pc:~/workspace/cpptest$ gcc define.c -o define -funsigned-char
loongson@loongson-pc:~/workspace/cpptest$ ./define 
value = 248
loongson@loongson-pc:~/workspace/cpptest$ gcc define.c -o define -fno-signed-char
loongson@loongson-pc:~/workspace/cpptest$ ./define 
value = 248
loongson@loongson-pc:~/workspace/cpptest$ gcc define.c -o define -fsigned-char
loongson@loongson-pc:~/workspace/cpptest$ ./define 
value = -8
loongson@loongson-pc:~/workspace/cpptest$ gcc define.c -o define -fno-unsigned-char
loongson@loongson-pc:~/workspace/cpptest$ ./define 
value = -8

四、汇编

4.1 -c 只激活预处理,编译,和汇编

只激活预处理,编译,和汇编,把源文件编译成可重定位目标文件,源文件可以是.c.i.s文件。

gcc main.c -o main.o -c
gcc main.i -o main.o -c
gcc main.s -o main.o -c

4.2 objdump 命令,反汇编

objdump命令是Linux下的反汇编目标文件或者可执行文件的命令,它以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。

  • 反汇编应用程序,objdump -d main.o
  • 显示文件头信息,objdump -f main.o
  • 显示制定section段信息(comment段),objdump -s -j .comment main.o

五、链接

如果程序需要使用某个动态库中的函数,则在程序的编译阶段和之后的运行阶段都需要链接这个动态库, 即编译时链接和运行时链接。

5.1 编译时链接

1)-L 指定编译时的路径

指定编译时,搜索使用到的库的路径,可以是静态库,也可以是动态库,-L.表示当前路径。

2)-l 指定编译时引用库的名字

指定编译时使用到的库名称,可以是静态库,也可以是动态库,静态库libmine.a和动态库libmine.so均可使用-lmine

3)ar命令 集合多个文件为一个文件

ar命令至少需要两个参数才能运行,用于建立,修改备存文件或从备存文件中抽取成员。一个备存文件是一个包含了很多其它文件的单独的文件,原始文件(成员)的内容、权限、时间属性、属主和组都在备存文件中得到保留,在抽取时可以得到恢复。

loongson@loongson-pc:~/workspace/cpptest$ ls
main.c  sum.cloongson@loongson-pc:~/workspace/cpptest$ gcc sum.c -o sum.o -c
loongson@loongson-pc:~/workspace/cpptest$ ls
main.c  sum.c  sum.oloongson@loongson-pc:~/workspace/cpptest$ ar -cr libmine.a sum.o
loongson@loongson-pc:~/workspace/cpptest$ ls
libmine.a  main.c  sum.c  sum.oloongson@loongson-pc:~/workspace/cpptest$ gcc main.c -o main -lmine -L.
loongson@loongson-pc:~/workspace/cpptest$ ls
libmine.a  main  main.c  sum.c  sum.o

5.2 运行时链接

1)-Wl,-rpath 指定运行时动态库路径

用于指定程序运行时查找动态链接库的路径,多个路径是使用冒号隔开,这样就不用添加路径到 /etc/ld.so.conf 文件中或者环境变量LD_LIBRARY_PATH了,在需要多个so版本共存时很有用。

2)-shared 生成共享目标文件

生成共享目标文件,与-fPIC一起通常用在建立共享库时。

3)-fPIC 生成位置无关代码

作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行(共享库被加载时,在内存的位置不是固定的)。

loongson@loongson-pc:~/workspace/cpptest$ ls
main.c  sum.cloongson@loongson-pc:~/workspace/cpptest$ gcc sum.c -o libsum.so -shared -fPIC //编译动态库
loongson@loongson-pc:~/workspace/cpptest$ ls
libsum.so  main.c  sum.cloongson@loongson-pc:~/workspace/cpptest$ gcc main.c -o main -lsum -L. -Wl,-rpath,. //链接动态库
loongson@loongson-pc:~/workspace/cpptest$ ls
libsum.so  main  main.c  sum.c

5.3 -static 禁止使用动态库

此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么动态连接库,就可以运行。

六、其他

6.1 -w-Wall-Werror 警告相关

  • -w:不生成警告信息。
  • -Wall:生成所有警告信息。
  • -Werror:将警告信息当作错误来处理,一般与-Wall搭配使用(-Wall -Werror只要有警告信息则编译停止)。
loongson@loongson-pc:~/workspace/cpptest$ ls
main.c  sum.c
loongson@loongson-pc:~/workspace/cpptest$ gcc main.c sum.c -o main -Wall -Werror
main.c: In function ‘main’:
main.c:12:6: error: unused variable ‘a’ [-Werror=unused-variable]12 |  int a = 0;|      ^
cc1: all warnings being treated as errorsloongson@loongson-pc:~/workspace/cpptest$ ls
main.c  sum.
loongson@loongson-pc:~/workspace/cpptest$ gcc main.c sum.c -o main -Wall
main.c: In function ‘main’:
main.c:12:6: warning: unused variable ‘a’ [-Wunused-variable]12 |  int a = 0;|      ^
loongson@loongson-pc:~/workspace/cpptest$ ls
main  main.c  sum.c

6.2 -g-gstabs-gstabs+-ggdb 产生调试信息

  • -g:可以产生供GDB调试的可执行文件。
  • -gstabs:产生stabs格式的调试信息,不包括GDB调试信息。
  • -gstabs+:产生stabs格式的调试信息,包括GDB调试信息。
  • -ggdb:尽可能的生成GDB可以使用的调试信息

6.3 -std 指定编译版本

指定采用什么版本的规范进行编译,如-std=c89-std=c99

6.4 @ 指定文件制定编译选项

可以使用@然后跟着文件名做编译选项,文件中的内容会连接在后面。

loongson@loongson-pc:~/workspace/cpptest$ ls
main.c  sum.c  temp.txt
loongson@loongson-pc:~/workspace/cpptest$ cat temp.txt 
main.c sum.c -o main
loongson@loongson-pc:~/workspace/cpptest$ gcc @temp.txt
loongson@loongson-pc:~/workspace/cpptest$ ls
main  main.c  sum.c  temp.txt

6.5 -M-MM-MD-MMD生成文件关联的头文件信息

这几个参数,在Makefile中会经常用到,代替手动将头文件添加到规则中:

  • -M:生成.c文件编译生成的默认目标文件名和所依赖的所有头文件信息,包括系统文件和项目中的文件,即#include造成的所有依赖关系。
  • -MM:与-M一样,但是不包括系统文件造成的依赖关系,只包括引用的项目中的文件。
  • -MD:和-M相同,但是输出将导入到.d的文件里面。
  • -MMD:和-MM相同,但是输出将导入到.d的文件里面。

参考链接:
https://blog.csdn.net/qq_35865125/article/details/87868653
https://blog.csdn.net/gangyanliang/article/details/73162231
https://blog.csdn.net/hktkfly6/article/details/61922685
https://blog.csdn.net/tsxw24/article/details/10220735
https://www.runoob.com/w3cnote/gcc-parameter-detail.html


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

相关文章

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…

kalman 滤波 演示与opencv代码

在机器视觉中追踪时常会用到预测算法&#xff0c;kalman是你一定知道的。它可以用来预测各种状态&#xff0c;比如说位置&#xff0c;速度等。关于它的理论有很多很好的文献可以参考。opencv给出了kalman filter的一个实现&#xff0c;而且有范例&#xff0c;但估计不少人对它的…

Ensemble Kalman filter集合卡尔曼滤波

在气象预测领域&#xff0c;很多时候&#xff0c;模型具有 O ( 10 e 8 ) O(10e8) O(10e8)以上的量级&#xff0c;如果使用传统的卡尔曼滤波&#xff0c;协方差矩阵的更新将是一个~ 10 e 22 10e22 10e22量级的计算操作&#xff0c;因此传统的卡尔曼滤波并不适用。集合卡尔曼滤波…

Kalman滤波MATLAB实现实例——在温度测量中的应用

参考&#xff1a;《卡尔曼滤波原理及应用MATLAB仿真》 原理介绍 假设我们要研究的对象是一个房间的温度。根据经验判断,这个房间的温度大概在25℃左右,可能受空气流通、阳光等因素影响,房间内温度会小幅度地波动。我们以分钟为单位,定时测量房间温度,这里的1分钟,可以理解为采…

图解卡尔曼滤波(Kalman Filter)

背景 关于滤波 首先援引来自知乎大神的解释。 “一位专业课的教授给我们上课的时候&#xff0c;曾谈到&#xff1a;filtering is weighting&#xff08;滤波即加权&#xff09;。滤波的作用就是给不同的信号分量不同的权重。最简单的loss pass filter&#xff0c; 就是直接把低…