我在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
从应用程序包加载s 所必需的.
denis.. 51
Mac OS X上的动态链接,一个很小的例子
脚步:
创建一个包含mymod.o的库libmylib.dylib
编译并链接一个调用它的"callmymod"
使用DYLD_LIBRARY_PATH和DYLD_PRINT_LIBRARIES从callmymod调用mymod
问题:您"只是"想要为其他模块创建一个库来使用.然而,有一堆令人生畏的程序 - 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: #includevoid 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
,它是mac上的glibtool和SCons.)
欢呼
- denis
Mac OS X上的动态链接,一个很小的例子
脚步:
创建一个包含mymod.o的库libmylib.dylib
编译并链接一个调用它的"callmymod"
使用DYLD_LIBRARY_PATH和DYLD_PRINT_LIBRARIES从callmymod调用mymod
问题:您"只是"想要为其他模块创建一个库来使用.然而,有一堆令人生畏的程序 - 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: #includevoid 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
,它是mac上的glibtool和SCons.)
欢呼
- denis
您可能需要确保构建的动态库具有导出的符号文件,该文件列出了应从库中导出的内容.它只是一个符号的平面列表,每行一个,用于导出.
此外,构建动态库时,它会在其中嵌入一个安装名称,默认情况下,它是构建它的路径.随后任何反对的链接将寻找它在指定的路径第一个也是唯一搜索之后的下描述默认路径(小)组DYLD_FALLBACK_LIBRARY_PATH
的dyld(1)
男子页.
如果您要将此库放在可执行文件旁边,则应调整其安装名称以引用它.只是在谷歌搜索"安装名称"时,应该提供大量关于这样做的信息.
不幸的是,根据我的经验,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
希望这可以帮助.
您是否了解Apple参考页面动态库编程主题?它应该涵盖你需要的大部分内容.请注意,在程序启动时无条件加载的共享库和按需加载的动态加载库(bundle,IIRC),两者在MacOS X上与Linux或Solaris上的等价物略有不同.