First, the overall outline
Second, the production of static library
1) naming convention
name library lib + + .a
example: lib yuchuan II.A
2) Production steps:
1) generating a corresponding .o file - .c -> .o -C.
2) will be generated. o file name packaged ar rcs + static library (libMytest.a) + generated by all .o
3) release and use static libraries:
1) publish static library.
2) headers.
4) advantages and disadvantages:
Third, the package static libraries
A. GCC use
1. GCC compilation process
(1) Pretreatment (cpp) gcc -E (usually end output .i ask price), to expand the file header, macro substitution operation and the like;
(2) a compiler (gcc) gcc -S (divalent output Q ending .s) generating assembly code;
(3) assembler (as) gcc -c (output files ending with .o) compiled into the compiled binary file;
(4) connectors (ld) gcc, an executable file link library lib.
Performed as follows (hello.c):
1 #include<stdio.h> 2 3 int main() 4 { 5 printf("hello world\n"); 6 return 0; 7 }
Linux执行过程:
[root@centos1 src]# gcc -E hello.c >> hello.i [root@centos1 src]# gcc -S hello.i [root@centos1 src]# gcc -c hello.s [root@centos1 src]# gcc -o hello.out hello.o [root@centos1 src]# ./hello.out hello world
注:第4步如果使用 ld 会报如下错误
[root@centos1 src]# ld hello.o ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0 hello.o: In function `main': hello.c:(.text+0xa): undefined reference to `puts'
没有 __start 是因为C程序以main为主函数,汇编以start为主函数入口,改用gcc连接就可以,如果非用ld,需要自己链接libc.so库。
2. GCC编译参数
- -I 包含头文件路径(可以使绝对路径,也可以是相对路径)
- -O 优化选项,1-3越高优先级越高
- -L 包含的库路径
- -l(L的小写)指定库名(通常libxxx.so或者libxxx.a,-lxxx)
- -o 目标文件
- -c 编译成.o文件
- -g 用于gdb调试不加此选项不能gdb调试
- -Wall 显示更多的警告
- -D 指定宏编译
- -lstdc++ 编译c++代码
二. 动静库
1. 制作库文件作用
作用:将实现某部分功能的代码封装成库文件,以方便调用,或者是对代码进行保护加密。
应用场景:有时想将某代码提供给别人用,但是又不想公开源代码,这时可以将代码封装成库文件。在开发中调用其他人员编写的库。
2. 静态库
(1)制作步骤
1)编译.o文件
2)将.o文件打包:ar rcs libname.a file1.o file2.o file3.o ...
3)将头文件与库一起发布
文件内容及路径分布如下:
[root@centos1 calc]# tree
.
├── include
│ └── head.h
├── lib
├── main.c
└── src
├── add.c
└── sub.c
1 #include<stdio.h> 2 3 int add(int a, int b); 4 int sub(int a, int b);
1 #include "head.h" 2 3 int add(int a, int b) 4 { 5 return a + b; 6 } 7 8 add.c
1 #include "head.h" 2 3 int sub(int a, int b) 4 { 5 return a - b; 6 } 7 8 sub.c
- 编译为.o文件
进入到 src 目录下执行:
[root@centos1 src]# gcc -c *.c -I ../include/ [root@centos1 src]# ll 总用量 16 -rw-r--r--. 1 root root 63 4月 20 14:53 add.c -rw-r--r--. 1 root root 1240 4月 20 15:10 add.o -rw-r--r--. 1 root root 63 4月 20 14:24 sub.c -rw-r--r--. 1 root root 1240 4月 20 15:10 sub.o
- 将.o文件打包,制作成libCalc.a静态库
[root@centos1 src]# ar rcs libCalc.a *.o [root@centos1 src]# ll 总用量 20 -rw-r--r--. 1 root root 63 4月 20 14:53 add.c -rw-r--r--. 1 root root 1240 4月 20 15:10 add.o -rw-r--r--. 1 root root 2688 4月 20 15:12 libCalc.a -rw-r--r--. 1 root root 63 4月 20 14:24 sub.c -rw-r--r--. 1 root root 1240 4月 20 15:10 sub.o
(2)使用
编译时需要加静态库名(记得路径),-I 包含头文件
- 使用静态库编译main.c并执行main
我们将libCalc.a移动到上层的lib中并退回到calc目录,编译main.c并执行:
[root@centos1 calc]# gcc main.c -o main -I include/ -L ./lib -lCalc [root@centos1 calc]# ll 总用量 24 drwxr-xr-x. 2 root root 4096 4月 20 15:07 include drwxr-xr-x. 2 root root 4096 4月 20 15:14 lib -rwxr-xr-x. 1 root root 6838 4月 20 15:14 main -rw-r--r--. 1 root root 179 4月 20 14:57 main.c drwxr-xr-x. 2 root root 4096 4月 20 15:14 src [root@centos1 calc]# ./main + 10 is 20 - 10 is 0
可以用 nm 命令查看文件内容:
[root@centos1 calc]# nm lib/libCalc.a
add.o:
T add
sub.o:
T sub
(3)静态库优缺点
优点:
1)执行快
2)发布应用时不需要发布库
缺点:
1)执行程序体积会比较大
2)库变更时需要重新编译程序