参考资料:4.gcc和arm-linux-gcc_冷暖自知_源的博客-CSDN博客_arm-linux-gcc

浅析gcc、arm-linux-gcc和arm-elf-gcc的关系_求佛_ce123的博客-CSDN博客_arm-elf-gcc

003_arm-linux-gcc使用_Da Liu的博客-CSDN博客_arm-linux-gcc使用

gcc(GNU编译器套件)_百度百科

目录

1、gcc和arm-linux-gcc有何不同?

2、gcc组成结构:

3、gcc使用:

1、分步骤执行

2、直接执行

4、arm-linux-gcc使用


1、gcc和arm-linux-gcc有何不同?

本质上都是编译器,而gcc是linux系统用来将代码编译成可执行程序的手段。编译出来的是适用于linux系统的可执行二进制文件。所以用gcc编译出来的可执行程序只有在linux系统下面可以运行。

arm-linux-gcc告诉编译器,我编写的环境是linux,但是我希望生成的可执行程序是在arm上面跑的。这就是交叉编译。编写环境和执行环境分离的一种手段。

2、gcc组成结构:

GCC 内部结构主要由 Binutils、gcc-core、Glibc 等软件包组成。

        1、Binutils:它是一组开发工具,包括连接器,汇编器和其他用于目标文件和档案的工具。关于 Binutils 的介绍可以参考 Binutils 简单介绍。这个软件包依赖于不同的目标机的平台。因为不同目标机的指令集是不一样的,比如 arm 跟 x86 就不一样。
        2、gcc-core:GCC 的核心部分,这部分是只包含 c 的编译器及公共部分,而对其他语言(C++、Ada 等)的支持包需要另外安装,这也是 GCC 为何如此强大的重要原因 。gcc-core依赖于 Binutils。
        3、Glibc:包含了主要的 c 库,这个库提供了基本的例程,用于分配内存,搜索目录,读写文件,字符串处理等等。kernel 和 bootloader不需要这个库的支持。
举例描述下上面 3 个包是如何进行运作的。有一个 c 源文件 test.c 源码如下:

#include<stdio.h>
int main(int argc, char *argv[])
{
	printf("Hello Linux!!\n");
	return 0;
}

        编译命令为: gcc -o test test.c 编译生成 test 可执行文件。gcc 编译流程分为四个步骤:预处理、编译、汇编、链接。个人认为预处理和编译主要由 gcc-core 来完成,汇编和链接主要由 Binutils 来 完成。那么何时用到 glibc 呢?看到源码中的 printf 函数没有,这个函数在 GCC 中是以库函数的形式存在,这个库函数在 glibc 库中,在 stdio.h 头文件中被声明。
        总的来说,如果真正了解了上面 3 个软件包的作用,自然就明白 GCC 是如何工作的。

        如果要使用交叉工具链为 ARM 机器编译简单的 Hello World 程序,可以运行如下命令编译并测试这个代码: arm-linux-gcc -o hello hello.c。
         arm-linux-gcc 是基于 ARM 目标机的交叉编译软件,x86 跟 ARM 所使用的指令集是不一样的,所以所需要的 binutils 肯定不一样;上面提到过 gcc-core 是依赖于 binutils 的,自然 ARM 跟 x86 所使用的 gcc-core 包也不一样glibc 一个 c 库,最终是以库的形式存在于编译器中,自然 ARM 所使用的 glibc 库跟 x86 同样也不一样,其它的依此类推。

3、gcc使用:

示例代码

#include<stdio.h>
    
 
int main(void)
 
{
  
      printf("hello\n");
 
     return 0;
    
}

1、分步骤执行

预编译过程

这个过程处理宏定义和include,去除注释,不会对语法进行检查。

可以看到预编译后,代码从6行扩展到了910行。

1

2

3

4

5

gcc -E a.c -o a.i

cat a.c|wc -l

5

cat a.i|wc -l

910

编译过程

这个阶段,检查语法,生成汇编代码。

1

2

3

gcc -S a.i -o a.s

cat a.s|wc-l

59

汇编过程

这个阶段,生成目标代码

此过程生成ELF格式的目标代码。

1

2

3

gcc -c a.s -o a.o

file a.o

a.o:ELF64-bitLSBrelocatable,AMDx86-64,version1(SYSV),notstripped

链接过程

链接过程。生成可执行代码。链接分为两种,一种是静态链接,另外一种是动态链接。使用静态链接的好处是,依赖的动态链接库较少,对动态链接库的版本不会很敏感,具有较好的兼容性;缺点是生成的程序比较大。使用动态链接的好处是,生成的程序比较小,占用较少的内存。

1

gcc a.o -o a

程序运行:

1

2

./a

hello

2、直接执行

gcc hello.c直接编译,生成一个a.out的文件

 gcc -o hello hello.c 使用-O选项指定文件输出,规定输出的文件名是hello

4、arm-linux-gcc使用

arm-linux-gcc 是交叉编译器,基本用法与 gcc 相同,目的是将编译的程序放在目标机(ARM)上运行。

以上面的hello.c文件为例说明arm-linux-gcc的用法

(1)$ arm-linux-gcc -o hello hello.c 

   生成可执行文件 hello,它包含了上述 4 个步骤(预处理、编译、汇编和链接)

(2)arm-linux-gcc -v -o hello hello.c

  使用“arm-linux-gcc -v -o hello hello.c”命令可以查看编译的细节

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐