Linux操作系统上面的动态共享库大致分为三类:
1、操作系统级别的共享库和基础的系统工具库
比方说libc.so, libz.so, libpthread.so等等,这些系统库会被放在/lib和/usr/lib目录下面,如果是64位操作系统,还会有/lib64和/usr /lib64目录。如果操作系统带有图形界面,那么还会有/usr/X11R6/lib目录,如果是64位操作系统,还有/usr/X11R6 /lib64目录。此外还可能有其他特定Linux版本的系统库目录。这些系统库文件的完整和版本的正确,确保了Linux上面各种程序能够正常的运行。
系统默认的/lib /usr/lib 或是64位系统的/lib64 /usr/lib64
2、应用程序级别的系统共享库
并非操作系统自带,但是可能被很多应用程序所共享的库,一般会被放在/usr/local/lib和/usr/local/lib64这两个目录下面。很多你自行编译安装的程序都会在编译的时候自动把/usr/local/lib加入gcc的-L参数,而在运行的时候自动到/usr/local/lib下面去寻
找共享库。
以上两类的动态共享库,应用程序会自动寻找到他们,并不需要你额外的设置和担心。这是为什么呢?因为以上这些目录默认就被加入到动态链接程序的搜索路径里面了。Linux的系统共享库搜索路径定义在/etc/ld.so.conf这个配置文件里面。这个文件的内容格式
大致如下:
1. /usr/X11R6/lib64
2. /usr/X11R6/lib
3. /usr/local/lib
4. /lib64
5. /lib
6. /usr/lib64
7. /usr/lib
8. /usr/local/lib64
9. /usr/local/ImageMagick/lib
假设我们自己编译安装的ImageMagick图形库在/usr/local/ImageMagick目录下面,并且希望其他应用程序都可以使用ImageMagick的动态共享库,那么我们只需要把/usr/local/ImageMagick/lib目录加入/etc /ld.so.conf文件里面,然后执行:ldconfig 命令即可。
ldcofig将搜索以上所有的目录,为共享库建立一个缓存文件/etc/ld.so.cache。为了确认ldconfig已经搜索到ImageMagick的库,我们可以用上面介绍的strings命令从ld.so.cache里面抽取文本信息来检查一下:
1. strings /etc/ld.so.cache | grep ImageMagick
输出结果为:
1. /usr/local/ImageMagick/lib/libWand.so.10
2. /usr/local/ImageMagick/lib/libWand.so
3. /usr/local/ImageMagick/lib/libMagick.so.10
4. /usr/local/ImageMagick/lib/libMagick.so
5. /usr/local/ImageMagick/lib/libMagick++.so.10
6. /usr/local/ImageMagick/lib/libMagick++.so
已经成功了!
3、应用程序独享的动态共享库
有很多共享库只被特定的应用程序使用,那么就没有必要加入系统库路径,以免应用程序的共享库之间发生版本冲突。因此Linux还可以通过设置环境变量 LD_LIBRARY_PATH来临时指定应用程序的共享库搜索路径,就像我们上面举的那个例子一样,我们可以在应用程序的启动脚本里面预先设置 LD_LIBRARY_PATH,指定本应用程序附加的共享库搜索路径,从而让应用程序找到它。
编译的时候动态库的搜索路径:
1、gcc会去找-L
2、环境变量LIBRARY_PATH
3、 /lib /usr/lib /usr/local/lib 这俩是当初compile gcc时写在程序内的
运行时动态库的搜索路径搜索的先后顺序是:
1.编译目标代码时指定的动态库搜索路径; 通过gcc 的参数"-Wl,-rpath,"指定。当指定多个动态库搜索路径时,路径之间用冒号":"分隔)
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib。
环境变量PATH,保存了一系列目录,它在系统中的主要作用是,提供命令的搜索路径
第一种方法:
在用户主目录下有一个 .bashrc 文件,可以在此文件中加入 PATH 的设置如下:
export PATH=”$PATH:/your path1/:/your path2/…..”
注意:每一个 path 之间要用 “:“ 分隔。
第二种方法:
在 /etc/profile中增加。
PATH="$PATH:/home/zhengb66/bin"
export PATH
如果要使得计时生效,使用 source 命令 source .bashrc,修改当前shell环境变量
/sbin /usr/sbin目录下的命令为系统命令没有加入普通用户的PATH中所以,普通用户无法使用其中的命令。
Search Path
GCC looks in several different places for headers. On a normal Unix system, if you do not instruct it otherwise, it will look for headers requested with #include <file> in:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
For C programs, it will also look in /usr/include/gv3, first. In the above, target is the canonical name of the system GCC was configured to compile code for; often but not always the same as the canonical name of the system it runs on. version is the version of GCC in use.
You can add to this list with the -Idir command line option. All the directories named by -I are searched, in left-to-right order, before the default directories. The only exception is when dir is already searched by default. In this case, the option is ignored and the search order for system directories remains unchanged.
Duplicate directories are removed from the quote and bracket search chains before the two chains are merged to make the final search chain. Thus, it is possible for a directory to occur twice in the final search chain if it was specified in both the quote and bracket chains.
You can prevent GCC from searching any of the default directories with the -nostdinc option. This is useful when you are compiling an operating system kernel or some other program that does not use the standard C library facilities, or the standard C library itself. -I options are not ignored as described above when -nostdinc is in effect.
GCC looks for headers requested with #include "file" first in the directory containing the current file, then in the directories as specified by -iquote options, then in the same places it would have looked for a header requested with angle brackets"<>的意思". For example, if /usr/include/sys/stat.h contains #include "types.h", GCC looks for types.h first in /usr/include/sys, then in its usual search path.
`#line' (see Line Control) does not change GCC's idea of the directory containing the current file.
You may put -I- at any point in your list of -I options. This has two effects. First, directories appearing before the -I- in the list are searched only for headers requested with quote marks(“”的意思). Directories after -I- are searched for all headers. Second, the directory containing the current file is not searched for anything, unless it happens to be one of the directories named by an -I switch. -I- is deprecated, -iquote should be used instead.
-I. -I- is not the same as no -I options at all, and does not cause the same behavior for `<>' includes that `""' includes get with no special options. -I. searches the compiler's current working directory for header files. That may or may not be the same as the directory containing the current file.
If you need to look for headers in a directory named -, write -I./-.,在打开动态库函数(dlopen或LoadLibrary)中指定动态库的文件名后,在程序运行时是以什么次序来搜索动态库呢?
Linux下搜索路径的次序:
1) ELF可执行文件中动态段中DT_RPATH所指定的路径,不常用但是比较使用的方法;
2) 编译目标代码时指定的动态库搜索路径(-WI,-rpath=./);
3) 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
4) 配置文件/etc/ld.so.conf(或ld.so.cache)中指定的动态库搜索路径;
5) 默认的动态库搜索路径/lib;
6) 默认的动态库搜索路径/usr/lib。
在上述1-3中指定的动态库搜索路径都可以指定多个搜索目录,其先后顺序是按指定路径的先后顺序搜索的。如果动态库之间存在依赖关系,那么先加载那些被依赖的动态库。
Windows下搜索路径次序
1) 可执行文件所在的目录(当前目录);
2) Windows的系统目录(该目录可以通过GetSystemDirectory函数获得);
3) 16位的系统目录(Windows目录下的system子目录);
4) Windows目录(该目录可以通过GetWindowsDirectory函数获得);
5) 进程当前所在的工作目录;
6) PATH环境变量中所列出的目录。
注:工作目录位于Windows目录之后,这一改变开始于Windows XP SP2之后。