当前位置:  开发笔记 > IOS > 正文

如何使用Xcode创建动态库(dylib)?

如何解决《如何使用Xcode创建动态库(dylib)?》经验,为你挑选了4个好方法。

我在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:
    #include 
    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 ,它是mac上的glibtool和SCons.)
欢呼
- denis



1> 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:
    #include 
    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 ,它是mac上的glibtool和SCons.)
欢呼
- denis



2> Chris Hanson..:

您可能需要确保构建的动态库具有导出的符号文件,该文件列出了应从库中导出的内容.它只是一个符号的平面列表,每行一个,用于导出.

此外,构建动态库时,它会在其中嵌入一个安装名称,默认情况下,它是构建它的路径.随后任何反对的链接将寻找它在指定的路径第一个也是唯一搜索之后的下描述默认路径(小)组DYLD_FALLBACK_LIBRARY_PATHdyld(1)男子页.

如果您要将此库放在可执行文件旁边,则应调整其安装名称以引用它.只是在谷歌搜索"安装名称"时,应该提供大量关于这样做的信息.



3> Brock Woolf..:

不幸的是,根据我的经验,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

希望这可以帮助.


@wintermute:一个不必要的评论.我相信这个网站上的每个用户之前都听过一百万次.

4> Jonathan Lef..:

您是否了解Apple参考页面动态库编程主题?它应该涵盖你需要的大部分内容.请注意,在程序启动时无条件加载的共享库和按需加载的动态加载库(bundle,IIRC),两者在MacOS X上与Linux或Solaris上的等价物略有不同.

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有