-52- 嵌入式Linux系统开发与应用实验教程
其中:-g 选项表示在文件中产生调试信息;-c 选项指定将输入的源文件编译成目标文件;-o 选项指定输出文件名。
2. 命令选项列表
(1)输出控制选项如下:
-c:将输入的源文件编译成目标文件; -S:将C/C++文件生成汇编文件; -o file:将输出内容存于文件file;
-pipe:在编译的不同阶段之间采用管道通信方式; -v:打印出编译过程中执行的命令;
-x language:说明文件的输入类型为language。
(2)C语言选项如下:
-ansi:支持所有ANSI C程序。
(3)警告选项如下: -w:关闭所有警告; -Wall:打开所有警告;
-Wimplicit:如果有隐含申明,显示警告信息; -Wno-implicit:不显示对隐含申明的警告。
(4)调试选项如下:
-g:该选项在文件中产生调试信息以便调试程序(调试信息的文件格式有stabs、COFF、XCOFF、DWARF)。
(5)优化选项如下: -O0:不优化; -O1:一级优化; -O2:二级优化; -O3:三级优化。
(6)预处理选项如下: -E:运行C的预处理器;
-C:在运用-E进行预处理时不去掉注释; -D macro:定义宏macro 为1; -D macro =defn:定义宏macro为defn。
第3章 Linux下应用程序开发基础 -53-
(7)汇编选项如下:
-Wa,option:将选项option传递给汇编器。
(8)搜索路径选项如下: -I dir:设置搜索路径为dir;
-I-:指定只对#include“file”有效的头文件搜索目录。
3. 源文件类型的识别
arm-elf-gcc能够自动根据文件名后缀识别文件类型。 文件名后缀和文件类型的对应关系如下: *.c:C源文件;
*.i:经过预处理后的C源文件; *.h:C头文件;
*.ii:经过预处理后的C++源文件; *.cc:C++源文件; *.cxx:C++源文件; *.cpp:C++源文件; *.C:C++源文件;
*.s:不需要预处理的汇编文件; *.S:需要预处理的汇编文件。
此外,用户可通过-x language 说明文件的输入类型,此时可以不用以上的后缀规则。例如:-x language
其中的language可为以下参数: c:C源文件; c++:C++源文件; c-header:C头文件;
cpp-output:经过预处理后的C源文件; c++ -cpp-output:经过预处理后的C++源文件; assembler:不需要预处理的汇编文件; assembler-with-cpp:需要预处理的汇编文件。 例如,编译一个不需要预处理的C程序: arm-elf-gcc –c –g –x cpp-output hello.c -x none
如果-x后面未跟任何参数,则按照文件的后缀名做相应处理。
4.命令的使用
-54- 嵌入式Linux系统开发与应用实验教程
(1)输出文件名的指定
-o file。将输出内容存于文件file,仅适用于只有一个输出文件时。例如,将hello.c编译成汇编程序并存放于文件hello.txt:
arm-elf-gcc –S –o hello.txt hello.c
(2)目标文件的生成
-c。将输入的源文件编译成目标文件。例如,将hello.c编译成hello.o: arm-elf-gcc –c –o hello.o hello.c
(3)将C/C++文件生成汇编文件
-S。将C/C++文件生成汇编文件。例如,将hello.c编译生成汇编文件hello.s: arm-elf-gcc –S –o hello.s hello.c
(4)预处理文件的生成
-E。只对源文件进行预处理并且默认输出到标准输出。例如,对hello.c进行预处理并将结果输出到屏幕:
arm-elf-gcc –E hello.c
(5)设置头文件搜索路径
头文件的引用有两种形式:一种是 # include“filename”,另一种是 # include
① -I dir。将目录dir添加到头文件搜索目录列表的第一项。通过此选项可以使用户头文件先于系统头文件被搜索到。如果同时用-I选项添加几个目录,目录被搜索时的优先级顺序为从左到右。
例如,编译hello.c,在当前目录和/μClinux目录中搜索hello.c所包含的头文件: arm-elf-gcc –I./ -I/μClinux –c hello.c
② -I-。-I-以前用-I指定的头文件搜索目录只对 # include“file”有效,对 # include
(6)控制警告产生
用户可以使用以-W开头的不同选项对特定警告进行设定。 例如,如有隐含申明,显示警告信息: arm-elf-gcc –c -Wimplicit hello.c
(7)实现优化
第3章 Linux下应用程序开发基础 -55-
优化的主要目的是使编译生成的代码的尺寸更小、运行速度更快,但是在编译过程中随着优化级别的升高,编译器会相应消耗更多时间和内存,而且优化生成代码的执行顺序和源代码有一定出入,因此优化选项更多地用于生成固化代码,而不用于生成调试代码。
① - O1。可以部分减小代码尺寸,对运行速度有一定的提高。较多地使用了寄存器变量,提高指令的并行度。
② - O2。除了解循环、函数插装和静态变量优化,几乎包含arm-elf-gcc所有优化选项。一般在生成固化代码时使用该选项较为适宜。
③ -O3。包含- O2的所有优化,并且还包含了解循环、函数插装和静态变量优化。通常情况下,该级优化生成的代码执行速度最快,但是代码尺寸比- O2大一些。
(8)在命令行定义宏
☉-D macro:定义宏macro 为1。 ☉-D macro =defn:定义宏macro为defn。
例如,编译hello.c并且预定义宏RUN_CACHE值为1的命令行如下: arm-elf-gcc –c –D RUN_CACHE hello.c
编译hello.c并且预定义宏RUN_CACHE值为0的命令行如下: arm-elf-gcc –c –D RUN_CACHE=0 hello.c
3.3.3 交叉连接器arm-elf-ld
arm-elf-ld根据链接定位文件Linkcmds中代码段、数据段、BBS段和堆栈段等定位信息,将可重定位的目标模块链接成一个单一的、绝对定位的目标程序,该目标程序是ELF格式,并且可以包含调试信息。arm-elf-ld可以输出一个内存映像文件,该文件显示所有目标模块、段和符号的绝对定位地址,它也产生目标模块对全局符号引用的交叉参考列表。
1. 命令格式
arm-elf-ld的命令格式如下: arm-elf-ld [option] file ?
命令行后跟选项和可重定位的目标文件名。
例如,若链接的输入文件为ming.o,输出文件为ming.elf,链接的库为libxxx.a,生成内存映像文件map.txt,链接定位文件为linkcmds,则命令如下:
arm-elf-ld –Map map.txt –N –T linkcmds –L . /lib –o ming.elf ming.o -lxxx
2. 命令选项列表
arm-elf-ld的命令选项列表如下: -e entyr:指定程序入口;
-56- 嵌入式Linux系统开发与应用实验教程
-Map:指定输出映像文件; -M:输出链接信息; -lar:指定链接库; -L dir:添加搜索路径; -o:设置输出文件名;
-Tcommandfile:指定链接命令文件; -v:显示版本信息。
3.命令使用
(1) 程序入口地址
-e entry是以符号entry作为程序执行的入口地址,而不从默认的入口地址开始。 例如,链接的输入文件为ming.o,输出文件为ming.elf,链接定位文件为linkcmds,将入口地址设为_start,命令如下:
arm-elf-ld -T linkcmds –e_start –o ming.elf ming.o
(2)输出链接信息
①-M。在标准端口打印出符号映像表和内存分布信息。
例如,链接的输入文件为ming.o,输出文件为ming.elf,在标准端口打印出符号映像表和内存分布信息,命令如下:
arm-elf-ld –M –o ming.elf ming.o
如果标准输出设置为显示器,运行命令后将在显示器上显示内存映像信息和符号映像表。 ②-Map mapfile。将链接的符号映像表和内存分布信息输出到文件mapfile里。 例如,链接的输入文件为ming.o,输出文件为ming.elf,将链接的符号映像表和内存分布信息输出到文件map.txt里,命令如下:
arm-elf-ld -Map map.txt –o ming.elf ming.o
(3)指定链接的库
-lar。用于指定库文件libar.a为链接的库。可以重复使用-1来指定多个链接的库。 例如,链接的输入文件为ming.o,指定libxxx.a为链接的库,输出文件为ming.elf,命令如下:
arm-elf-ld –o ming.elf ming.o –1xxx
注意:库的命名规则为libxxx.a,在-1指定库名时使用的格式为-1xxx。
(4)添加库和脚本文件的搜索路径
-Ldir。用于将dir添加到搜索路径。搜索顺序按照命令行中输入的顺序,并且优先于默认的搜索路径。所有在-L添加的目录中找到的-1指定的库都有效。