2009-11-19 58 views
2

我打算发布一些编译后的代码,这些代码将由MacOSX上的客户端应用程序链接。在OSX上分发二进制库

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

这些都是我的要求或至少我希望我能做到:

  • 我想我的图书馆是为不可知 尽可能什么OSX 的版本和GCC用户运行。虽然有 单独的库为64位和32 位是好的。
  • 我希望我的库 可以从 支持加载C库(例如 python或类似文件)的语言加载。
  • 我希望我的 库的内部符号是从 链接到的代码中分离出的 。我不想 重复的符号错误,因为我们 恰巧以相同的方式命名内部函数 。我的C++代码是正确命名空间的,所以这可能不是一个大问题,但我依赖的一些库是C并且可能是一个问题(见下一点)。
  • 我想我的库 依赖关系是安全的。我的图书馆 取决于一些库如 的libpng,升压和STL,我不希望 的问题,因为许多用户并不 一定个个安装 或得到的问题,因为他们已经 编译与其他标志或 与我有不同的版本。

在Windows上,我使用带导出库的DLL,并将所有依赖关系静态链接到dll。它符合上述所有条件,如果我可以在OSX上得到相同的结果,那将是非常好的,但是我听说动态库往往不以同样的方式在mac上隔离符号。

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

回答

2

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

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

编辑:为了回答如何应用exports文件的链接命令的后续问题,为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(默认情况下未定义);将其设置为您的导出文件的路径,并将其传递给链接器。

+0

这似乎是一个很好的解决方案。关于如何创建导出文件,您有没有很好的参考? – Laserallan 2009-11-19 23:52:34

+0

我添加了一些关于如何使用导出文件的细节;关于如何创建一个,如果库不是太大,我通常使用nm来获取所有符号的列表,然后删除那些我想保持私有的。对于大型项目,这不是一个真正可行的方法,所以我通常编写脚本来为我生成文件。 – 2009-11-20 01:42:54

+2

另请注意,不需要单独的32位和64位库; OS X允许支持多种体系结构的dylib。从命令行看起来有些复杂,但如果你使用XCode,它应该是Just Work。 – 2009-11-20 01:45:08

1

您需要的关键词是'框架'。您需要创建一个独立的“通用”框架。 ('通用'是苹果易于'编译多次并封装到一个库中。)它不像封装那样直接在Windows上,但必要的链接器选项就在那里。