1. gcc/g++/clang
了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数。
clang
clang 是一个C、C++、Object-C
的轻量级编译器。基于LLVM
(LLVM是以C++编写而成的构架编译器的框架系统,可以说是一个用于开发编译器相关的库)
gcc
GNU C
编译器。原本只能处理C语言
,很快扩展,变得可处理C++
。(GNU计划,又称革奴计划。目标是创建一套完全自由的操作系统)
g++
GNU c++
编译器
gcc、g++、clang都是编译器。
- gcc和g++都能够编译c/c++,但是编译时候行为不同。
- clang也是一个编译器,对比gcc,它具有编译速度更快、编译产出更小等优点,但是某些软件在使用clang编译时候因为源码中内容的问题会出现错误。
- clang++与clang就相当于gcc与g++。
对于gcc与g++:
- 后缀为
.c
的源文件,gcc把它当作是C程序,而g++当作是C++程序;后缀为.cpp
的,两者都会认为是c++程序 - g++会自动链接c++标准库stl,gcc不会
- gcc不会定义__cplusplus宏,而g++会
linux安装gcc
apt install build-essential #安装gcc、g++与make
2. 编译器过程
一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)、和连接(linking)才能变成可执行文件。
1、预处理
gcc -E main.c -o main.i
-E
的作用是让gcc在预处理结束后停止编译。
预处理阶段主要处理include和define等。它把#include包含进来的.h 文件插入到#include所在的位置,把源程序中使用到的用#define定义的宏用实际的字符串代替
2、编译阶段
gcc -S main.i -o main.s
-S
的作用是编译后结束,编译生成了汇编文件。
在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。
3、汇编阶段
gcc -c main.s -o main.o
汇编阶段把 .s文件翻译成二进制机器指令文件.o,这个阶段接收.c, .i, .s的文件都没有问题。
4、链接阶段
gcc -o main main.s
链接阶段,链接的是函数库。在main.c中并没有定义”printf”的函数实现,且在预编译中包含进的”stdio.h”中也只有该函数的声明。系统把这些函数实现都被做到名为libc.so
的动态库。
函数库一般分为静态库和动态库两种
- 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。Linux中后缀名为”.a”。
- 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库。Linux中后缀名为”.so”,如前面所述的libc.so就是动态库。gcc在编译时默认使用动态库。
静态库节省时间:不需要再进行动态链接,需要调用的代码直接就在代码内部
动态库节省空间:如果一个动态库被两个程序调用,那么这个动态库只需要在内存中
Java中在不经过封装的情况下只能直接使用动态库。