gcc 中的-L、-rpath和 -rpath-link的区别

本文将通过实验的方法找到三种方式的区别。

-L

1.1 deps.cc

#include <stdio.h>

void deps() {
	printf("deps.\n");
}

parent.cc

#include <stdio.h>

void deps();

void parent() {
 printf("parent.\n");
 deps();
}

test.cc

#include <stdio.h>
void parent();

int main(void) {
  parent();
  return 0;
}

a.首先编译汇编代码,得到deps.o 和 parent.o

 gcc -c deps.cc parent.cc

查看编译得到的object file

nm -C parent.o

输出

  U _GLOBAL_OFFSET_TABLE_
                 U deps()
0000000000000000 T parent()
                 U puts

b. 其次生成共享库

gcc -shared -o libparent.so parent.o
gcc -shared -o libdeps.so deps.o

为了达到使libparent.so依赖于libdeps.so的目的,在生成libparent.so时要链接到libdeps.so:

gcc -shared -o libmain.so  parent.o  -ldeps -L .

ldd libmain.so
输出:

linux-vdso.so.1 (0x00007ffd4855c000)
	libdeps.so (0x00007fa99459f000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa9941ae000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fa9949a3000)

此时libmain.so已经依赖于libdeps.so。

  1. 编译test.cc
    由于test.c直接依赖于libmain.so,因此使用-lmain -L
gcc test.cc -lmain -L.

或者

gcc test.cc -lparent -ldeps -L.

得到可执行程序 a.out
ldd a.out

linux-vdso.so.1 (0x00007ffeb632a000)
	libmain.so (0x00007f0d9c701000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0d9c310000)
	libdeps.so (0x00007f0d9c10e000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f0d9cb05000)

由上可见,libmain.so,并且libdeps.so也出现在a.out的依赖中!

-rpath 或者 -rpath-link

1.移动libmain.so 和 libdeps.so 到当前目录的子目录./lib
如果执行gcc test.cc -lmain -L./lib,则会报错:

/usr/bin/ld: warning: libdeps.so, needed by ./lib/libmain.so, not found (try using -rpath or -rpath-link)
./lib/libmain.so: undefined reference to `deps()'
collect2: error: ld returned 1 exit status

可以看出 libmain.so 找不到 libdeps.so,所以需要通过 -rpath 执行 libdeps.so 的路径。

gcc test.cc -lmain -L ./lib -Wl,-rpath=./lib

编译成功!
执行:

export LD_LIBRARY_PATH=./lib
./a.out

-rpath和-rpath-link都可以在链接时指定库的路径;但是运行可执行文件时,-rpath-link指定的路径就不再有效(链接器没有将库的路径包含进可执行文件中),而-rpath指定的路径还有效(因为链接器已经将库的路径包含在可执行文件中了。)

-rpath=dir

Add a directory to the runtime library search path.  This is used when linking an ELF executable with shared objects.  
All -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at  
runtime.  The -rpath option is also used when locating shared objects which are needed by shared objects explicitly  
included in the link; see the description of the -rpath-link option.  If -rpath is not used when linking an ELF  
executable, the contents of the environment variable "LD_RUN_PATH" will be used if it is defined.  
  
The -rpath option may also be used on SunOS.  By default, on SunOS, the linker will form a runtime search path out of  
all the -L options it is given.  If a -rpath option is used, the runtime search path will be formed exclusively using  
the -rpath options, ignoring the -L options.  This can be useful when using gcc, which adds many -L options which may  
be on NFS mounted file systems.  
  
For compatibility with other ELF linkers, if the -R option is followed by a directory name, rather than a file name, it  
is treated as the -rpath option.  

-rpath-link=dir

When using ELF or SunOS, one shared library may require another.  This happens when an "ld -shared" link includes a  
shared library as one of the input files.  
  
When the linker encounters such a dependency when doing a non-shared, non-relocatable link, it will automatically try  
to locate the required shared library and include it in the link, if it is not included explicitly.  In such a case,  
the -rpath-link option specifies the first set of directories to search.  The -rpath-link option may specify a sequence  
of directory names either by specifying a list of names separated by colons, or by appearing multiple times.  
  
This option should be used with caution as it overrides the search path that may have been hard compiled into a shared  
library. In such a case it is possible to use unintentionally a different search path than the runtime linker would do.  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝鲸123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值