gcc的操作
预处理
gcc -E file.c -o file.i
-E选项表示预处理完就停下来,在编译时-o file.i可以省略,编译器会默认生成同名的.i文件
编译
gcc -S file.i -o file.s
-s表示生成完汇编码就停下来,在编译时-o file.s可以省略,编译器会默认生成同名的.s文件
汇编
gcc -c file.s -o file.o
-c表示转换成机器码就停下来,在编译时-o file.o可以省略,编译器会默认生成同名的.o文件
链接
gcc file.o -o file
不带选项就直接形成可执行文件,-o file不加,编译器默认生成a.out可执行文件
注:有多个源文件时-o不能省略,因为有多个源文件时编译器不知道如何命名。
软链接
软连接本质上是创建一个新的文件,该文件有自己的inode,文件的内容是所连接文件的地址。
指令 : ln -s 源文件 目标文件
硬链接
硬链接本质上是对所连接的文件取别名,该文件没有自己的inode,只是在该文件的目录上建立了文件名和inode的映射关系
指令 : ln 源文件 目标文件
静态库
静态库在连接时是直接将所用函数的代码拷贝到文件当中。静态库要以lib开头,.a结尾
指令:ar -rc 源文件 目标文件
上述指令是对.o文件进行打包
当我们创建好静态库后该如何使用呢?
我们所创建的静态库并不是在系统默认的搜索路径下的,所以要进行如下指令
-(shift+i) .h文件的路径(不用带文件名,因为文件名在test.c中已经包含,操作系统知道在该路径下寻找哪个文件)
-L .c文件的路径
-l 静态库名(去掉lib前缀,.a后缀)
其它方式
1.将文件拷贝到系统默认的搜索路径下
.h文件:/usr/include
.so/.a库 : /lib64
2.采用软连接的方式将文件拷贝到系统默认的搜索路径下
注:使用了其它方式后一样要指明库名
动态库
动态库在连接时会给调用函数处一个该函数在动态库里的地址。静态库要以lib开头,.so结尾
指令 : gcc -shared -o 目标动态库名 源文件
我们所创建的动态库并不是在系统默认的搜索路径下的,同静态库一样
其他方法解决这一问题
1.将文件拷贝到系统默认的搜索路径下
.h文件:/usr/include
.so/.a库 : /lib64
2.采用软连接的方式将文件拷贝到系统默认的搜索路径下
动态库的加载解决方案
上述两种方式可以解决
1.将动态库的路径(不用加动态库名,因为链接时已经给过库名)添加到LD_LIBRARY_PATH环境变量下,这一个环境变量时操作系统提供给用户存放动态库路径的
2.在/etc/ld.so.conf.d/路径下创建一个.conf文件,将动态库的路径添加到该文件的内容中,一个.conf只能有一个路径。添加好后再执行ldconfig。
动态库的加载
我们在程序里使用的库接口在链接时会将调用函数处转换成库的起始地址+偏移量,所以在我们将动态库加载到内存当中时是可以在任意位置加载的,然后通过页表将虚拟地址空间和物理内存建立映射关系,但是在虚拟地址空间内会将动态库的起始地址存放在共享区里,
如:libc.so.6 (0x00007f86ecfc8000)
这样操作系统就可以通过起始地址+偏移量的方式访问到对应的函数了。