我的目标是与brew中的库动态链接.如何捆绑分发?

Bir*_*abs 5 macos dylib dynamic-linking dyld install-name-tool

我构建了一个音频插件.我的目标.app.component.

我动态链接到Brew安装的库,libfluidsynth.

我复制libfluidsynth.app/ .component.
我曾经install_name_tool重新链接二进制文件指向捆绑libfluidsynth.

libfluidsynth取决于glib,gthread,intl.
我将这些库复制到捆绑包中,重新链接libfluidsynth以更喜欢捆绑的副本.
我也为这些库及其依赖项做了同样的事情.

这是一个快速查看看起来像:

ls /Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/Frameworks
    libfluidsynth.1.7.1.dylib
    libglib-2.0.0.dylib
    libgthread-2.0.0.dylib
    libintl.8.dylib
    libpcre.1.dylib

otool -L \
/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/MacOS/juicysfplugin \
/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/Frameworks/* \
| grep -vE '\t(/System/Library|/usr/lib)'

/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/MacOS/juicysfplugin:
    @executable_path/../Frameworks/libfluidsynth.1.7.1.dylib (compatibility version 1.0.0, current version 1.7.1)
/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/Frameworks/libfluidsynth.1.7.1.dylib:
    @loader_path/../Frameworks/libfluidsynth.1.dylib (compatibility version 1.0.0, current version 1.7.1)
    @loader_path/../Frameworks/libgthread-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libglib-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/Frameworks/libglib-2.0.0.dylib:
    @loader_path/../Frameworks/libglib-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libpcre.1.dylib (compatibility version 4.0.0, current version 4.9.0)
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/Frameworks/libgthread-2.0.0.dylib:
    @loader_path/../Frameworks/libgthread-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libglib-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libpcre.1.dylib (compatibility version 4.0.0, current version 4.9.0)
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/Frameworks/libintl.8.dylib:
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/git/juicysfplugin/Builds/MacOSX/build/Release/juicysfplugin.app/Contents/Frameworks/libpcre.1.dylib:
    @loader_path/../Frameworks/libpcre.1.dylib (compatibility version 4.0.0, current version 4.9.0)
Run Code Online (Sandbox Code Playgroud)

这非常适合.app.在这里,查看文件opens(opensnoop | grep 'dylib'):

EXECNAME      PATH
juicysfplugin  juicysfplugin.app/Contents/MacOS/../Frameworks/libfluidsynth.1.7.1.dylib
juicysfplugin  juicysfplugin.app/Contents/MacOS/../Frameworks/../Frameworks/libgthread-2.0.0.dylib
juicysfplugin  juicysfplugin.app/Contents/MacOS/../Frameworks/../Frameworks/libglib-2.0.0.dylib
juicysfplugin  juicysfplugin.app/Contents/MacOS/../Frameworks/../Frameworks/libintl.8.dylib
juicysfplugin  juicysfplugin.app/Contents/MacOS/../Frameworks/../Frameworks/../Frameworks/libpcre.1.dylib
Run Code Online (Sandbox Code Playgroud)

.app只查找其捆绑的框架文件夹内dylibs.完善.

然后我做了相同的副本并重新链接到我的.component目标.这没用.

我加载.component到音频插件主机,并检查文件打开:

EXECNAME     PATH
Plugin Host  /Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/MacOS/juicysfplugin
Plugin Host  /usr/local/lib/libfluidsynth.1.7.1.dylib
Plugin Host  /usr/local/opt/glib/lib/libgthread-2.0.0.dylib
Plugin Host  /usr/local/opt/glib/lib/libglib-2.0.0.dylib
Plugin Host  /usr/local/opt/gettext/lib/libintl.8.dylib
Plugin Host  /usr/local/opt/pcre/lib/libpcre.1.dylib
Run Code Online (Sandbox Code Playgroud)

它正在寻找下的图书馆/usr/local.为什么?作为一个完整性检查,我曾经otool确认我确实已正确链接:

otool -L \
/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/MacOS/juicysfplugin \
/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/Frameworks/* \
| grep -vE '\t(/System/Library|/usr/lib)'

/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/MacOS/juicysfplugin:
    @executable_path/../Frameworks/libfluidsynth.1.7.1.dylib (compatibility version 1.0.0, current version 1.7.1)
/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/Frameworks/libfluidsynth.1.7.1.dylib:
    @loader_path/../Frameworks/libfluidsynth.1.dylib (compatibility version 1.0.0, current version 1.7.1)
    @loader_path/../Frameworks/libgthread-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libglib-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/Frameworks/libglib-2.0.0.dylib:
    @loader_path/../Frameworks/libglib-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libpcre.1.dylib (compatibility version 4.0.0, current version 4.9.0)
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/Frameworks/libgthread-2.0.0.dylib:
    @loader_path/../Frameworks/libgthread-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libglib-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.3.0)
    @loader_path/../Frameworks/libpcre.1.dylib (compatibility version 4.0.0, current version 4.9.0)
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/Frameworks/libintl.8.dylib:
    @loader_path/../Frameworks/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
/Users/me/Library/Audio/Plug-Ins/Components/juicysfplugin.component/Contents/Frameworks/libpcre.1.dylib:
    @loader_path/../Frameworks/libpcre.1.dylib (compatibility version 4.0.0, current version 4.9.0)
Run Code Online (Sandbox Code Playgroud)

我以为我正确地联系了它.我使用完全相同的脚本(它是自动化和参数化的).我究竟做错了什么?音频插件主机如何知道查找依赖项/usr/local?为什么忽略我的图书馆链接?

我发布了二进制文件:https://github.com/Birch-san/juicysfplugin/releases/tag/1.0.1

我的重新链接脚本在这里:https://github.com/Birch-san/juicysfplugin/blob/master/Builds/MacOSX/relink-build-for-distribution.sh

使用.app.component目标的主要区别在于:

  • .app 是独立的
  • .component 是一个Audio Unit插件,可以加载到DAW /音频插件主机中.

那么,当父进程负责加载我们的可执行文件时,运行时依赖项解析可能会有所不同吗?

Bir*_*abs 3

好的,我成功了

\n\n

macOS 加载时链接记录在man dyld

\n\n

问题是我告诉我的二进制文件寻找与@executable_path.

\n\n

这对于 .app 来说效果很好,因为 .app 的二进制文件可执行文件。

\n\n

但对于我的 .vst 和 .component 插件,二进制文件被加载到不同的可执行文件中:音频插件主机。

\n\n

因此,如果我们想查找与二进制文件( juicysfplugin.component/Contents/MacOS/juicysfplugin) 相关的库,我们需要使用@loader_path, 而不是@executable_path

\n\n
\n\n

现在,到其他谜团\xe2\x80\xa6 为什么加载时链接器忽略我的安装路径(@executable_path/../Frameworks/libfluidsynth.1.7.1.dylib),而是在下面查找 find Fluidsynth/usr/local/lib/libfluidsynth.1.7.1.dylib

\n\n

正是因为DYLD_FALLBACK_LIBRARY_PATH

\n\n
\n

它用作安装路径中未找到的库的默认位置。默认情况下,它设置为$(HOME)/lib:/usr/local/lib:/lib:/usr/lib

\n
\n\n

我相信它无法在安装路径中找到该库。libfluidsynth.1.7.1.dylib然后它在几个目录下查找叶文件名 \xe2\x80\x94 \xe2\x80\x94 ,包括/usr/local/lib(成功了)。

\n\n

为什么我在 opensnoop 中没有看到失败的文件查找?open可能它使用与//不同open_nocancel的系统调用open_extended。例如,stat在文件上运行不会显示在 opensnoop 中。

\n\n

加载时链接也可能由dyld进程完成。SIP 不允许将 DTrace 附加到此进程。

\n