完成宏替换、文件引入,以及去除空行,注释等,为下一步编译做准备。也就是对各种预编译命令做处理,包括头文件的包含,宏定义的拓展、条件编译的选择等。
选项-E让gcc在预处理结束后停止编译,test.i
文件为预处理后的输出文件
gcc中可以通过-o
来指定输出文件
#test.c文件内容
#include
int main(){
printf("hello world!\n");
return 0;
}
gcc -E test.c -o test.i
选项-S
让gcc在编译结束后停止编译过程,test.s文件为编译后生成的汇编代码
gcc -S test.i -o test.s
汇编就是把编译阶段生成的.s文件转成二进制目标代码,也就是机器码(01序列)
选项-c
让gcc在汇编结束停止编译过程,test.o
文件为汇编结束生成的机器码目标文件
gcc -c test.s -o test.o
就是将多个目标文件以及所需的库文件链接称为可执行的目标文件的过程
-o
本质上是一个重命名选项,不使用-o
时,默认生成a.out
文件。这里生成的可执行文件时test
./test
执行后输出hello world!
$ gcc test.o -o test
$ ./test
hello world!
test.c代码内容
#include
int main(){
printf("hello world!\n");
return 0;
}
执行的操作
gcc -E test.c -o test.i
gcc -S test.c -o test.s
gcc -c test.o -o test
gcc test.o -o test
./test
这里有是三个文件
main.c tool.c tool.h
tool.h
int find_max(int arr[],int n);
tool.c
#include "tool.h"
int find_max(int arr[],int n){
int max = arr[0];
int i;
for(i=0;imax){
max=arr[i];
}
}
return max;
}
main.c
#include
#include "tool.h"
int main(){
int arr[]={1,3,5,8,2};
int max=find_max(arr,5);
printf("max =%d\n",max);
return 0;
}
.a
结尾,只用于生成可执行文件阶段。首先生成test.o目标文件
使用ar命令将test.o打包成libtest.o静态库
// 首先生成目标文件
gcc -c test.c -o test.o
//使用ar命令将目标文件打包静态库
ar rcs libtest.a test.o
//使用 ar t libtest.a 查看静态库内容
ar t libtest.a
test.o
gcc -c tool.c
ar rcs libtool.a tool.o
gcc -o main main.c -L. -ltool
./main 执行main文件
ls -lh 查看总共的大小
ldd main 查看依赖情况
首先生成test.o
目标文件
使用-shared
和-fPIC参数生成动态库
// 首先生成目标文件
gcc -c test.c
// 使用-fPIC和-shared生成东莞台库
gcc -shared -fPIC -o libtest.so test.o
gcc -shared -fPIC -o libtool.so tool.o
gcc -o main main.c -L. -ltool
./main
会报错
./main :error whild loading shared libraries:libtool.so : cannot open shared object file:such file or directory
ldd main 查看缺失的内容
LD_LIBRARY_PATH =. ./main 设置环境变量
载入的时刻不同
静态库在程序编译时会连接到目标代码中,程序运行时不需要静态库,因此体积比较大,而且每次编译都需要载入静态代码,因此内存开销大
动态库在编译是不会被链接到目标代码中,而是在程序运行时才被载入,程序运行时需要动态库存在,因此体积比较小。而且系统只需要载入一次动态库,不同程序可以得到内存中相同的动态库副本,因此内存开销小。