原来,自己在很多年前就总结了这块知识
今日,再一次进行更松散的总结。
linker在文件编译时,解决所有的外部符号;当执行时,loader(属于OS)将会重置所有的符号,并且放入合适的内存中。
linux 支持两类库: 静态库和动态库。根据程序编译阶段的不同,又可以分为动态链接库和动态加载库。
Shared library
共享库没啥特别的地方,也是一种ELF格式文件,和普通的C语言文件没有区别(编译之前),除了没有main()
函数入口。当然,要告诉gcc-fPIC
选项。
当然,也可以综合起来:
那么, 在其他文件中,调用这个函数的方法是:
我们的main函数在编译阶段会link这个lib。
但是,如果你执行试试:
link是没问题的,但是load是无法的。也就是说,尽管我们我们在link阶段指明了so的位置,但是load并不会得知。以上,基本上就是前面文件的内容。
So in order to make the loader find our library, we have to tell it where to look, either by adding the correct directory to the LD_LIBRARY_PATH environment variable, or by adding it to the ldconfig paths in either /etc/ld.so.conf inside the /etc/ld.so.conf.d/ directory. Let’s try it with the environment variable for now
动态加载共享库
如果只想在加载 load 时使用共享库的函数,还是有办法的。
这段代码需要借助libdl
动态库, 其实不好的一点就是得猜。
linux lib 管理
linux中有两种lib,一种是静态的,一种是动态的(Dynamic Shared Object–DSO),由操作系统借助
ld.so
或者ld-linux.so
在运行时动态load.
- ldconfig : Updates the necessary links for the run time link bindings.
- ldd : Tells what libraries a given program needs to run.
- ltrace : A library call tracer.
- ld.so/ld-linux.so: Dynamic linker/loader.
重要的文件
- /lib/ld-linux.so.* : Execution time linker/loader.
- /etc/ld.so.conf : File containing a list of colon, space, tab, newline, or comma separated directories in which to search for libraries.
-
/etc/ld.so.cache : File containing an ordered list of libraries found in the directories specified in /*etc/ld.so.conf. This file is not in human readable format, and is not intended to be edited. This file is created by ldconfig command.
- lib*.so.version : Shared libraries stores in /lib, /usr/lib, /usr/lib64, /lib64, /usr/local/lib directories.
ldconfig
在上面的 main 例子中, ldconfig
作用在libmylib.so 的目录中并不起作用,不知道为什么。
但是,可以使用下面的命令让共享库生效:
查看ldconfig的内容使用-v
选项。
ldd
ldd可以查看一个可执行文件所依赖的动态库
ld.so or ld-linux.so
The ld.so or / ld-linux.so used as follows by Linux:
- To load the shared libraries needed by a program.
- To prepare the program to run, and then runs it.
与ldd的作用一样
环境变量
The LD_LIBRARY_PATH can be used to set a library path for finding dynamic libraries using LD_LIBRARY_PATH, in the standard colon seperated format:
$ export LD_LIBRARY_PATH=/opt/simulator/lib:/usr/local/lib
The LD_PRELOAD allow an extra library not specified in the executable to be loaded:
$ export LD_PRELOAD=/home/vivek/dirhard/libdiehard.so
Please note that these variables are ignored when executing setuid/setgid programs.
补充
pkg-config
pkg-config的作用与ldconfig有些类似,但是pkg-config更侧重在编译、链接阶段;而ldconfig侧重链接、运行时阶段。