1、概述
arm-linux-gcc 是交叉编译器,基本用法与 gcc 相同,目的是将编译的程序放在目标机(ARM)上运行。
2、用法举例
(1)预处理:C/C++源文件中,以“#”开头的命令被称为预处理命令,如包含命令“#include”、宏定义命令“#define”、条件编译命令“#if”、“#ifdef”等。预处理就是将要包含(include)的 文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西 输出到一个“.i”文件中等待进一步处理。预处理将用到 arm-linux-cpp 工具。
(2)编译:编译就是把 C/C++代码(比如上述的“.i”文件)“翻译”成汇编代码,所用到的工具为 cc1(它的名字就是 cc1,不是 arm-linux-cc1)。
(3)汇编:汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在 Linux 系统上一般表现为 ELF 目标文件(OBJ 文件),用到的工具为 arm-linux-as。“反汇编”是指将机器代码转换为汇编代码,这在调试程序时常常用到。
(4)链接:连接就是将上一步生成的 OBJ 文件和系统库的 OBJ 文件、库文件连接起来,最终生成了可 以在特定平台运行的可执行文件,用到的工具为 arm-linux-ld。
/* File: hello.c */
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
以上面的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”命令可以观看编译的细节
3、连接器选项(Linker Option)
下面的选项用于连接 OBJ 文件,输出可执行文件或库文件。
(1)object-file-name
如果某些文件没有特别明确的后缀(a special recognized suffix),GCC 就认为他们是OBJ 文件或库文件(根据文件内容,连接器能够区分 OBJ 文件和库文件)。如果 GCC 执行连接操作,这些 OBJ 文件将成为连接器的输入文件。
gcc -o test main.o sub.o
main.o、sub.o 就是输入的文件。
(2)-llibrary
连接名为 library 的库文件。连接器在标准搜索目录中寻找这个库文件,库文件的真正名字是`liblibrary.a'。搜索目录除了一些系统标准目录外,还包括用户以`-L'选项指定的路径。一般说来用这个方法找到的文件是库文件──即由 OBJ 文件组成的归档文件(archive file)。连接器处理归档文件的方法是:扫描归档文件,寻找某些成员,这些成员的符号目前已被引用,不过还没有被定义。但是,如果连接器找到普通的 OBJ 文件,而不是库文件,就把这个 OBJ 文件按平常方式连接进来。指定`-l'选项和指定文件名的唯一区别是,`-l’选项用`lib'和`.a'把 library包裹起来,而且搜索一些目录。
(3)-nostdlib
不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。这个选项常用于编译内核、bootloader 等程序,它们不需要启动文件、标准库文件。
$ gcc -v -nostdlib -o test main.o sub.o
(4)-static
在支持动态连接(dynamic linking)的系统上,阻止连接共享库。
(5)-shared
生成一个共享 OBJ 文件,它可以和其他 OBJ 文件连接产生可执行文件。只有部分系统支持该选项。当不想以源代码发布程序时,可以使用-shared 选项生成库文件,比如对于 options 程 序,可以如下制作库文件:
$ gcc -c -o sub.o sub.c
$ gcc -shared -o sub.a sub.o
以后要使用 sub.c 中的函数 sub_fun 时,在连接程序时,将 sub.a 加入即可,比如:
$ gcc -o test main.o ./sub.a
可以将多个文件制作为一个库文件,比如:
$ gcc -shared -o sub.a sub.o sub2.o sub4.o
4、arm-linux-ld 选项
arm-linux-ld 用于将多个目标文件、库文件连接成可执行文件。
(1)直接指定代码段、数据段、bss 段的起始地址
-Ttext startaddr
-Tdata startaddr
-Tbss startaddr
其中的‘startaddr’分别表示代码段、数据段和 bss 段的起始地址,它是一个 16 进制数。在/work/hardware/led_on/Makefile 中,有如下语句:
arm-linux-ld -Ttext 0x0000000 -g led_on.o -o led_on_elf
它表示代码段的运行地址为 0x0000000,由于没有定义数据段、bss 段的起始地址,它们被依次放在代码段的后面。
5、arm-linux-objdump 选项
arm-linux-objdump 用于显示二进制文件信息,常用来查看反汇编代码。
使用格式如下:
(1)将 ELF 格式的文件转换为反汇编文件
$ arm-linux-objdump -D elf_file > dis_file
(2)将二进制文件转换为反汇编文件
$ arm-linux-objdump -D -b binary -m arm bin_file > dis_file