Sun Studio 12:Fortran 编程指南

4.3 设置库搜索路径和顺序

链接程序按某一规定顺序在若干位置搜索库。这些位置中有一些是标准路径,有一些则取决于编译器选项 -Rpath-llibrary-Ldir 以及环境变量 LD_LIBRARY_PATH

4.3.1 标准库路径的搜索顺序

链接程序所用的标准库搜索路径由安装路径确定,对于静态和动态加载,它们会有所不同。标准安装将 Sun Studio 编译器软件置于 /opt/SUNWspro/ 下。

4.3.1.1 静态链接

生成可执行文件时,静态链接程序按指定顺序在以下路径(在其他路径中)中搜索 库:

/opt/SUNWspro/lib

Sun Studio 共享库 

/usr/ccs/lib/

SVr4 软件的标准位置 

/usr/lib

UNIX 软件的标准位置 

这些是链接程序所用的缺省路径。

4.3.1.2 动态链接

动态链接程序在运行时按指定顺序搜索共享库:

这些搜索路径被内置于可执行文件中。

4.3.2 LD_LIBRARY_PATH 环境变量

使用 LD_LIBRARY_PATH 环境变量指定链接程序应在哪些目录路径中搜索用 -llibrary 选项指定的库。

可以指定多个目录,其间用冒号分隔。通常,LD_LIBRARY_PATH 变量包含两个用冒号分隔的目录列表,列表间用分号隔开:

dirlist1;dirlist2

首先搜索 dirlist1 中的目录,接着是命令行上用任何显式 -Ldir 指定的目录,再接着是 dirlist2 以及标准目录。

也就是说,如果使用多个 -L 调用编译器,如下所示:

f95 ... -Lpath1 ... -Lpathn ...

则搜索顺序是:

dirlist1 path1 ... pathn dirlist2 standard_paths

LD_LIBRARY_PATH 变量只包含一个用冒号分隔的目录列表时,它会被解释为 dirlist2

在 Solaris 操作环境中,当搜索 64 位依赖性时,可以用相似的环境变量 LD_LIBRARY_PATH_64 来替代 LD_LIBRARY_PATH。有关详细信息,请参见 Solaris《链接程序和库指南》以及 ld(1) 手册页。

4.3.3 库搜索路径和顺序-静态链接

使用 -llibrary 编译器选项对链接程序在解析外部引用时要搜索的其他库命名。例如,用选项 -lmylib 将库 libmylib.solibmylib.a 添加到搜索列表中。

链接程序会在标准目录路径中查找其他的 libmylib 库。-L 选项(和 LD_LIBRARY_PATH 环境变量)会创建一个路径列表,告知链接程序到哪里查找位于标准路径以外的库。

假如 libmylib.a 位于 /home/proj/libs 目录中,则选项 –L/home/proj/libs 会告知链接程序在生成可执行文件时到哪里查找:


demo% f95 -o pgram part1.o part2.o -L/home/proj/libs -lmylib

4.3.3.1 -l library 选项的命令行顺序

对于任何未解析的特殊引用,只对库进行一次搜索,并且只搜索在搜索时未定义的符号。如果命令行上列出了多个库,则会按其在命令行上出现的顺序来搜索这些库。-llibrary 选项放置在以下位置:

4.3.3.2 -Ldir 选项的命令行顺序

-Ldir 选项会将 dir 目录路径添加到库搜索列表中。链接程序首先在 -L 选项指定的任何目录中搜索库,然后在标准目录中进行搜索。只有将其放在它所应用的 –llibrary 选项之前,该选项才有用。

4.3.4 库搜索路径和顺序-动态链接

对于动态库,库搜索路径和加载顺序的更改与静态情况不同。实际链接发生在运行时而不是生成时。

4.3.4.1 在生成时指定动态库

生成可执行文件时,链接程序会在可执行文件本身中记录共享库的路径。这些搜索路径可以用 -Rpath 选项指定。这一点与 -Ldir 选项相反,该选项在生成时指示到哪里查找 -llibrary 选项所指定的库,但不会将该路径记录到二进制可执行文件中。

使用 dump 命令可以查看创建可执行文件时内置的目录路径。

示例:列出内置于 a.out 之中的目录路径:


demo% f95 program.f -R/home/proj/libs -L/home/proj/libs -lmylib
demo% dump -Lv a.out | grep RPATH
[5]      RPATH    /home/proj/libs:/opt/SUNWspro/lib

4.3.4.2 在运行时指定动态库

运行时,链接程序会确定到哪里查找可执行文件所需的动态库:

如前所述,使用 LD_LIBRARY_PATH 会带来意想不到的副作用,因而不建议这样做。

4.3.4.3 修复动态链接期间的错误

当动态链接程序找不到所需库的位置时,它会发出以下错误消息:


ld.so: prog: fatal: libmylib.so: can’t open file:

此消息表明这些库不在其应在的位置。您也许在生成可执行文件时指定了共享库的路径,但这些库随后已被移动。例如,您可能先用 /my/libs/ 中您自己的动态库生成了a.out,而后来又将这些库移到了另一目录。

使用 ldd 确定可执行文件期望在哪儿找到这些库:


demo% ldd a.out
libfui.so.1 =>   /opt/SUNWspro/lib/libfui.so.1
    libfai.so.1 =>   /opt/SUNWspro/lib/libfai.so.1
    libfai2.so.1 =>  /opt/SUNWspro/lib/libfai2.so.1
    libfsumai.so.1 =>    /opt/SUNWspro/lib/libfsumai.so.1
    libfprodai.so.1 =>   /opt/SUNWspro/lib/libfprodai.so.1
    libfminlai.so.1 =>   /opt/SUNWspro/lib/libfminlai.so.1
    libfmaxlai.so.1 =>   /opt/SUNWspro/lib/libfmaxlai.so.1
    libfminvai.so.1 =>   /opt/SUNWspro/lib/libfminvai.so.1
    libfmaxvai.so.1 =>   /opt/SUNWspro/lib/libfmaxvai.so.1
    libfsu.so.1 =>   /opt/SUNWspro/lib/libfsu.so.1
    libsunmath.so.1 =>   /opt/SUNWspro/lib/libsunmath.so.1
    libm.so.1 =>     /usr/lib/libm.so.1
    libc.so.1 =>     /usr/lib/libc.so.1
    libdl.so.1 =>    /usr/lib/libdl.so.1
    /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1

如果可能的话,将这些库移动或复制到正确的目录中,或者在链接程序搜索的目录中建立到该目录的软链接(使用 ln -s)。或者,可能是没有正确设置 LD_LIBRARY_PATH。检查 LD_LIBRARY_PATH 是否包含运行时所需库的路径。