5

我建立了一个音频插件。我的目标是.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)

这对.app. 在这里,查看打开的文件(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

唯一在其.app捆绑的 Frameworks 文件夹中查找 dylib。完美的。

.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

它正在寻找/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)

我以为我正确地链接了它。我使用了完全相同的脚本(它是自动化的和参数化的)。我究竟做错了什么?音频插件主机是如何知道在 下查找依赖项的/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是一个音频单元插件,您可以将其加载到 DAW / 音频插件主机中。

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

4

1 回答 1

3

好的,我得到它的工作

macOS 加载时链接记录在man dyld.

问题是我告诉我的二进制文件查找相对于@executable_path.

这适用于 .app,因为 .app 的二进制文件可执行文件。

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

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


现在,进入其他谜团……为什么加载时链接器忽略了我的安装路径(@executable_path/../Frameworks/libfluidsynth.1.7.1.dylib),而是在下面寻找 find fluidsynth /usr/local/lib/libfluidsynth.1.7.1.dylib

是因为DYLD_FALLBACK_LIBRARY_PATH

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

我相信它在安装路径中找不到库。libfluidsynth.1.7.1.dylib然后它在几个目录下寻找那个叶子文件名——包括/usr/local/lib(成功)。

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

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

于 2018-03-15T02:14:15.060 回答