linux程序在编译、链接、运行时涉及多个路径,我们经常分不清楚。下面对几个相关路径进行说明。
PATH环境变量
我们在编译程序时经常提到PATH这个环境变量,特别是交叉编译时。PATH环境变量指定的是可执行程序的查找路径。
PATH环境变量通常可以通过以下几种方法进行设置:(其他环境变量设置方法也类似)
1. 利用export命令设置
如设置PATH环境变量添加/home/test路径
export PATH=$PATH:/home/test
在添加时注意不要覆盖原有的PATH变量值。另外本方法设置当关闭了当前shell后即失效。
2. 修改~/.bashrc或者~/.bash_profile或者/etc/profile文件。具体操作如下:
- 在上述文件添加如下export命令添加路径
export PATH=$PATH:/home/test
- 执行source ~/.bashrc(~/.bash_profile、/etc/profile类似)命令使刚刚设置的环境变量立马生效
source命令通常用于重新执行刚修改的初始化文件,使之立马生效,而不用等到注销重新登录,其作用和点符号“.”相同。
LD_LIBRARY_PATH环境变量
LD_LIBRARY_PATH环境变量指定的是程序运行时动态库的查找路径。LD_LIBRARY_PATH环境变量的设置和上面的PATH环境变量类似,也有两种方法,在此不再赘述。
-L参数
-L参数用于指定程序链接时依赖的动态库查找路径。有一点我们需要注意,linux区分了程序的链接时路径(Link-time path)和运行时路径(Run-time path)。
-Wl,-rpath参数
-Wl,rpath命令主要包括以下两个作用:
- 在gcc编译可执行程序时利用-Wl,-rpath命令指定程序的运行时查找路径。该路径查找信息是保存到对应可执行文件中。正如上面所说,注意区分程序的链接时路径和运行时路径。
- 程序链接时,在指定的目录中,隐式地链接那些动态库所需要的其他动态链接库。比如我们需要编译的目标可执行程序test依赖libA.so,而libA.so又同时依赖了libB.so和libC.so。如果我们指定了-Wl,rpath参数,那么就只需要显式地给出对libA.so的依赖即可,-lA,而不需要很麻烦地写出-lA、-lB、-lC。
-Wl,-rpath-link参数
-Wl,-rpath-link参数主要用于指定程序链接时动态库的查找路径。另外,实际使用时其也有查找递归依赖动态库作用。
/etc/ld.so.conf配置
我们可以直接在/etc/ld.so.conf配置文件中添加动态库的运行搜索路径。步骤如下:
1. 修改/etc/ld.so.conf文件,添加对应的动态库运行时搜索路径。(若/etc/ld.so.conf文件里面包含了其他文件,则也可在包含的其他文件中添加)
include ld.so.conf.d/*.conf /home/test
2. 执行ldconfig命令使修改的配置生效。ldconfig命令主要是用于在当前系统设置下搜索出所有动态库运行可搜索路径并生成动态装入程序ld.so所需的连接和缓存文件。通常的缓存文件为/etc/ld.so.cache,该文件中包含了已排序的动态链接库列表。
动态库编译时头文件查找顺序
- 先搜索当前目录
- 搜索-I指定目录
- gcc的环境变量C_INCLUDE_PATH、CPLUS_INCLUDE_PATH、OBJC_INCLUDE_PATH
- 内定目录/usr/include、/usr/local/include
- gcc自带的一系列目录,如CPLUS_INCLUDE_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include
动态库链接时查找顺序
- -L
- LIBRARY_PATH
- 内定目录:
- /lib和lib64
- /usr/lib和/usr/lib64
- /usr/local/lib和/usr/local/lib64
动态库运行时查找顺序:
- -Wl,-rpath
- LD_LIBRARY_PATH
- /etc/ld.so.cache文件中缓存的文件位置,也即/etc/ld.so.conf文件中配置的路径
- 默认的搜索路径/lib、/usr/lib