我正在尝试创建一个动态库,该库旨在在运行时链接并加载到主机环境中(例如,类似于 Java 中类加载的工作方式)。因此,我希望动态库保留一些“悬空”引用,我希望它在加载到宿主环境时从宿主环境中获取这些引用。
我的问题是,如果不将动态库显式链接到现有符号,我无法弄清楚如何创建动态库。我希望生成一个不依赖于特定主机可执行文件(或主机库)的动态库,而是一个能够在任何主机中加载(例如通过 dlopen
)的动态库,只要主机提供了几个可供使用的符号。
现在,我尝试过的任何链接命令都会导致缺少符号的投诉。我希望它允许缺少符号(理想情况下,只是特别指定的符号)。
例如,这是在 OS X 上出现错误的抄本:
$ cat frotz.c
void blort(void);
void run(void) {
blort();
}
$ cc -c -o frotz.o frotz.c
$ cc -dynamiclib -o libfrotz.dylib frotz.o
Undefined symbols for architecture x86_64:
"_blort", referenced from:
_run in frotz.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
如果我使用 GNU 工具链(在 Linux 上)做同样的事情,它会告诉我:
$ gcc -shared -o libfrotz.so frotz.o
/usr/bin/ld: frotz.o: relocation R_X86_64_PC32 against undefined symbol `blort'
can not be used when making a shared object; recompile with -fPIC
事实上,将 -fPIC
添加到 C 编译命令似乎可以解决该环境中的问题。但是,它在 OS X 中似乎没有任何效果。
我能在 SO 上找到的所有其他动态链接问题似乎都与库的更常见排列有关,在这种情况下,正在构建库以在可执行文件运行之前链接到可执行文件,而不是相反。我发现最接近的相关问题是:
不幸的是,其中的信息很少,与我在这里提出的问题无关。
更新:我从答案中提取了信息以及我想到的所有其他信息 出来,并把这个例子放在一起:
最佳答案
据我所知,您想使用弱链接:
// mark function as weakly-linked
extern void foo() __attribute__((weak));
// inform the linker about that too
clang -dynamiclib -o bar.dylib bar.o -flat_namespace -undefined dynamic_lookup
如果一个弱函数可以在运行时解决,那么它就会被解决。如果不能,它将是 NULL
,而不是生成运行时(或者,显然是链接时)错误。
关于创建一个在运行时链接的dylib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19941730/