在OSX上分发二进制库

时间:2009-11-19 23:44:02

标签: c macos

我打算发布一些编译代码,这些代码将由MacOSX上的客户端应用程序链接。

分发是某种代码库和一组定义库的公共接口的头文件。代码是内部C ++,但它的公共接口(即标题中显示的内容)完全是C。

这些是我的要求或至少我希望能够完成的任务:

  • 我希望我的图书馆不可知 尽可能适用于什么版本的OSX 和用户正在运行的GCC。有 64位和32位的独立库 有点可以。
  • 我想要我的图书馆 可以从那些语言加载 支持加载C库,如 python或类似的。
  • 我想要我的 库内部符号 与它所存在的代码隔离开来 联系到。我不想要 重复符号错误,因为我们 碰巧命名内部函数 以同样的方式。我的C ++代码是正确的命名空间,所以这可能不是一个大问题,但我依赖的一些库是C,可能是一个问题(见下一点)。
  • 我想要我的图书馆 依赖是安全的。我的图书馆 取决于一些库,如 libpng,boost和stl,我没有 想要问题,因为有些用户没有 必须安装所有这些 或因为他们有问题而得到问题 用其他标志编译或 有不同的版本。

在Windows上,我使用带有导出库的DLL,并将所有依赖项静态链接到dll中。它符合上述所有标准,如果我能在OSX上获得相同的结果,那就太棒了,但我听说动态库往往不会以相同的方式隔离mac上的符号。

在OSX上有这种最佳实践吗?

2 个答案:

答案 0 :(得分:2)

正常的OS X .dylib几乎可以满足您的要求,请注意您需要一个导出文件,链接器使用该文件来确定导出哪些符号(以防止泄漏内部符号)。

为了使您自己的库依赖项安全,您可能需要将这些库包含在您的库中,或者将它们静态链接到您的库中。

编辑:要回答有关如何将导出文件应用于链接命令的后续问题,ld的手册页有以下内容:

 -exported_symbols_list filename
     The specified filename contains a list of global symbol names
     that will remain as global symbols in the output file.  All
     other global symbols will be treated as if they were marked
     as __private_extern__ (aka visibility=hidden) and will not be
     global in the output file. The symbol names listed in file-
     name must be one per line.  Leading and trailing white space
     are not part of the symbol name.  Lines starting with # are
     ignored, as are lines with only white space.  Some wildcards
     (similar to shell file matching) are supported.  The *
     matches zero or more characters.  The ? matches one charac-
     ter.  [abc] matches one character which must be an 'a', 'b',
     or 'c'.  [a-z] matches any single lower case letter from 'a'
     to 'z'.

因此,如果您的库只有两个您希望公开的函数,那么我们称之为foobar,它们是C函数(因此符号名称不会被修改),你的导出文件(我们称之为myLibrary.exports)将包含以下两行:

_foo
_bar

也许还有一些注释等。当您执行构建库的最后一个链接步骤时,您会将-exported_symbols_list myLibrary.exports标志传递给链接器。如果您不提供其中一个导出符号,这还有一个额外好处,即链接将失败;这可以捕获很多“哎呀,我忘了在构建中包含该文件”的错误。

当然,您不需要使用命令行工具来完成所有这些工作。在XCode中的动态库的构建设置中,您将找到Exported Symbols File(默认情况下未定义);将其设置为导出文件的路径,然后将其传递给链接器。

答案 1 :(得分:1)

您需要的关键术语是“框架”。您需要创建一个自包含的“通用”框架。 ('Universal'是Apple-ease for'编译几次并打包成一个库。)在封装方面,它并不像在Windows上那么简单,但是必要的链接器选项就在那里。