一:gcc编译器
GNU CC(简称为gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。gcc不仅功能强大,而且可以编译如C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多种语言,而且gcc又是一个交叉平台编译器,适合在多种架构中开发程序!!
编译过程:
把一个.c文件编程一个可执行文件,其实就是这四个步骤:
预处理->编译->汇编->连接
再具体说明这几个过程的作用:
预处理阶段:
在该阶段,对包含的头文件(#include)和宏定义(#define、#ifdef等)进行处理 (替换)。预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。可以使用gcc的选项“-E” 让gcc在预处理结束后停止编译过程,如下!
gcc –E hello.c –o hello.i
- 1
编译阶段:
接下来进行的是编译阶段,在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
gcc –S hello.i –o hello.s
- 1
- 2
汇编阶段:
该阶段就是把编译阶段生成的目标“.s”文件生成目标文件
gcc –c hello.s -o hello.o
- 1
链接阶段:
链接是把.s汇编文件链接生成.o的目标文件,链接的作用把你使用的函数实现链接起来,比如你的程序使用了printf()函数,而“stdio.h”中也只有该函数的声明,而没有该该函数的实现,那么就需要也就是链接到libc.so.6库函数中去,这样就能够调用函数“printf”了,而这也是链接的作用。其命令如下:
gcc hello.o –o hello
- 1
其实gcc命令顺序可以变,但是大家一定要记住!-o后面一定是生成得目标文件
平时如果想把.c文件编译成可执行文件,直接如下就行
gcc hello.c -o hello
- 1
为了方便理解,这是gcc所支持后缀名解释:
二:动静态库
静态库:
静态库是一系列的目标文件(.o文件)的归档文件(文件名格式为libxxx.a),如果在编译某个程序时链接静态库,则链接器将会搜索静态库,从中提取出它所需要的目标文件并直接拷贝到该程序的可执行二进制文件(ELF格式文件)之中;静态库只在程序链接时起作用,最终的执行程序脱离静态库运行。
动态库
动态库(文件名格式为libxxx.so)在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。
实践是最好的说明:
静态库例子:
hello.c
#include<stdio.h>
void hello()
{
printf("hello world\n");
}
- 1
- 2
- 3
- 4
- 5
hello.h
void hello();
- 1
main.c
#include <stdio.h>
#include "hello.h"
int main()
{
hello();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
首先把hello.c生成.o目标文件
gcc –c hello.c -o hello.o
- 1
把hello.o生成静态库.a
ar rcsv libmy_lib.a hello.o
- 1
libmy_lib.a就是我们的静态库,静态库的命名规则:lib库名.a
这个时候你可以把库libmy_lib.a和头文件hello.h、给其他人使用了
然后main.c就可以使用这个库生成可执行文件
gcc main.c -o main -L./ -lmy_lib
- 1
注意:-L./是指链接库的位置,即当前目录下
那如果我的头文件hello.h是在./include目录下呢
gcc main.c -o main -I./include -L./ -lmy_lib
- 1
gcc 里关于库的一些选项:
标题
动态库:
还是上面的hello.c hello.h main.c
创建libmy_lib.so:
gcc -shared -fpic hello.c -o libmy_lib.so
- 1
动态库的命名规则:lib库名.so
gcc main.c -o main -L./ -lmy_lib
- 1
生成可执行文件main
运行时候
./main
- 1
发现执行错误,原因是动态库libmy_lib.so路径没找到,动态库不是在当前目录下吗?怎么又找不到!!因为运行文件用到函数的动态库,系统默认是在/lib或者/usr/lib/目录下,由/etc/ld.so.conf设置。
解决方法:
第一种方法:将libmy_lib.so复制到/lib或者/usr/lib/目录中
第二种方法:将库路径添加到环境变量LD_LIBRARY_PATH中去使用export指令
第三种方法:配置文件/etc/ld.so.conf中指定的动态库搜索路径
第四种方法:编译目标代码时指定的动态库搜索路径
Src : https://blog.csdn.net/haha1fan/article/details/76339285