我在Xcode中构建了一些命令行实用程序(普通C,没有Cocoa)。我希望他们所有人都使用我自定义的libpng版本,我想通过在所有可执行文件中共享一个库副本来节省空间(我不介意用它们重新分发.dylib
)。
我是否需要做一些魔术才能获得libpng导出符号?
“Link Binary with Libraries”是否静态构建阶段链接?
Apple的文档提到在运行时使用dlopen
加载库,但是如何让Xcode创建可执行文件而不抱怨缺少符号?
我想我已经明白了:
libpng没有正确链接,因为我已经构建了32/64位可执行文件和32位库。库和可执行文件的构建设置必须匹配。
libpng的config.h需要有大量的定义,如#define FEATURE_XXX_SUPPORTED
“Link Binary with Libraries”构建阶段处理动态库就好了,DYLD_FALLBACK_LIBRARY_PATH
环境变量是从应用程序包加载.dylib
所必需的。 / p>
答案 0 :(得分:50)
Mac OS X上的动态链接,一个很小的例子
步骤:
问题:您“只是”想要为其他模块创建一个库来使用。 然而,有一堆令人生畏的程序 - gcc,ld,macosx libtool,dyld - 有数以万计的选项,一些腐烂的堆肥,以及MacOSX和Linux之间的差异。 有大量的手册页(我在10.4.11 ppc中计算7679 + 1358 + 228 + 226行) 但是没有太多的例子,或者有“告诉我你在做什么”模式的程序。
(理解中最重要的是简化 自己概述:画一些图片,运行一些小例子, 向其他人解释。)
背景:apple OverviewOfDynamicLibraries, Wikipedia Dynamic_library
第1步,创建libmylib.dylib -
mymod.c:
#include <stdio.h>
void mymod( int x )
{
printf( "mymod: %d\n", x );
}
gcc -c mymod.c # -> mymod.o
gcc -dynamiclib -current_version 1.0 mymod.o -o libmylib.dylib
# calls libtool with many options -- see man libtool
# -compatibility_version is used by dyld, see also cmpdylib
file libmylib.dylib # Mach-O dynamically linked shared library ppc
otool -L libmylib.dylib # versions, refs /usr/lib/libgcc_s.1.dylib
第2步,编译并链接callmymod -
callmymod.c:
extern void mymod( int x );
int main( int argc, char** argv )
{
mymod( 42 );
}
gcc -c callmymod.c
gcc -v callmymod.o ./libmylib.dylib -o callmymod
# == gcc callmymod.o -dynamic -L. -lmylib
otool -L callmymod # refs libmylib.dylib
nm -gpv callmymod # U undef _mymod: just a reference, not mymod itself
步骤3,运行callmymod链接到libmylib.dylib -
export DYLD_PRINT_LIBRARIES=1 # see what dyld does, for ALL programs
./callmymod
dyld: loaded: libmylib.dylib ...
mymod: 42
mv libmylib.dylib /tmp
export DYLD_LIBRARY_PATH=/tmp # dir:dir:...
./callmymod
dyld: loaded: /tmp/libmylib.dylib ...
mymod: 42
unset DYLD_PRINT_LIBRARIES
unset DYLD_LIBRARY_PATH
这结束了一个小例子;希望它有助于理解这些步骤
(如果你这么做,请参阅GNU Libtool
这是macs上的glibtool,
和SCons。)
欢呼声
- 丹尼斯
答案 1 :(得分:7)
您可能需要确保构建的动态库具有导出的符号文件,该文件列出了应从库中导出的内容。它只是一个符号的平面列表,每行一个,可以导出。
此外,构建动态库时,它会在其中嵌入安装名称,默认情况下,它是构建它的路径。随后,链接到它的任何内容都将首先在指定的路径中查找它,然后才搜索dyld(1)
man page中DYLD_FALLBACK_LIBRARY_PATH
下描述的一小组默认路径。
如果您要将此库放在可执行文件旁边,则应调整其安装名称以引用它。只是在谷歌搜索“安装名称”时,应该提供大量关于这样做的信息。
答案 2 :(得分:6)
不幸的是,根据我的经验,Apple的文档过时,冗余,缺少您通常需要的大量常用信息。
我在我的网站上写了一些东西,我必须得到FMOD(Sound API)才能使用我们在uni开发的跨平台游戏。这是一个奇怪的过程,我很惊讶Apple没有在他们的开发人员文档中添加更多信息。
不幸的是,作为微软的“邪恶”,他们实际上更好地用文档来管理他们的开发人员(这来自Apple传教士)。
我认为基本上,你没有做的是你编译.app Bundle之后。然后,您需要在可执行二进制文件/MyApp.app/contents/MacOS/MyApp上运行命令,以便更改可执行文件查找其库文件的位置。您必须创建可以运行脚本的新构建阶段。我不会再解释这个过程,我已经在这里深入探讨了这个过程:
http://brockwoolf.com/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod
希望这有帮助。
答案 3 :(得分:5)
您是否了解Apple参考页面Dynamic Library Programming Topics?它应该涵盖你需要的大部分内容。请注意,在程序启动时无条件加载的共享库和按需加载的动态加载库(bundle,IIRC),两者在MacOS X上与Linux或Solaris上的等价物略有不同。