一、Linux 指定动态库搜索路径
方法一:配置文件/etc/ld.so.conf中指定的动态库搜索路径,需要执行 /sbin/ldconfig使之生效。
方法二:环境变量LD_LIBRARY_PATH指定的动态库搜索路径。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
上面的设置方式只是临时的,假如重新启动一个窗口,需要重新设置。
方法三:编译代码指定动态库路径。
注意:第三种比较容易出错,当编译指定了动态库路径,生成的可执行文件默认搜索路径按照编译指定的路径去查找。
虽然第三种容易出错,但是简单粗暴,我个人工作中也是推荐使用的!
工作经验:linux,我们编译的二进制依赖的库是LD_LIBRARY_PATH 导进来的,其中有些动态库(如glic,但是和系统的glic版本不一样,大于系统)。此时,当一个大的shell脚本中,调用很多命令,如果我们使用LD_LIBRARY_PATH 导入这个的程序的依赖中也有个giibc,那么整个大的shell脚本都会优先使用整个LD_LIBRARY_PATH 进来的glic,导致,我们后面的一些程序出错。后面程序使用成了 LD_LIBRARY_PATH 进来的glic,这就是污染当前系统环境。
因此,工作总结:如果为了避免污染当前系统环境,独立使用一个shell并定义一下环境变量LD_LIBRARY_PATH ,我们可以用独立shell封装我们的linux二进制程序,调用时单独调用这个shell。 其他程序放在没有污染的shell中。
LIBRARY_PATH:程序编译时链接so
LIBRARY_PATH:程序编译时链接so
指定gcc编译需要链接动态链接库的目录。设置libtest1和libtest2目录
# export LIBRARY_PATH=$LIBRARY_PATH:/home/libtest1:/home/libtest2
//查看配置的编译环境
# env
//编译时分别链接libtest1目录libtest1.so与libtest2目录libtest2.so
# gcc *.c -L./libtest1 -L./libtest2 -ltest1 -ltest2
#arm-linux-gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld
二、静态库和动态库
静态库和动态库的打包
打包时,先应将各个.c文件编译汇编成为目标文件
动态库的生成:
gcc -fPIC -c child.c -o child.o
gcc --share child.o -o libchild.so
注:动态库的命名方式:libxxx.so(xxx表示库的名称)
生成动态库的指令的参数的含义
- –share:生成一个共享库,告诉gcc生成库,不生成可执行程序,不要去检测main函数
- -fPIC:产生与位置无关代码,当库用于多个程序共享,便于映射到每个程序中。 让库中的每个函数在各个程序中生成的时候相对于映射的起始位置的偏移量生成
静态库的生成:
gcc -c child.c -o child.o
ar -cr libchild.a child.o(后面的参数都是.o文件,可以不止一个,就是要打包的文件)
注:静态库的命名方式:libxxx.a(xxx表示库的名称)
生成静态库的指令的参数的含义:
- -c:创建静态库
- -r :当静态库要生成,判断是否要将所有的.o文件重新生成静态库,如果只是某一个.o修改了,内容未变,则只用将该模块替换,不用重新生成静态库。(可以没有该参数选项)
生成可执行程序时链接使用
gcc main.c -0 main -lxxx ( -l:后面加库的名称)
有三种方法:
1.必须将库文件放到指定路径下:/usr/lib64或/usr/lib
2.设置存放链接库时搜索路径的环境变量:将当前库文件所在的路径添加进去
export LIBRARY_PATH=$LIBRARY_PATH:.
冒号链接路径. 表示当前路径;该路径下存在静态库和动态库,但链接的是动态库,因为gcc默认链接的是动态库.
3.使用gcc -L选项指定链接库的搜索路径:gcc main.c -o mian -L./ -lchild
我们日常应用最多的方式,采用-L指定库的所在路径,我们链接静态库,将静态库放到指定的文件下,然后链接。
编译demo时链接静态库:
$gcc main.c -L. -lstack -Istack -o main
符号注明:-I 头文件目录 -L库目录 -l链接库名称
注意:可以不用-L ,我们可以直接使用绝对路径 /xx/xxx/xx.a引入静态库,因为静态库会打包进二进制程序中,最终的程序和xxx.a的路径没有关系,ldd查看二进制程序也看不出来(ldd只显示动态库依赖,不会显示静态库依赖),所以,我比较喜欢这种方式。