使用GCC编译程序常用命令

使用GCC编译程序常用命令一 编译器驱动程序首先梳理一下源文件到可执行文件的整个过程 下面是两个源文件的组成 main c 和 sum c main cintsum int a intn intarray 2 1 2 intmain intval sum array 2 returnval sum cintsum int a intn inti s 0 for i 0 i

一、编译器驱动程序

首先梳理一下源文件到可执行文件的整个过程,下面是两个源文件的组成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 
     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 
     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.c loongson@loongson-pc:~/workspace/cpptest$ gcc sum.c -o sum.o -c loongson@loongson-pc:~/workspace/cpptest$ ls main.c sum.c sum.o loongson@loongson-pc:~/workspace/cpptest$ ar -cr libmine.a sum.o loongson@loongson-pc:~/workspace/cpptest$ ls libmine.a main.c sum.c sum.o loongson@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.c loongson@loongson-pc:~/workspace/cpptest$ gcc sum.c -o libsum.so -shared -fPIC //编译动态库 loongson@loongson-pc:~/workspace/cpptest$ ls libsum.so main.c sum.c loongson@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 errors loongson@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 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221438.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午6:06
下一篇 2026年3月17日 下午6:06


相关推荐

  • C++ 无锁队列

    C++ 无锁队列atomic 类型的操作是原子操作 是不可分割的 不能被中断的操作 程序代码中的一条简单赋值语句会被翻译为多条汇编指令 那么多个线程同时对某一存储单元进行修改 就有可能出现脏数据 原子操作可以避免脏数据的出现 2 多线程读写三 总结无锁队列依靠原子和 CAS 操作 对队列的读写索引进行判断来入队和出队 它没有使用互斥量 mutex 来进行加锁 从性能上具有明显的优势 但同时编程的复杂性增加了很多 在编码时也要对内存序有简单的了解

    2025年12月11日
    6
  • 高通msm8937的BLSP学习

    高通msm8937的BLSP学习1.基础概念(1)  BusAccessModule(BAM),总线访问模块BAMisusedtomovedatato/fromtheperipheralbuffers.(2)  BAMLow-SpeedPeripheral(BLSP),低速接口的总线访问模块(3)  QUP:QualcommUniversalPeripheral,高通统一的…

    2022年10月19日
    5
  • centos7.6安装yum模块

    centos7.6安装yum模块准备阶段:查看系统版本:目的是为后面正确下载对应版本的安装包,包不对会让你走很多弯路#cat/etc/redhat-release版本号为:CentOSLinuxrelease7.6.1810(Core)一:卸载老的安装#检查老的安装rpm-qa|grepyum#卸载老的安装rpm-aq|grepyum|xargsrpm-e–nodeps…

    2022年5月6日
    48
  • Springboot源码_pe启动制作源码

    Springboot源码_pe启动制作源码我们在使用SpringBoot启动项目的时候,可能只需加一个注解,然后启动main,整个项目就运行了起来,但事实真的是所见即所得吗,还是SpringBoot在背后默默做了很多?本文会通过源码解析的方式深入理解SpringBoot启动全过程SpringBoot启动过程流程图源码解析大家不要抗拒源码解析,这个非常优秀的代码,我们如果能够学会对自己代码编写水平大有裨益首先,我们先来看下SpringBoot项目的启动类@SpringBootApplicationpublicclassSp.

    2022年8月21日
    7
  • 打开Android Studio报错 “required plugin “Android Support” is disabled”>

    打开Android Studio报错 “required plugin “Android Support” is disabled”>

    2021年9月30日
    55
  • 手动ghost备份系统步骤_手动ghost备份图解

    手动ghost备份系统步骤_手动ghost备份图解备份前我们需要ghost,在此我提供下,在压缩文件下找到ghost百度网盘:http://pan.baidu.com/s/1mh77iWS 密码:ivxq进入ghost界面以后,按回车键,进入下一个操作界面。如下图所示:使用键盘上的方向键依次选择“Local”(本机)“Partition”(分区)“ToImage”(到镜像)然后

    2025年9月22日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号