Makefile学习 -5 gcc分步讲解

gcc编译器的过程有预处理、编译、汇编、链接几个步骤。

平时我们都不太关注,这是什么鬼,这里简单说明一下,以便于理解gcc工作原理。

 

总结:

gcc -E -o main.i main.c //只预处理,将库文件展开
gcc -S -o main.s main.c //编译,将.c编译成汇编
gcc -c -o main.o main.s //编译+汇编,将汇编码转换成ELF机器码
gcc -o main main.o     //链接,将.o文件链接库生成可执行文件

 

1、 gcc常用的参数有:

gcc --help
Usage: gcc [options] file...
  -v                       Display the programs invoked by the compiler
  -E                       Preprocess only; do not compile, assemble or link
  -S                       Compile only; do not assemble or link
  -c                       Compile and assemble, but do not link
  -o <file>                Place the output into <file>

 

 

2、示例

main.c文件为例讲解gcc编译过程。

#finename:main.c
#include<stdio.h>

#define NUM 15
#define DEBUG

int main()
{
	printf("num:%d\n", NUM);

#ifdef DEBUG
	printf("hello debug\n");
#endif

	return 0;
}

a- 预处理 -E

就是将你文件里的宏展开。

你可以打开你的main.i看到里面是什么。

粗略看了下,就是将一些数据类型什么的给展开到预处理文件main.i,以及main.c里用到的宏给展开。自己看下吧。

gcc -E -o main.i main.c //只预处理,将库文件展开

 

b- 编译 -S

就是将你的c代码编译成汇编语言,打开main.s可以看到是汇编码

gcc -S -o main.s main.c //编译,将.c编译成汇编

 

c- 汇编 -c

就是将上一步生成的.s的汇编码生成ELF格式的机器码。

gcc -c -o main.o main.s //编译+汇编,将汇编码转换成ELF机器码

可以用file命令查看文件类型

file main.o
main.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

 

d- 链接 -o

就是将上一步生成的.o和系统库OBJ文件、库文件进行链接,生成可执行文件。

gcc -o main main.o     //链接
file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=2ba667769aa54a32ab02b9bd5e7d09f53938c564, not stripped

查看编译过程

gcc -v -o main main.o     //链接

查看可执行文件依赖的库

ldd main
	linux-vdso.so.1 =>  (0x00007ffce31b1000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd1ecfaf000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd1ed379000)

好了,gcc编译的步骤和原理就这样,有个大概的认知了吧

 

3、 简化gcc编译命令

上面的编译步骤很详细,一步步的,让我们知道.c文件是如何生成可执行文件的。但是实际编译过程中这样写也太折磨人了吧。。。

gcc默认对.c文件进行预处理,-c指明编译+汇编,-o指将输出文件进行链接成可执行文件。
上述步骤可以简化为:

gcc -c -o main.o main.c
gcc -o main main.o

 

4- Makefiel脚本

我们平时写一个.c文件进行测试学习一些C语言用法,用gcc还可以。

但是每次都写这两行,还是会感到不爽,Makefile脚本就是来解放你的。

写一个通用的Makefile脚本,里边内容就是以gcc编译命令。

当你想执行编译的文件前,只需make一下,搞定!

前边写了几个Makefile的帖子,可以参考下。

 

5- 动态库 静态库(了解)

动态库:生成的可执行文件运行时,必须将依赖的库加载到内存中。默认动态链接。

静态库:将依赖的库写进可执行文件。文件较大。

gcc$ gcc -static -o main_static main.o  //静态链接
gcc$ gcc -o main_share main.o   //动态链接
gcc$ ls -l
-rwxrwxrwx 1 root root   8656 Aug  3 16:43 main
-rwxrwxrwx 1 root root  17130 Aug  3 16:03 main.i
-rwxrwxrwx 1 root root   1616 Aug  3 16:08 main.o
-rwxrwxrwx 1 root root    543 Aug  3 16:05 main.s
-rwxrwxrwx 1 root root   8656 Aug  3  2020 main_share
-rwxrwxrwx 1 root root 912816 Aug  3 16:48 main_static

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值