代码之家  ›  专栏  ›  技术社区  ›  Laserallan

在OSX上分发二进制库

  •  2
  • Laserallan  · 技术社区  · 16 年前

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

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

    这些是我的要求,或者至少是我希望我能完成的:

    • 我希望我的图书馆像不可知论者一样 尽可能使用哪种版本的OSX 以及用户正在运行的gcc。有 64位和32位的独立库 不过也没关系。
    • 我想要我的图书馆 可从以下语言加载 支持加载C库,例如 巨蟒或类似。
    • 我想要我的 图书馆内部符号 与它的代码隔离 链接到。我不想有 重复符号错误,因为我们 恰巧命名了一个内部函数 以同样的方式。我的C++代码是正确的命名空间,所以这可能不是一个大问题,虽然,但我所依赖的一些库是C,可能是一个问题(见下一点)。
    • 我想要我的图书馆 依赖关系要安全。我的图书馆 取决于某些库,如 libpng,boost和stl,我没有 因为有些用户不希望出现问题 必须全部安装 或者因为他们有问题 已用其他标志编译或 有不同的版本。

    在Windows上,我使用一个带有导出库的DLL,并将所有依赖项静态链接到该DLL中。它满足上面所有的标准,如果我能在OSX上得到相同的结果,那就太好了,但是我听说动态库不会以相同的方式隔离Mac上的符号。

    在OSX上是否有这样的最佳实践?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Stephen Canon    16 年前

    一个普通的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'.
    

    所以,如果您的库只有两个您想要公开的函数,那么我们就称它们为 foo bar ,它们是C函数(所以符号名不会被破坏),您的导出文件(我们称之为 myLibrary.exports )包含这两行:

    _foo
    _bar
    

    可能还有一些评论等。当您完成构建库的最后一个链接步骤时,您将通过 -exported_symbols_list myLibrary.exports 指向链接器的标志。这还有一个额外的好处,即如果您不提供一个导出的符号,链接将失败;这可能会捕获许多“哎呀,我忘了在构建中包含该文件”错误。

    当然,您不需要使用命令行工具来完成这一切。在xcode中动态库的构建设置中,您将发现 Exported Symbols File (默认未定义);将其设置为导出文件的路径,然后将其传递到链接器。

        2
  •  1
  •   bmargulies    16 年前

    你需要的关键术语是“框架”。您需要创建一个独立的“通用”框架。(‘universal’是苹果的易用软件,可以编译几次并打包到一个库中。)在封装方面,它不像Windows那样简单,但有必要的链接器选项。