目录
交叉编译
hello.c文件
提问
GCC编译器
GCC编译过程
GCC常用选项
编译多个文件
预处理
编译
汇编
链接
交叉编译
hello.c文件
#include <stdio.h>
int main(int argc, char argv)
{
if(argc >= 2)
printf("Hello, %s!\n", argv[1]);
else
printf("Hello, world!\n");
return 0;
}
在虚拟机上的Ubuntu编译、执行(需要预先安装gcc):
gcc -o hello hello.c(编译)
./hello(执行)
Hello, world!(输出打印)
./hello couvrir(执行)
Hello, couvrir!(输出打印)
gcc编译是给PC机编译的,里面的机器指令是x86。如果想要给ARM板编译出hello程序,需要使用交叉编译工具链。
在ARM上的Ubuntu编译(需要预先安装gcc-arm-linux-gnueabihf):
gcc-arm-linux-gnueabihf -o hello hello.c(编译)
提问
怎么确定交叉编译器中头文件的默认路径?
进入交叉编译器的目录里,执行:find -name "stdio.h"。
找到"stdio.h"位于一个"include"目录下的根目录里。
怎么自己指定头文件目录?
编译时,加上"-I <头文件目录>"这样的选项。
怎么确定交叉编译器中库文件的默认路径?
进入交叉编译器的目录里,执行:find -name lib。
可以得到xxx/lib、xxx/usr/lib,一般这两个目录就是要找的路径。如果有很多类似的lib,可以进去看看,有很多so文件的目录一般就是要找的路径。
怎么自己指定库文件目录、库文件?
编译时,加上"-L <库文件目录>"这样的选项,用来指定库目录。
编译时,加上"-labc"这样的选项,用来指定库文件libabc.so。
GCC编译器
GCC编译过程
GCC常用选项
通过不同的gcc选项可以控制这些流程:
gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s(先编译,不链接)
gcc -o hello hello.o(再链接)
常用选项 | 描述 |
-E | 预处理 |
-c | 只执行预处理、编译、汇编 |
-o | 指定输出文件 |
-I(i的大写) | 指定头文件目录 |
-L | 指定链接时库文件目录 |
-l(L的小写) | 指定链接时库文件 |
编译多个文件
一起编译、链接:
gcc -o test main.c sub.c
分开编译、统一链接:
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -o test main.o sub.o
预处理
C/C++源文件中,以“#”开头的命令被称为预处理命令,如#include为包含命令、#dedine为宏定义命令、条件编译命令#if等。
预处理就是将要包含的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些内容输出到“.i”文件中等待进一步处理。
编译
编译就是把C/C++代码(比如.i文件)翻译成汇编代码。所用的工具是cc1(x86有自己的cc1命令,ARM板也有自己的cc1命令)。
汇编
汇编就是把输出的汇编代码翻译成机器代码。在Linux系统上一般表现为ELF目标文件(OBJ文件),用到的工具为as(x86有自己的as命令,ARM板也有自己的as命令)。
反汇编是指将机器代码转换为汇编代码(调试时常用)。
链接
链接就是将生成的OBJ文件和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。用到的工具为ld或collect2。