1,GCC所支持不同后缀名的处理方式
文件作用 |
后缀名 |
所对应的语言 |
编译流程 |
预处理文件 |
.c |
C原始程序 |
预处理、编译、汇编 |
.C/.cc/.cxx |
C++原始程序 |
预处理、编译、汇编 |
.m |
Objective C原始程序 |
预处理、编译、汇编 |
.h |
预处理文件(头文件) |
(不常出现在指令行) |
编译文件 |
.i |
已经过预处理的C原始程序 |
编译、汇编 |
.ii |
已经过预处理的C++原始程序 |
编译、汇编 |
汇编文件 |
.s/.S |
汇编语言原始程序 |
汇编 |
链接文件 |
.o |
目标文件 |
链接 |
.a/.so |
编译后的库文件 |
链接 |
2,GCC编译流程分析
编译阶段 |
源文件 |
命令参数 |
目标文件 |
示例 |
参数解释 |
预处理阶段 |
.c |
-E |
.i/.ii(C代码) |
gcc -E test.c -o test.i -Wall |
-E:使编译器在预处理结束时就停止编译 |
.C/.cc/.cxx |
-o:制定GCC的输出结果 |
.m |
-Wall:(预处理阶段不起作用) |
编译阶段 |
.i |
-S |
.s/.S(汇编代码) |
gcc -S test.i -o test.s -Wall |
-S:使编译器在编译结束后就停止 |
.ii |
-Wall:编译时打印出所有警告 |
汇编阶段 |
.s/.S |
-c |
.o(二进制代码) |
gcc -c test.s -o test.o -Wall |
|
链接阶段 |
.o |
|
|
gcc test.o -o test.out |
|
.a/.so |
|
3,GCC链接阶段的参数解释
</tbody>
库路径 |
描述 |
参数 |
描述 |
举例 |
解释 |
相关路径 |
库文件不在系统默认路径下 |
-I<dir> |
在头文件的搜索路径列表中添加<dir>目录 |
gcc hello.c -I/root/work/gcc -o hello |
程序所需使用的库在"/root/work/gcc/"路径下 |
-L<dir> |
在库文件的搜索路径列表中添加<dir>目录 |
gcc hello.c -I/root/work/gcc/lib-sunq-o -o hello |
程序要链接"/root/work/gcc/"路径下的库"libsunq.so" |
链接库 |
"/usr/lib"路径下的库文件文件 |
-l |
指明具体使用的库文件 |
gcc hello.c -lm -o hello |
(Linux中函数库都以lib开头,因此-l后只需跟lib后的部分)有静态库文件"libm.a",调用时只需写"-lm" |
-static |
系统默认链接的是共享库。-static将禁止使用共享库 |
gcc hello.c -static -lm -o hello |
系统中同时存在库名相同的静态库文件"libm.a"和动态库文件"libm.so",系统默认采用动态链接方式,若想使用静态库,则需加"-static" |
4,静态库创建与使用
a,编写库源码hello.c
#include <stdio.h>
#include "hello.h"
void hello(void)
{
printf("hello world\n");
return 0;
}
b,给库源码编写头文件hello.h
#ifndef __HELLO_H__
#define __HELLO_H__
void hello(void);
#endi
c,编译生成目标文件hello.o
linux@linux:~/test/stdio/static_library$ gcc -c hello.c -Wall
linux@linux:~/test/stdio/static_library$ ls
hello.c hello.h hello.o
d,创建静态库hello
"libm.a"是库文件名,"m"是库名
linux@linux:~/test/stdio/static_library$ ar crs libhello.a hello.o
linux@linux:~/test/stdio/static_library$ ls
hello.c hello.h hello.o libhello.a
e,使用nm,可以查看静态库中符号信息
linux@linux:~/test/stdio/static_library$ nm libhello.a
hello.o:
00000000 T hello
U puts
f,编写测试程序test.c
#include <stdio.h>
#include "hello.h"
int main(int argc, const char *argv[])
{
hello();
return 0;
}
g,编译test.c,并链接静态库libhello.a
linux@linux:~/test/stdio/static_library$ gcc test.c -o test.out -L. -lhello
linux@linux:~/test/stdio/static_library$ ls
hello.c hello.h hello.o libhello.a test.c test.out
linux@linux:~/test/stdio/static_library$ ./test.out
hello world
h,由于使用的是静态库,编译后相关代码已复制到可执行文件中。删除静态库,不影响程序执行
linux@linux:~/test/stdio/static_library$ ls
hello.c hello.h hello.o libhello.a test.c test.out
linux@linux:~/test/stdio/static_library$ rm libhello.a
linux@linux:~/test/stdio/static_library$ ls
hello.c hello.h hello.o test.c test.out
linux@linux:~/test/stdio/static_library$ ./test.out
hello world