在Linux中使用gcc/g++编译代码

1.方法速记

直接编译语法:将text.c文件或者text.cpp文件直接编译成text文件。

  • gcc text.c -o text // gcc-o text.c text
  • g++ text.cpp -o text // g++ -o text.cpp text
  • 注意:-o后面一定对应着目标文件(可执行文件)就好啦。

2.具体过程

2.1 预处理阶段

预处理的过程就是头文件包含,去注释,宏替换的过程。
预处理指令是以#开头的代码行。

将text.c文件预处理后变成text.i文件

  • gcc -E text.c -o text.i
    -E的选项是让gcc在预处理结束后就停止编译。

在这里插入图片描述
观察可以看到,预处理过后的文件800多行,头文件被包含在里面,并且观察main里面,具体的注释已经被去掉。

2.2 编译阶段

编译阶段是指将预处理后的代码变成汇编语言。

将text.c变成text.s或者将text.i变成text.s:

  • gcc -S text.i -o text.s
    -S:从现在开始进行编译,如果编译成功就停止下来。

在这里插入图片描述

2.3 汇编阶段

将汇编语言变成二进制代码。

将text.c/text.s文件变成text.o文件:

  • gcc -c text.s -o text.o
  • .o文件又叫可重定位目标文件。
    -c:从现在开始进行程序的翻译,如果汇编完成,就停下来。

使用od -x 文件命令,查看机器代码:
在这里插入图片描述

2.4链接阶段

将汇编阶段生成的.s文件转成目标文件(可执行文件)。

将text.o文件链接成可执行文件text:

  • gcc text.o -o -text

在这里插入图片描述

2.4.1 链接的细节

链接:动态链接和静态链接。
动态链接是将库(动态库.so)中我要的方法地址,填入我的可执行程序中,建立关联。(节省资源)
静态链接是直接将库(静态库.a)中的方法真的拷贝到我们的可执行程序中。(占用资源)


gcc或者g++默认使用动态链接编译过程。

  • 查看文件链接属性
  • file 文件名

在这里插入图片描述


  • 将源程序采用静态链接的策略
  • gcc text.c -o text-s -static
    -static:生成的目标文件采用静态链接
    在这里插入图片描述
    观察到文件大小差异很大。

在C程序中,并没有定义"printf"函数的实现,并且在预编译中的“stdio.h”头文件中只有该函数的声明,并没有该函数的实现,那么程序是如何运行"printf"的呢?
事实上,gcc默认是动态链接,预处理把printf函数的声明放到.i文件后,链接阶段可以根据该函数的声明(该函数定义的地址)找到函数的实现,从而实现连接过程。
可以使用ldd指令查看程序链接动态库的情况:

在这里插入图片描述

gcc和g++的操作一样,g++的方法就仅需把gcc换成g++即可。

猜你喜欢

转载自blog.csdn.net/weixin_45153969/article/details/132491586