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