第七章:GCC的编译过程

我们知道gcc是一个强大的编译器,很多Linux下的GNU工具都是用C语言写的,并且用gcc编译的,那么gcc的编译过程是怎样的呢?

1. 首先是源文件经过预加载变成了.i结尾的文件,可以通过-E这个参数来生成这个中间文件,这里主要是把一些include的头文件和一些宏定义,放到源文件中。
2. 从预加载的文件经过编译就会变成汇编语言的文件,这一步可以通过-S这个参数来生成这个中间文件 。
3. 从汇编语言的文件通过汇编,就会变成目标代码.o的文件,这一步可以通过-C这个参数来生成这个中间文件 。
4. 最后经过链接,生成最终的可执行文件 。

接下来我们通过一个例子来说明下:
我新建了一个文件:

/* main.c */
/* $begin main */
int sum(int *a, int n);

int array[2] = {1, 2};

int main() 
{
    int val = sum(array, 2);
    return val;
}
/* $end main */

现在我们开始尝试将这个文件在Linux环境下,利用GCC编译生成可执行文件:
我先生成.i结尾的预加载文件
gcc -E main.c -o main.i 在这里插入图片描述

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"


int sum(int *a, int n);

int array[2] = {1, 2};

int main()
{
    int val = sum(array, 2);
    return val;
}

大家会发现这个文件的内容非常多,但是最后是我们本来的代码,上面的代码都是头文件和一些宏的内容,全加载进来了 。
下面我们通过编译生成汇编文件.s

gcc -S main.i -o main.s

	.file	"main.c"
	.text
	.globl	array
	.data
	.align 8
	.type	array, @object
	.size	array, 8
array:
	.long	1
	.long	2
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	$2, %esi
	leaq	array(%rip), %rdi
	call	sum@PLT
	movl	%eax, -4(%rbp)
	movl	-4(%rbp), %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0"
	.section	.note.GNU-stack,"",@progbits

看到了我们熟悉的汇编语言
我们继续,经过汇编器,生成.o的目标文件

gcc -c main.s -o main.o
objdump main.o -D|more
在这里插入图片描述
最后通过链接器,生成可执行文件
gcc main.o -o mian
然后执行
在这里插入图片描述
makefile.txt:

CC = gcc
CFLAGS = -Wall -Og

PROGS = global \
	mismatch \
	prog\
	prog2c\
	prog2l\
	prog2r\
	static-local.o \
	symbols.o \

# Do nothing
all: $(PROGS)

static-local.o: static-local.c
	$(CC) $(CFLAGS) -c static-local.c

# example program 1 
prog: main.o sum.o
	$(CC) $(CFLAGS) -o prog main.o sum.o
	$(CC) $(CFLAGS) -S main.c
	objdump -dx main.o          > main-relo.d
	objdump -dx -j .data main.o > maindata-relo.d
	readelf -s main.o	    > mainsym.d	
	objdump -dx sum.o           > sum-relo.d
	objdump -dx -j .data sum.o  > sumdata-relo.d
	objdump -dx prog            > prog-exe.d
	objdump -dx -j .data prog   > progdata-exe.d

# Type mismatch example
mismatch: mismatch-main.c mismatch-variable.c
	$(CC) $(CFLAGS) -o mismatch mismatch-main.c mismatch-variable.c

# Use of extern specifier
global: global-c1.c global-c2.c global.h
	$(CC) $(CFLAGS) -o global global-c1.c global-c2.c

# Static library linked at compile time
prog2c: main2.o addvec.o multvec.o
	$(CC) $(CFLAGS) -c main2.c addvec.c multvec.c
	ar rcs libvector.a addvec.o multvec.o
	$(CC) $(CFLAGS) -static -o prog2c main2.o -L. -lvector
#       Alternative for above line
#	$(CC) $(CFLAGS) -static -o prog2c main2.o libvector.a
	objdump -d prog2c > prog2c-exe.d


# Shared library linked at load-time
prog2l: main2.o libvector.so
	$(CC) $(CFLAGS) -o prog2l main2.o ./libvector.so
	objdump -dx main2.o          > main2-relo.d
	objdump -dx prog2l > prog2l-exe.d
	objdump -xs -j .data -j .got prog2l > prog2ldata-exe.d

# Shared library linked at run time
prog2r: dll.c
	$(CC) $(CFLAGS) -rdynamic -o prog2r dll.c -ldl

libvector.so: addvec.c multvec.c	
	$(CC) $(CFLAGS) -shared -fpic -o libvector.so addvec.c multvec.c
	objdump -xd libvector.so > libvector-relo.d
	objdump -xRr -j .data -j .got -j .got.plt -j rela.dyn -j rela.plt libvector.so > libvectordata-relo.d

clean:
	rm -f $(PROGS) *.o *~ *.d *.so *.a *.s

至此,可执行文件就生成成功了,让我们来看一下执行的结果。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在CentOS 7上编译安装特定版本的GCC(例如5.1.0),可以按照以下步骤进行操作: 1. 首先,确保系统已经安装了一些必要的软件包来构建GCC。运行以下命令以安装这些软件包: ``` sudo yum groupinstall -y "Development Tools" sudo yum install -y wget sudo yum install -y bzip2 ``` 2. 下载所需的GCC源代码。在此示例中,我们将使用版本5.1.0。运行以下命令: ``` wget https://ftp.gnu.org/gnu/gcc/gcc-5.1.0/gcc-5.1.0.tar.bz2 ``` 3. 解压缩下载的源代码包: ``` tar -xvf gcc-5.1.0.tar.bz2 cd gcc-5.1.0 ``` 4. 创建一个用于构建GCC的目录,并切换到该目录: ``` mkdir build cd build ``` 5. 运行以下命令来配置GCC的构建过程: ``` ../configure --prefix=/usr/local/gcc-5.1.0 --enable-languages=c,c++ ``` 请注意,上述命令将指定GCC安装到`/usr/local/gcc-5.1.0`目录中。 6. 开始构建和安装GCC。运行以下命令: ``` make -j4 sudo make install ``` 这将使用4个并行线程构建GCC,加快构建过程。根据您的系统性能,您可以调整`-j`参数的值。 7. 完成安装后,您需要通过设置环境变量来使新安装的GCC生效。打开您的shell配置文件(例如`~/.bashrc`)并添加以下行: ``` export PATH=/usr/local/gcc-5.1.0/bin:$PATH export LD_LIBRARY_PATH=/usr/local/gcc-5.1.0/lib64:$LD_LIBRARY_PATH ``` 确保将路径`/usr/local/gcc-5.1.0`替换为您在第5步中指定的实际安装路径。 8. 保存并关闭您的shell配置文件,然后重新加载它: ``` source ~/.bashrc ``` 现在,您已经成功在CentOS 7上编译和安装了GCC 5.1.0版本。您可以使用`gcc -v`命令检查GCC版本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值