我正在 Xcode 中构建一些命令行实用程序(纯 C,无 Cocoa)。 我希望他们所有人都使用我的自定义版本的 libpng,并且我想通过在所有可执行文件之间共享该库的一份副本来节省空间(我不介意与他们重新分发 .dylib
) 。
我需要施展一些魔法才能获得 libpng 导出符号吗?
“将二进制文件与库链接”是否静态构建阶段链接?
Apple 的文档提到在运行时使用 dlopen 加载库,但是如何让 Xcode 创建可执行文件而不抱怨缺少符号呢?
我想我已经弄清楚了:
I'm building few command-line utilities in Xcode (plain C, no Cocoa). I want all of them to use my customized version of libpng, and I want to save space by sharing one copy of the library among all executables (I don't mind re-distributing .dylib
with them).
Do I need to do some magic to get libpng export symbols?
Does "Link Binary With Libraries" build phase link statically?
Apple's docs mention loading of libraries at run time with dlopen
, but how I can make Xcode create executable without complaining about missing symbols?
I think I've figured it out:
-
libpng wasn't linking properly, because I've built 32/64-bit executables and 32-bit library. Build settings of the library and executables must match.
-
libpng's config.h needs to have tons of defines like #define FEATURE_XXX_SUPPORTED
-
"Link Binary With Libraries" build phase handles dynamic libraries just fine, and DYLD_FALLBACK_LIBRARY_PATH
environmental variable is neccessary for loading .dylib
s from application bundle.
发布评论
评论(4)
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 --
步骤2,编译并链接callmymod --
第 3 步,运行链接到 libmylib.dylib 的 callmymod ——
一个小例子就这样结束了; 希望它有助于理解这些步骤。
(如果您经常这样做,请参阅 GNU Libtool
这是 Mac 上的 glibtool,
和SCons。)
Dynamic linking on Mac OS X, a tiny example
Steps:
Problem: you "just" want to create a library for other modules to use.
However there's a daunting pile of programs -- gcc, ld, macosx libtool, dyld --
with zillions of options, some well-rotted compost, and differences between MacOSX and Linux.
There are tons of man pages (I count 7679 + 1358 + 228 + 226 lines in 10.4.11 ppc)
but not much in the way of examples, or programs with a "tell me what you're doing" mode.
(The most important thing in understanding is to make a simplified
OVERVIEW for yourself: draw some pictures, run some small examples,
explain it to someone else).
Background: apple OverviewOfDynamicLibraries,
Wikipedia Dynamic_library
Step 1, create libmylib.dylib --
Step 2, compile and link callmymod --
Step 3, run callmymod linking to libmylib.dylib --
That ends one tiny example; hope it helps understand the steps.
(If you do this a lot, see GNU Libtool
which is glibtool on macs,
and SCons.)
您可能需要确保您构建的动态库具有导出的符号文件,其中列出了应从库中导出的内容。 它只是要导出的符号的平面列表,每行一个。
此外,当构建动态库时,它会嵌入一个安装名称,默认情况下,它是构建它的路径。 随后,任何链接到它的东西都会首先在指定的路径中查找它,然后才搜索 DYLD_FALLBACK_LIBRARY_PATH 下描述的一组(小)默认路径。 apple.com/documentation/Darwin/Reference/ManPages/man1/dyld.1.html" rel="noreferrer" title="dyld(1) 手册页">
dyld(1)
手册页< /a>.如果您打算将此库放在可执行文件旁边,则应该调整其安装名称以引用它。 只要在谷歌上搜索“安装名称”就可以找到大量有关执行此操作的信息。
You probably need to ensure that the dynamic library you build has an exported symbols file that lists what should be exported from the library. It's just a flat list of the symbols, one per line, to export.
Also, when your dynamic library is built, it gets an install name embedded within it which is, by default, the path at which it is built. Subsequently anything that links against it will look for it at the specified path first and only afterwards search a (small) set of default paths described under
DYLD_FALLBACK_LIBRARY_PATH
in thedyld(1)
man page.If you're going to put this library next to your executables, you should adjust its install name to reference that. Just doing a Google search for "install name" should turn up a ton of information on doing that.
不幸的是,根据我的经验,苹果的文档已经过时、冗余,并且缺少很多您通常需要的常见信息。
我在我的网站上写了很多关于此的内容,其中我必须获得 FMOD(声音 API)才能与我们在大学开发的跨平台游戏一起使用。 这是一个奇怪的过程,我很惊讶苹果没有在他们的开发人员文档中添加更多信息。
不幸的是,尽管微软很“邪恶”,但他们实际上在用文档来照顾开发人员方面做得更好(这是来自苹果的布道者)。
我认为基本上,您没有做的是在编译了 .app 捆绑包之后。 然后,您需要在可执行二进制文件 /MyApp.app/contents/MacOS/MyApp 上运行命令,以便更改可执行文件查找其库文件的位置。 您必须创建一个可以运行脚本的新构建阶段。 我不会再解释这个过程,我已经在这里深入完成了:
http://brockwoolf.com/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod
希望这有帮助。
Unfortunately, in my experience Apple's documentation is antiquated, redundant and missing a LOT of common information that you would normally need.
I wrote a bunch of stuff on this on my website where I had to get FMOD (Sound API) to work with my cross platform game that we developed at uni. Its a weird process and I'm surprised that Apple do not add more info on their developer docs.
Unfortunately, as "evil" as Microsoft are, they actually do a much better job of looking after their devs with documentation ( this is coming from an Apple evangelist ).
I think basically, what you are not doing is AFTER you have compiled your .app Bundle. You then need to run a command on the executable binary /MyApp.app/contents/MacOS/MyApp in order to change where the executable looks for its library file. You must create a new build phase that can run a script. I won't explain this process again, I have already done it in depth here:
http://brockwoolf.com/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod
Hope this helps.
您是否知道 Apple 参考页 动态库编程主题? 它应该涵盖您需要的大部分内容。 请注意,共享库在程序启动时无条件加载,而动态加载库(捆绑包、IIRC)则按需加载,两者在 MacOS X 上与 Linux 或 Solaris 上的等效库有些不同。
Are you aware of the Apple reference page Dynamic Library Programming Topics? It should cover most of what you need. Be aware that there a shared libraries that get loaded unconditionally at program startup and dynamically loaded libraries (bundles, IIRC) that are loaded on demand, and the two are somewhat different on MacOS X from the equivalents on Linux or Solaris.