动态库,头文件,命令搜索路径

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./-.

最近在做的项目中使用到动态库的动态加载技术,Windows和Linux都提供了相应的函数来打开动态库、获取函数指针和关闭动态库

,在打开动态库函数(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之后。

时间: 2024-07-30 23:54:12

动态库,头文件,命令搜索路径的相关文章

Gcc对头文件与库文件的搜索路径

一.简介 对头文件与库文件的搜索路径不太清楚,编译.运行时老碰到问题,ldd查看程序的链接时,总是出现unkown链接. 二.头文件 gcc 在编译时寻找所需要的头文件 : 1)搜寻会从-I开始 2)然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH (这些变量在windows下对应的是include环境变量) 3)再找内定目录 /usr/include /usr/local/include /usr/lib/gcc-l

Ubuntu linux设置从当前目录下加载动态库so文件

linux的excutable在执行的时候缺省是先搜索/lib和/usr/lib这两个目录,然后按照ld.so.conf里面的配置搜索绝对路径,linux缺省是不会在当前目录搜索动态库的.windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录. windows的动态库搜索顺序,虽然有可能会造成潜在的混乱,但是对于开发和测试无疑是比较方便的,尤其是debug和release版本的动态库需要经常切换进行测试的时候

Linux下c函数dlopen实现加载动态库so文件代码举例

dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了.可以在自己的程序中使用 dlopen().dlopen() 在 dlfcn.h 中定义,并在 dl 库中实现.它需要两个参数:一个文件名和一个标志.文件名就是一个动态库so文件,标志指明是否立刻计算库的依赖性.如果设置为 RTLD_NOW 的话,则立刻计算:如果设置的是 RTLD_LAZY,则在需要

Android NDK开发及调用标准linux动态库.so文件

源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动将so文件和java应用一起打包成apk.对应:jni层c++开发 2.Cygwin:是windows平台上模拟Linux运行环境的工具,即window平台上的linux环境工具,so文件需要在linux平台上编译运行.对应:arm linux平台 3.CDT:eclipse下的C/C++开发工具,

【linux】linux下动态库so文件的一些认识

来源:http://mypyg.iteye.com/blog/845915 so其实就是shared object的意思.今天看了上面的博客,感觉好吃力.赶紧做个笔记记录一下.下面的内容大多都是连接中的,穿插我自己的笔记 牵扯到ELF格式,gcc编译选项待补,简单实用的说明一下,对Linux下的so文件有个实际性的认识. 1.so文件是什么? 2.怎么生成以及使用一个so动态库文件? 3.地址空间,以及线程安全. 4.库的初始化,解析: 5.使用我们自己库里的函数替换系统函数: 1.so文件是什

C&amp;C++——库头文件及其作用

1. 一些头文件的作用::ANSI C.提供断言,assert(表达式):GCC.GTK,GNOME的基础库,提供很多有用的函数,如有数据结构操作函数.使用glib只需要包含:GCC.文件夹操作函数.struct dirent,struct DIR,opendir(),closedir(),readdir(),readdir64()等:ANSI C.字符测试函数.isdigit(),islower()等:ANSI C.查看错误代码errno是调试程序的一个重要方法.当linuc C api函数发

linux下动态库so文件的一些认识

转自:http://mypyg.iteye.com/blog/845915 个人创作,欢迎指错. 牵扯到ELF格式,gcc编译选项待补,简单实用的说明一下,对Linux下的so文件有个实际性的认识. 1.so文件是什么? 2.怎么生成以及使用一个so动态库文件? 3.地址空间,以及线程安全. 4.库的初始化,解析: 5.使用我们自己库里的函数替换系统函数: //--------------------------------------------------------------------

cocoapods导入三方库头文件找不到问题

问题描述:使用cocoapods时,import 找不到头文件. 问题原因: 1.缓存导致 2.没设置头文件的目录. 1.解决办法: command + k 清理工程 ,找到DerivedData文件夹,路径是~/Library/Developer/Xcode/DerivedData,删除.重新编译. 2.如果还是报找不到头文件,检查下头文件设置 一些标识符:${SRCROOT}   (这代表工程根目录).${PODS_ROOT}   (这代表pods文件夹).$(inherited) (这个是

/lib64/libc.so.6 升级动态库导致所有命令不能使用

问题:一次安装软件,更改/lib64/libc.so.6导致所有命令都不能使用 注意:不要重启机器 解决步骤: 找一台相同的机器,先找出libc.so.6所在位置及其软连接哪个文件,如下 [[email protected] ~]# find / -name "libc.so.6" /lib64/libc.so.6 [[email protected] ~]# ll /lib64/libc.so.6 lrwxrwxrwx 1 root root 12 Mar  9  2016 /lib