linux上应用程序如果依赖so库,执行时需要能找到so库才能正确执行,与Windows(默认会在当前目录查找)和Mac OS X(基于rpath, install_name)的查找机制不同,linux上需要系统lib目录下找到或者显式指定LD_LIBRARY_PATH来引导程序搜索动态库的路径。
通过ldd命令可以查看linux上可执行程序或so库的依赖项。
程序加载so库的几种查找机制
指定环境变量 LD_LIBRARY_PATH
例如:
export LD_LIBRARY_PATH=/home/suninf/ffmpeg_build/lib:$LD_LIBRARY_PATH
依赖库安装到系统目录
- 如果是管理员权限
- so库可以安装到
/usr/lib
,如果是64位程序,一般安装到/usr/lib64
- 头文件
/usr/include
- 可执行程序
/usr/bin
- so库可以安装到
- 一般用户权限
- 可以安装到
/usr/local/lib
或/usr/local/lib64
- 头文件
/usr/local/include
- 可执行程序
/usr/local/bin
- 可以安装到
把依赖库路径添加到系统搜索路径
- 需要管理员权限,在
/etc/ld.so.conf
文件最后添加 so库所在的路径 sudo ldconfig -v
刷新系统搜索缓存
关于环境变量和脚本启动
linux上应用程序部署后(so模块没有安装在系统目录下的话),一般是shell脚本启动的:
1) 脚本设置应用依赖的动态库so目录LD_LIBRARY_PATH,相关的依赖设置
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
2) 脚本启动应用
比如:
help.h
#if defined(HELP_IMPLEMENT) #define HELP_EXP __attribute__((visibility("default"))) #else #define HELP_EXP #endif HELP_EXP int add(int a, int b);
help.cc
#include "help.h" int add(int a, int b) { return a+b; }
main.cpp
#include <iostream> #include "help.h" template<typename T> void print(T const& t) { std::cout << "print: " << t << "\n"; } int main() { std::cout << add(1,2) << "\n"; print( add(3,4) ); return 0; }
Makefile
objects = main.o help_objects = help.o main : $(objects) help g++ -o main $(objects) -L ./ -lhelp help : $(help_objects) g++ -fPIC -shared -DHELP_IMPLEMENT -o libhelp.so $(help_objects) clean : rm main $(objects) $(help_objects) libhelp.so
startup.sh
#!/bin/bash export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ./main
运行:
$ make
g++ -c -o main.o main.cpp
g++ -c -o help.o help.cc
g++ -shared -o libhelp.so help.o
g++ -o main main.o -L ./ -lhelp
$ ./startup.sh
3
print: 7
如果不设置LD_LIBRARY_PATH,则会报错:
./main: error while loading shared libraries: libhelp.so: cannot open shared object file: No such file or directory