fooofei / cpp.notes

1 stars 0 forks source link

na #33

Closed fooofei closed 5 years ago

fooofei commented 6 years ago

ld.so.cache

有时候疑惑,写的项目里没有写过那个 path,但是ldd -r <elf> 能看到引用那个 path 下的一个 .so 文件。

后来找到原因,是因为在/etc/ld.so.conf.d目录下,存在一个 xxx.conf文件记录了这个 path。所以会从这个 path 下寻找 .so文件。

验证:

当我删除 /etc/ld.so.conf.d 下的那个 xxx.conf 文件后,运行 ldconfig ( 修改完 /etc/ld.so.conf.d,要运行这个命令,是为了更新缓存文件 /etc/ld.so.cache,而 /etc/ld.so.cache 才是 ELF 文件使用的。 ), 再次运行 ldd -r <ELF> 验证不再去那个 path 目录下寻找 .so 文件了。

ELF 会依据这个目录中文件的指引去加载 .so ,这些步骤都是手动的,与 ELF文件所在的项目无关,不是修改项目 makefile 做到的。

ld 这个命令就是去 /etc/ld.so.conf.d 目录找的。

fooofei commented 6 years ago
$ ldconfig -p
344 libs found in cache `/etc/ld.so.cache'
fooofei commented 6 years ago

rpath in makefile

makefile 中写了 -L 能解决项目编译生成过程中的 undefined reference 或者 undefined symbol ,

但是拿着我们的二进制到其他机器运行的时候,就可能找不到某个 .so,这时候可以在 makefile 中使用

-Wl,rpath=<your_lib_dir> 指定一个存放运行使用到的众多 .so 目录,在运行的时候,会去这个目录找。

使用 readelf -d <ELF> 能看到这个目录。

fooofei commented 6 years ago

-l in makefile

比如我们的项目里用到了 curl, 我们 yum -y install libcurl-devel 肯定是没问题的,include 文件和 /usr/lib64/libcurl.so 都会有。

但是我不想做这一步。

我发现我的机器上本来就有

$ ll /usr/lib64/libcurl.so*
lrwxrwxrwx. 1 root root   16 3月  12 14:11 /usr/lib64/libcurl.so.4 -> libcurl.so.4.3.0
-rwxr-xr-x. 1 root root 425K 2月   2 12:49 /usr/lib64/libcurl.so.4.3.0

只是缺少 ln -s /usr/lib64/libcurl.so.4.3.0 /usr/lib64/libcurl.so

这一步显然我们是不能多做的,不然拿到我们代码的人,都要这么操作一遍。 如何从我们的项目入手呢?

这里说在 makefile 里写 -l:<full name> https://stackoverflow.com/questions/828053/how-do-you-link-to-a-specific-version-of-a-shared-library-in-gcc 我试了下,还真行。

这里没有解释 https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Link-Options.html

这里有解释 https://sourceware.org/binutils/docs-2.18/ld/Options.html

-lnamespec
--library=namespec

节,If namespec is of the form :filename, ld will search the library path for a file called filename, otherise it will search the library path for a file called libnamespec.a.

遇到的问题: 编译链接通过, 但是 ldd -r 有的能自动找到 /usr/lib64 /usr/local/lib 目录的文件,挺好,有的找不到,还把自己的全路径写进去了.

$ readelf -d <>
Dynamic section at offset 0x27bd08 contains 38 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libanl.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libnsl.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libcurl.so.4]
 0x0000000000000001 (NEEDED)             Shared library: [libmysqlclient.so.18]
 0x0000000000000001 (NEEDED)             Shared library: [/docker_host/xxx/src/lib/cjson/libcjson.so.1.5.5]
 0x0000000000000001 (NEEDED)             Shared library: [/docker_host/xxx/src/lib/cjson/libcjson_utils.so.1.5.5]
 0x0000000000000001 (NEEDED)             Shared library: [libz.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libzmq.so.5]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/usr/lib64/mysql:/data/lib:/usr/local/lib]