一、Linux生成动态库
- 两步生成动态库
1.gcc -fPIC -c test.c
2.gcc -shared -o libtest.so test.o
- 一步生成动态库
gcc -shared -fPCI -o libtest.so test.c
二、Linux生成静态库
1. 生成目标文件
gcc -c test.c
2.生成静态库
ar -r libtest.a test.o
ar参数:
-a :把新的目标文件(*.o)添加到静态库文件中现有文件之后;
-b :把新的目标文件(*.o)添加到静态库文件中现有文件之前;
-d :从指定的静态库文件中删除文件;
-m:把文件移动到指定的静态库文件中;
-p :把静态库文件中指定的文件输出到标准输出;
-q :快速地把文件追加到静态库文件中;
-r :把文件插入到静态库文件中;
-t :显示静态库文件中文件的列表;
-x :从静态库文件中提取文件;
-v :使用详细模式
三、导出指定函数
如果你test.c中有多个函数,但是不想没一个函数都让别人使用,那么就需要导出指定函数列表,和winodws下的模块定义.def文件和__declspec(dllexport)似的,那么如何做呢?
有四种方法:
- 在方法声明定义时,加修饰:attribute((visibility(“hidden”)))
就是说将不公开的函数都加上这个属性,没加的就是可见的
- gcc 在链接时设置 -fvisibility=hidden,则不加 visibility声明的都默认为hidden; gcc默认设置 -fvisibility=default,即全部可见;
在gcc中加了这个设置之后表示所有的函数都是对外不可见了,然后在代码里面对于想公开的函数加上 attribute((visibility(“default”)))
- 使用链接参数 –retain-symbols-file 控制静态符号表,–version-script 控制动态符号表
则除了export_func外,全部为内部可见;
- 使用libtool的export-symbols选项
本人推荐使用第三种,其他自行查询使用。
如你有代码如下:
#include <stdio.h>
#include "test.h"
void fun1()
{
printf("fun1\n");
}
void fun2()
{
printf("fun2\n");
}
libtest.map
{
global:
fun1();
local: *;
};
libtest.sym
fun2()
编译动态库:
gcc c -fPIC -shared -o libtest.so test.c -Wl,--retain-symbols-file=libtest.sym -Wl,--version-script=libtest.map
显而易见:动态符号表中是函数func_1,静态符号表中是func_2
动态符号表 (.dynsym)和静态符号表(.symtab)主要区别是
动态符号表 (.dynsym) 用来保存与动态链接相关的导入导出符号,不包括模块内部的符号。而 静态符号表(.symtab) 则保存所有符号,包括 .dynsym 中的符号。
详细介绍请移步:
https://blog.csdn.net/farmwang/article/details/72847529?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
或者自行百度。
四、使用动态库和静态库
- 使用动态库
把生成好的动态库libtest.so放到和待测试的程序同一级目录下
g++ -o testSO testSO.c -L. -ltest
或者
g++ -o testSO testSO.c -L. libtest.so
如有有环境变量/usr/lib 或者/usr/lib64
可以把libtest.so放到里边
g++ -o testSO testSO.c -ltest
- 使用静态库
把生成好的静态库libtest.a放到和待测试的程序同一级目录下
g++ -o testSO testSO.c -L. -ltest
或者
g++ -o testSO testSO.c -L. libtest.a
如有有环境变量/usr/lib 或者/usr/lib64
可以把libtest.so放到里边
g++ -o testSO testSO.c -ltest
提示:我一般都是把需要连接的库(动态库或者静态库)放到当前目录下,不放到/usr/lib或者/usr/lib64,如果放到当前目录下需要添加环境变量,因为在运行的时候需要找到这个动态库,根据需要自行修改就可以了。