一、编译步骤:
一个源码文件需要经过预处理、编译、汇编和连接四个步骤完成可执行档的生成.
1.预处理
处理的内容:
C/C++源文件中,以"#"开关的命令被称为预处理命令,如包含命令"#include"、宏定义命令"#define"、条件编译命令"#if"、"#ifdef"等.预编译阶段完成的工作是将头文件(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码.
输出文件:
输出".i"文件等待进一步处理.
所用工具:
arm-linux-cpp.
2.编译
把上述的".i"文件翻译成汇编代码.
输出文件:
输出".s"文件等待进一步处理.
所用工具:
ccl,而不是arm-linux-ccl
3.汇编
汇编就是将上述编译的汇编代码翻译成符合一定格式的机器代码.
输出文件:
输出ELF格式目标文件.
所用工具:
arm-linux-as
4.连接
将上述汇编生成的OBJ文件和系统库的OBJ文件、库文件连接起来,最终生成可以在特定平台运行的可执行文件.
所用工具:
arm-linux-ld
二、arm-linux-gcc选项
1.-c
预处理、编译和汇编源文件,不作连接.默认情况下通过".o"替换文件名后缀".c",".i",".s"等.
2.-S
编译后停止,不作汇编处理.默认情况下用".s"替换源文件后缀".c",".i"等.
3.-E
预处理后即停止,不进行编译.
4.-o file
指定输出文件为file.如果没有指明使用"-o"选项,默认输出为a.out.
5. -v
显示编译过程及编译器版本号.
如:
gcc -v -o main main.c
编译过程会打印编译器的版本信息及连接的标准库.
实例解释:
比如,可执行文件main_test是由main.c和test.c两个源文件生成物.可以通过下面三条命令完成.
gcc -c -o main.o main.c
gcc -c -o test.o test.c
gcc -o main_test main.o test.o
6. -Wall
打开所有需要注意的警告信息,如没有指定类型的声明、在声明之前就使用函数、局部变量只有声明没有再使用等.
7. -g
产生调试信息,供GDB使用.
8. -On (n=1,2,3)
优化级别,n数值越高,优化越厉害.一般实际使用过程使用-O2等级.
9. -llibrary
从标准搜索目录下寻找名为library的库文件.此库文件实际的名字为"liblibrary.a",因为编译器会自动过滤掉库"lib"前缀及".a"后缀.
从指定目录下寻找库文件可以通过-L指定.
10.-nostartfiles
不连接系统标准启动文件.往往在bootloader、内核中会选用此选项,因为bootloader、kernel开始阶段时,启动环境还没实现好.
如,gcc -v -nostartfiles -o test main.o sub.o
11. -nostdlib
不连接系统标准启动文件和标准库文件,只需要把指定的文件传递给连接器.像boodloader、kernel等程序,里面没有标准C库的,但是标准C库的功能已经被以源码的形式重新封装.
如,gcc -v -nostdlib -o test main.o sub.o
12. -static
静态编译,把引用的库文件放入文件系统中.编译出来的可执行档比较大.
如,gcc -o test_static main.o sub.o -static
13. -shared
生成OBJ文件,它可以和其他OBJ连接产生可执行档.当不想以源码发布程序时,可以使用此选项生成库文件.
如,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 sub3.o
14. -Idir
在头文件的搜索路径列表添加dir目录.
头文件搜索方法为:如果以"#include<>"包含文件,则只在标准库目录下开始搜索(包括使用-Idir选项定义的目录);如果以'#include "file.h"'包含文件,则先从用户的工作目录开始搜索,再搜索标准库目录.
15. -Ldir
在"-I"选项的搜索路径列表中添加dir目录.
使用实例:
gcc -c -o sub.o sub.c
gcc -shared -o libsub.a sub.o
编译main.c:
gcc -c -o main.o main.c
连接程序,下面报找不到库文件的错误:
gcc -o test main.o -lsub
/usr/bin/ld:cannot find -lsub
collect2:ld returned 1 exit status
使用"-Ldir"选项将当前目录加入到搜索路径,如下:
gcc -o test main.o -L./ -lsub
上述代码表示在当前路径下寻找libsub.a库文件.