【三、深入浅出GCC编译器】一个源文件到可执行文件是如何生成的:GCC编译工具链及编译参数详解(一)

简介: 【三、深入浅出GCC编译器】一个源文件到可执行文件是如何生成的:GCC编译工具链及编译参数详解

一、GCC交叉编译工具链

GCC编译工具链包含了GCC编译器在内的一整套工具,主要包含了GCC编译器、Binutils工具集、glibc标准函数库。一般情况下,我们说的GCC编译工具链就是指GCC编译器。

1. GCC编译器

GCC原名为GNU C语言编译器(GNU C Compiler),只能对C语言进行编译等处理。后来随着其功能的扩展,可以支持更多编程语言,如C++、Java、Fortran、Pascal、Objective -C、Ada、Go以及各类处理器架构上的汇编语言等。所以,现在我们所说的GCC是指GNU编译器套件(GNU Compiler Collection),并且现在的GCC还可以进行交叉编译(在一个平台下编译包含另一个平台的代码)。通过下面的命令可以查看GCC版本和GCC的安装路径。

gcc -v

which gcc

C语言编译器是gcc-core,C++语言编译器是gcc-c++。

2. Binutils工具集

(1)链接器与汇编器

binutils(bin utility,GUN二进制工具集),GNU binutils是一组二进制工具集。包括:addr2line ar gprof nm objcopy objdump ranlib size strings strip等。工具集默认在目录 /usr/bin 目录下,在这个工具集中我们必须要知道的工具有两个:ld 链接器和 as 汇编器。这两个工具和我们编译一个源文件息息相关。

as 汇编器用于把汇编文件(汇编语言)转换为目标问价(机器码),完成 .s.o 的工作;

ld 链接器用于把编译生成的多个目标文件链接组织为可执行文件;

这两个工具我们一般不会直接调用,它们大多是在GCC编译文件的时候由GCC编译器调用的。

(2)其它常用工具介绍及用法演示

首先我们准备几个文件,包括.s文件.o文件.c文件.i文和可执行文件,具体这些文件怎么生成,以及这些文件是什么含义在后面的章节有详细介绍(可以先看下一章再返回看本小节)。

① size: 列出文件每个部分的内存大小,如代码段、数据段、总大小等。

输入 size 文件名 就可以看到文件的内存占用情况

text是代码段,用于存放代码;data是用来放已初始化的数据;bss是用来放未初始化的数据。

② readelf: 显示有关ELF格式文件内容的信息。ELF格式是UNIX系统实验室作为应用程序二进制接口开发的。ELF格式是Unix/Linux平台上应用最广泛的二进制工业标准之一。

可以输入 readelf 查看说明及选项参数

readelf -h 显示可执行文件或目标文件的ELF Header的文件头信息(就是ELF文件开始的前52个字节)

③ nm: 查看目标文件中出现的符号(函数、全局变量等)。

上面可以看到,nm列出的信息总共有三列:第一列是指程序运行时的符号所对应的地址,对于函数来说表示的是函数的开始地址,对于变量则表示的是变量的存储地址;第二列是指相应符号是放在内存的哪一个段;第三列则是指符号的名称。这个命令通常会和 addr2line (后面会介绍)一块使用,因为nm列出了符号的地址,但是并没有行号和源文件名称,而 addr2line 可以根据符号地址给出行号和源文件目录及名称。更多信息可以查看man手册

nm只能用于目标文件和可执行文件,对普通文件无效

④ objcopy: 将目标文件的一部分或者全部内容拷贝到另外一个目标文件中,或者实现目标文件的格式转换。可用于目标文件格式转换,如.bin转换成.elf、.elf转换成.bin等。

比如,格式转换命令

objcopy -O binary  xx  xx.bin

⑤ objdump: 显示程序文件相关信息,最主要的作用是反汇编。这里介绍两个常用的选项参数:

可以通过 -d 选项来对可执行文件进行反汇编

也可以对目标文件反汇编

通过 -h 选项查看目标程序中的段信息和调试信息

⑥ addr2line: 将程序地址翻译成文件名和行号;给定地址和可执行文件名称,它使用其中的调试信息判断与此地址有关联的源文件和行号,通常搭配 nm 使用。

这个命令一般用于调试信息时快速定位错误位置。它的命令用法为addr2line 地址 -e 可执行文件名。为演示这个命令用法,首先创建一个文件,这个文件包含一个函数,函数功能为打印函数地址,代码如下

然后编译这个文件,编译时必须要加上 -g 包含调试信息,然后运行,得到打印出的地址

输入命令addr2line 地址 -e 可执行文件名 -f,可以看到文件位置,行号都打印出来了

我么可以确认一下是不是第11行,cat -n 显示行号

⑦ strings: 显示程序文件中的可显示字符串。

可以通过管道和grep过滤自己需要的信息

3. glibc库

glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc和libc都是Linux下的C函数库。libc是Linux下的ANSI C函数库,glibc是Linux下的GUN C函数库。

在CentOS操作系统下,查看glibc的版本

如果你是Ubuntu系统,可以用这个命令

/lib/x86_64-linux-gnu/libc.so.6



相关文章
|
前端开发 C语言
gcc动态库升级
gcc动态库升级
1311 1
|
存储 编译器 C语言
深入理解GCC 和 G++ 编译器
GCC 和 G++ 是 GNU 工具链中的核心编译器,支持 C 和 C++ 程序开发。本文详细介绍其编译流程、常用选项及动态链接与静态链接的区别。编译过程分为预处理、编译、汇编和链接四个阶段,每个阶段有特定任务和命令选项。常用选项如 `-E`、`-S`、`-c` 和 `-o` 分别用于预处理、生成汇编代码、生成目标文件和指定输出文件。动态链接节省空间且易于更新,但依赖运行时库;静态链接独立高效,但文件较大且更新困难。合理选择优化选项(如 `-O0` 至 `-O3`)可提升程序性能。掌握这些知识有助于开发者更高效地编写、调试和优化代码。
深入理解GCC 和 G++ 编译器
|
编译器 Linux C语言
gcc的编译过程
GCC(GNU Compiler Collection)的编译过程主要包括四个阶段:预处理、编译、汇编和链接。预处理展开宏定义,编译将代码转换为汇编语言,汇编生成目标文件,链接将目标文件与库文件合并成可执行文件。
692 11
|
Unix 编译器 Linux
1.8.3 GNU编译器集合和LLVM项目
GNU项目自1987年起致力于开发自由UNIX软件,其成果之一GNU编译器集合(GCC)在指导委员会领导下持续演进,紧跟C语言标准。GCC适用于多种平台如UNIX、Linux和Windows,并常通过gcc或cc命令调用。另一方面,起源于2000年伊利诺伊大学研究项目的LLVM,提供了另一种开源编译器集合,其Clang编译器处理C代码,自2012年起成为FreeBSD默认C编译器,并良好支持最新C标准。
317 1
|
编译器 开发工具 C语言
Gcc 链接文件
Gcc 链接文件
461 4
|
编译器 Linux 开发工具
|
NoSQL 编译器 开发工具
006.gcc编译器
gcc是什么?
320 0
006.gcc编译器
|
存储 NoSQL 算法
从一个crash问题展开,探索gcc编译优化细节
问题分析的过程也正是技术成长之路,本文以一个gcc编译优化引发的crash为切入点,逐步展开对编译器优化细节的探索之路,在分析过程中打开了新世界的大门……
|
C语言
gcc的简易用法
【5月更文挑战第10天】gcc的简易用法。
315 8
|
编译器 C语言 C++
MinGW安装gcc
MinGW安装gcc
664 0