linux环境
静态库的制作和使用:
这里我们示例多文件的打包成静态库,首先建立4个文件(add_sub.c add_sub.h mul_div.c mul_div.h)在建立一个main.c
静态库的制作命令及步骤:(静态库的命名 lib文件名.a )
1、将所有要加入静态库的源文件编译成目标文件
例如:gcc -c add_sub.c mul_div.c
2、将要加入静态库的所有目标文件打包到静态库文件中
例如:ar -cr libcalc.a *.o
-c create的意思
-r replace的意思,表示当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
3、使用静态库链接成可执行文件
例如:gcc main.c -L. -ltcalc
注意点:-L+库函数的所在路径 就是让链接器到这个路径下到这个额路径下找库文件
-l(小写的L)+库名 指定库的名字
.代表当前路径
4、如何查看静态库中的内容
ar -tf 库名 看到的是函数库中包含的目标文件的名字
5、查看静态库文件中的包含哪些函数
动态库的制作和使用:
1、将所有要加入动态库的源文件生成与位置无关的代码
-fpic(fPIC):产生位置无关代码(fpic两种写法谁都可以)
gcc -c -fpic add_sub.c mul_div.c
2、将第一步生成的目标文件,打包到动态裤文件中
gcc -shared -o libcalc.so *.o
3、使用动态库链接生成可执行文件
gcc main.o -L. -lt_math
虽然可以编译通过,但是在执行的时候或找不到动态库文件而报错
4、下面几种解决方式
1)将生成的动态库文件放到系统自动搜索的路径(一般是 /lib /usr/lib)使用gcc -v main.c 查看LIBRARY_PATH=...
2) 通过环境变量LD_LIBRARY_PATH告诉加载器到那些路径下搜索库文件
只需要把LD_LIBRARY_PATH的值加上动态库的路径即可
使用LD_LIBRARY_PATH环境变量。(临时有效,且有时候没有效果),把需要添加的路径加入到LD_LIBRARY_PATH中, 注意如果多于一个要用冒号隔开
例如:export LD_LIBRARY_PATH=/home/htt/test:$LD_LIBRARY_PATH
3)在/etc/ld.so.conf文件中指定了默认的动态链接库查找路径,我的/etc/ld.so.conf文件内容是这样的
include /etc/ld.so.conf.d/*.conf。
也就是说在ld.so.conf.d文件夹在的所有.conf文件
我们只需要把需要的路径加到/etc/ld.so.conf.d目录下的任何一个文件中,再运行ldconfig就可以了
为了不影响其他程序的正常运行,或者自己想独立一个文件,就在/etc/ld.so.conf.d目录下创建一个.conf文件,里面写上自己的包含的动态库文件路径就好了,最后运行一下ldconfig。
4)gcc main.c -lcalc -L./ -Wl,-rpath=./ -o main
(大写W 小写L)
使用-WI,rpath指定动态库的目录
linux下应用程序依赖的动态库另有依赖动态库时,该程序该如何编译?
假设程序test依赖动态库b,而动态库b依赖动态库a。
在编译test的时候,我们希望的是只指定b,而不用指定a,因为我们不希望知道a的依赖库有哪些,只需关心b。那么我们采用这样的思路去编译test的时候,是会报错的。比如:
我们编译动态库a:gcc a.c -o liba.so -shared -fPIC
我们编译动态库b:gcc b.c -o libb.so -shared -fPIC -I../a/ -L../a/ -la
我们编译test:gcc main.c -o test -I../b -L../b -lb
程序会报错如下:
/usr/bin/ld: warning: liba.so, needed by ../b/libb.so, not found (try using -rpath or -rpath-link)
../b/libb.so: undefined reference to `a'
collect2: ld returned 1 exit status
错误的原因在于程序没能自动找到liba.so,因为liba.so不在ld的默认搜索路径里。解决方法是如下编译:
gcc main.c -o test -I../b -L../b -lb -Wl,-rpath=../a