在动态C库(dylib)中编译到OS X上的程序中

时间:2017-03-11 10:36:06

标签: c macos static-linking

我写了一个使用libusb的小程序。现在我想把这个程序发布到" normal" (不是开发)Mac OS X计算机。但是当我将编译后的文件移植到测试机器时,我收到了以下错误:

dyld: Library not loaded: /opt/local/lib/libusb-0.1.4.dylib
  Referenced from: /Users/kitty/myprogram
  Reason: image not found
Trace/BPT trap: 5

当我复制文件时(仅适用于所有文件)

/opt/local/lib/libusb-0.1.4.dylib   /opt/local/lib/libusb-1.0.a     
/opt/local/lib/libusb.a
/opt/local/lib/libusb-1.0.0.dylib   /opt/local/lib/libusb-1.0.dylib     
/opt/local/lib/libusb.dylib

从我的机器到目标机器程序运行完美无缺。

但我真的想在一个可执行文件中创建或编译所有内容。这怎么可能?

编译时使用-static不起作用,因为并非所有库都可以静态编译到最终应用程序中(参见this SO question here)。

那么如何制作一个整洁的小应用程序文件呢?

1 个答案:

答案 0 :(得分:1)

您可以convert a static library to a dynamic library,但我不知道如何按照您的意愿进行反向。

如果您正在使用捆绑包构建应用程序,则需要将要分发的库放在Frameworks目录中的捆绑包中,然后链接到该目录。

如果您构建基于捆绑包的应用程序,只需一个二进制文件,您可能需要为用户提供有关如何在其系统上安装库的说明(例如,通过Homebrew)。

以下是基于捆绑应用的应用方式:

Apple有一个document about run-path dependent libraries但实际上没有解释如何为新手设置这个。

以下是它应该如何运作:

  • 将您要使用的libusb.dylib添加到项目中。
  • 它应该会自动添加到项目的“Build Phases”中的“Link Binary with Libraries”阶段。如果没有,请在此处添加。
  • 添加新的“复制文件”构建阶段。
    • “目标”下拉框中,选择“Frameworks”。这是 应用程序最终包中的Frameworks目录。
    • 然后在该复制构建阶段按“+”图标并添加您的库。
  • 如果您有-L/usr/local/lib-lusb等任何手动关联选项,请将其删除。
  • 清洁和建造。

现在查看您的应用包时,您会看到该库已复制到<bundle_path>/Contents/Frameworks/。您现在可以从任何地方启动应用程序,动态链接加载器知道需要查看<path_to_binary>/../Frameworks/以查找您的库。

但是:您可能需要重建libusb以将install_name设置为@rpath/../Frameworks/libusb.dylib或使用install_name_tool CLI工具修复您添加到项目中的libusb.dylib副本的路径。