我只是做了使用ld的一个基本的例子-rpath选项与$ORIGIN 这里(见一个工作版本第二反应).我试图创造一个例子main.run链接foo.so,进而链接bar.so,全部采用rpath和$ORIGIN.
运行时文件结构是:
- 项目/
- LIB /
- DIR /
- 子/
- bar.so
- foo.so
- 跑/
- main.run(无法构建)
我正在建设foo.so使用:
g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/dir/foo.so obj/foo.o -Wl,-soname,foo.so -Wl,-rpath,'$ORIGIN/sub' -Llib/dir/sub -l:bar.so
Run Code Online (Sandbox Code Playgroud)
哪个建好了.ldd lib/dir/foo.so甚至可以找到bar.so.
但是,当我尝试链接main.run到时foo.so,foo.so找不到bar.so.
我正在构建main.so使用:
g++ -c -o obj/main.o src/main.cpp
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib/dir' -Llib/dir -l:foo.so
Run Code Online (Sandbox Code Playgroud)
如果foo.so使用不递归链接的另一个版本,这可以正常工作.(取消注释make.sh中的行,在下面的项目中进行测试).
但是,使用正常foo.so我在构建时遇到此错误main.run:
/ usr/bin/ld:警告:bar.so,lib/dir/foo.so需要,找不到(尝试使用-rpath或-rpath-link) …
注意:现在完整的工作示例如下.原始问题如下:
我在使用ld的-rpath参数时遇到问题$ORIGIN.
由于我找不到一个完整的例子,我以为我会尝试自己写一个,以便我和其他人可以在以后使用它.一旦我开始工作,我会整理它.
示例项目构建一个共享库和一个链接到所述库的可执行文件.
它非常小(3个文件,22行包含buildscript).
您可以从这里下载项目
文件结构(构建前):
project/
src/
foo.cppmain.cppmake.shproject/src/foo.cpp
int foo()
{ return 3; }
Run Code Online (Sandbox Code Playgroud)
project/src/main.cpp
int foo();
#include <iostream>
int main()
{
std::cout << foo() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
project/make.sh
# Make directories:
mkdir -p -v obj
mkdir -p -v lib
mkdir -p -v run
# Build the library:
g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/foo.sh obj/foo.o
# Build the executable: …Run Code Online (Sandbox Code Playgroud) 虽然在库中组合多个目标文件是很常见的,但是(至少在Linux中)可以将多个目标文件组合到另一个目标文件中.
(请参阅将两个GCC编译的.o对象文件合并到第三个.o文件中)
由于使用库而不仅仅是组合对象文件存在缺点:
1:链接时只使用一种类型的文件(对象)更容易,特别是如果所有文件都做同样的事情.
2:链接时(至少在GCC中),库(默认情况下)需要排序,不能处理循环依赖.
我想知道图书馆有什么优势(除了捕获22他们使用了很多).
在搜索了一段时间之后,我得到的唯一解释似乎是单个库比多个目标文件更好.