Mac:如何从可执行文件中导出符号?

时间:2010-10-17 16:31:53

标签: macos linker shared ld

我正在编写一个可执行文件,它使用dlopen()(Windows上的LoadLibrary())来动态加载共享库。共享库使用可执行文件中的符号。

在Windows中这是可能的。可执行文件可以导出符号:declspec(dllexport)和.def文件都可以。链接器在创建.exe时也会创建.lib文件(“导入库”),因此DLL只需要链接该.lib。

在Linux中,这也是可能的。我在构建可执行文件时传递了-Wl,-export_dynamic,因此它会导出它的符号。

在Mac OS X上,而不是...... -Wl,-export_dynamic不起作用,但有-Wl,-exported_symbols_list,<filename>其中<filename>是要导出的符号列表(a一种更简单的.def文件版本)。但是,构建共享库并不容易:链接器抱怨未解析的符号。

我尝试了一个hack:将可执行文件重命名为lib <executable>。dylib,并且在链接共享库时,我传递了-l <executable>。但它给出了错误“无法与主要可执行文件链接”。

一般问题是Linux共享库可能有未解析的符号,而Windows和Mac OS X不允许。但Windows有“导入库”来解析符号依赖的符号,Mac OS X显然不会......

如何在Mac OS X上解决这个问题?是否有相当于“导入库”(在创建.dll时由Windows链接器创建的存根库,因此,如果任何模块需要动态链接到.dll,它是否与“导入库”链接)?还是其他一些解决方案?

2 个答案:

答案 0 :(得分:5)

独立的Lua解释器支持动态加载(通过dlopen)使用可执行文件中的符号(Lua API)的共享库。构建它时不使用特殊的链接标志。共享库是使用这个咒语构建的:

env MACOSX_DEPLOYMENT_TARGET=10.3 gcc -bundle -undefined dynamic_lookup -o random.so lrandom.o

答案 1 :(得分:4)

谢谢你,你的回答刺激了调查捆绑和dylibs之间差异的愿望。 ld的手册页提到了一个名为-bundle_loader

的选项
  

-bundle_loader可执行文件
                   这指定将加载包的可执行文件                    输出文件被链接。捆绑包中未定义的符号                    检查指定的可执行文件,就像它是一个                    与之链接的动态库。

(注意-bundle_loader在构建dylib时失败,它只适用于bundle) 所以旧的命令行

cc -shared -o <output>.so <input>.c

变成了

cc -bundle -bundle_loader <executable> -o <output>.so <input>.c

并且输出包针对可执行文件解析了未定义的符号。