库文件在连接(静态库和共享 库)和运行(仅限共享库的程序,静态库会和可执行编译到一起)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到 库的搜索路径之中。
设置库文件的搜索路径总的来说有以下几种:
- LIBRARY_PATH、LD_LIBRARY_PATH等 环境变量:指定连接、运行时库文件路径;
- /etc/ld.so.conf 文件:添加链接时库文件的搜索路径,运行时还需要使用ldconfig命令将路径刷新到ld.so.cache中;
- g++/gcc参数-L、-l、-I:指定链接时库文件的路径、名字和头文件,运行时还需要使用环境变量或者在文件/etc/ld.so.conf中指定(或者放到默认/lib路径),然后ldconfig;
接下来我们分连接、运行不同阶段来分别解读一下。见:0.2动态链接、静态链接.note
1、环境变量:
在/etc/profile中添加如下环境变量。
1)编译时用到的环境变量:
#gcc找到头文件的路径
C_INCLUDE_PATH=/usr/include/libxml2:/MyLib
export C_INCLUDE_PATH
#g++找到头文件的路径
CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/libxml2:/MyLib
export CPLUS_INCLUDE_PATH
#gcc和g++在编译的链接(link)阶段查找库文件的目录列表
LIBRARY_PATH=$LIBRARY_PATH:/MyLib
export LIBRARY_PATH
2)运行时用到的环境变量:
#程序运行时查找ku文件的路径
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/MyLib
export LD_LIBRARY_PATH
3)示例:
一个头文件my_so_test.h和两个源文件test1.cpp、test2.cpp,将他们制作成一个名为libmytest.so的动态链接库文件:
3.1)先通过$ g++ -o libmytest.so -shared -fPIC test1.cpp test2.cpp 创建动态链接库;
3.2)编写一个main.cpp调用动态连接库:
#include "my_so.h"
int main()
{
test1();
test2();
return 0;
}
编译、连接:
解决方案:vim /etc/profile,添加如下,然后source /etc/profile:
LIBRARY_PATH=$LD_LIBRARY_PATH:/home/roo/kevinliu/test6/so
export LIBRARY_PATH
然后再编译、连接:$ g++ -o run main.cpp -lmytest 没问题了。
3.3)运行:
vim /etc/profile,添加如下,然后source /etc/profile
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/roo/kevinliu/test6/so
export LD_LIBRARY_PATH
然后再运行./run 没问题了。
2、/etc/ld.so.conf 文件:
将库文件的路径都加入到/etc/ld.so.conf中是明智的选择,添加方法也很简单,一行一个,例如:
/usr/X11R6/lib
/usr/local/lib
/opt/lib
添加完成后只是链接时不会报错,执行前还需要使用ldconfig命令刷新到ld.so.cache中。
示例:还是上面的例子
2.1)连接:
将动态库拷贝到系统默认的库路径中,即可编译链接通过。或者在/etc/ld.so.conf中加上一行/home/roo/kevinliu/test6/so
2.2)运行:
解决方案:执行ldconfig,之后即可运行成功。
3、gcc/g++参数:
通上面的例子看一下-L、-l、-I(指定头文件的)参数。
1)编译、连接:
$ g++ -o run main.cpp -L./ -lmytest
说明:通过-L参数指定库文件的地址;-l指定动态库的名字;
2)运行:
3)解决:
通过LD_LIBRARY_PATH环境变量,或者在文件/etc/ld.so.conf中指定库文件路径(或者将库文件放到默认/lib路径),然后ldconfig刷新ld.so.cache。
默认库文件路径、头文件路径
1、查看默认库文件路径:
- gcc --print-search-dir
- g++ --print-search-dir
2、查看默认头文件(include)路径:
- `gcc -print-prog-name=cc1plus` -v
- `g++ -print-prog-name=cc1plus` -v