dyld 无法加载 dylib

发布于 2024-10-28 21:49:17 字数 225 浏览 6 评论 0原文

我有一堆 dylib,我需要在运行时从应用程序包加载。我注意到,如果我将 dylibs 放在 /usr/lib 文件夹中,那么应用程序就可以加载它。我已经阅读了 install_name_tool 手册,但不知道如何让我的应用程序从 .app/contents/Frameworks 文件夹加载这些 dylib。

有人可以帮我解决这个问题吗?

I have a bunch of dylibs which i need to load at runtime from application bundle. I have noticed that if i put my dylibs in /usr/lib folder, then application is able to load it. I have gone thru install_name_tool manual but haven't got a clue on how can i make my application load these dylibs from .app/contents/Frameworks folder.

Could please someone help me out with this??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月野兔 2024-11-04 21:49:17

我昨天刚刚处理了同样的问题。

不直观的是,您会期望,因为您将 dylib 拖到 XCode 的文件浏览器中,并且由于您添加了一个构建阶段来将它们复制到捆绑的可执行文件中,所以链接器会“写入”应用程序以告诉它在哪里可以找到这些 dylib 。不幸的是,事实并非如此。

无论出于什么历史原因或谁知道为什么,它不是从 XCode 中执行的操作中获取此信息,而是从 dylib 本身内部的字符串中获取此信息。 XCode 不涉及的一种,您需要使用命令行工具手动设置。

每个 dylib 内部都有一个名为“id”的字符串,它是程序查找 dylib 的路径。我认为这会在链接时复制到可执行文件中。要找出该字符串是什么,可以运行以下命令:

otool -L pathToMyDylib

命令输出的第一行是程序运行时 exec 期望的字符串,称为“id”。我构建了一些 boost 库,它们的 id 的输出只是文件名。该命令输出的后面几行是“依赖项”;这些是您的 dylib 可能依赖于运行的其他库。通常,就像我的情况一样,这些库保证存在于任何 mac 发行版中,因此您不必担心必须更正这些库。如果他们不是这样的话;如果它们是您自己构建的库并将包含在您的应用程序中,您也必须更正这些库。因此,我的 otool -L libboost_regex.dylib 的输出是:

libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.0.0)

第一行是需要更正以查看可执行文件内部的行。您是正确的,install_name_tool 是解决此问题的正确方法。我用来解决这个问题的是(我的终端与我的 boost dylib 位于同一目录中):

install_name_tool -id "@executable_path/../Frameworks/libboost_regex.dylib" libboost_regex.dylib

分别,那里的第一个参数(在 -id 标志之后)是新路径,第二个参数是要修改的 dylib 文件。

如果您需要对其中一个依赖项进行类似的修改,您可以使用:

install_name_tool -change oldpath newpath currentfile

并且必须对每个单独的依赖项重新应用此修改。

我希望这有帮助!

I just dealt with this same problem yesterday.

What's unintuitive is that you would expect, since you drag your dylibs into XCode's file browser, and since you add a build phase to copy them into your bundled executable, the linker would "write into" the app to tell it where to find those dylibs. Unfortunately, it doesn't.

For whatever historical-or-who-knows-why reason, instead of deriving this info from what you do in XCode, it derives this from a string inside the dylibs themselves. One which XCode doesn't touch, and which you need to set manually with a commandline tool.

Inside each of the dylibs is a string called the "id", which is the path that the program will look for the dylibs at. I think this gets copied into the executable at link time. To find out what this string is, you can run the following:

otool -L pathToMyDylib

The first line that command outputs is the string the exec will expect it to be at, when the program is run, which is called the "id". I built some boost libraries, and the output for their id was simply the filename. The later lines that the command outputs are "dependencies"; these are other libraries that your dylib may depend on to run. Often, as was the case with mine, these are libraries which are guaranteed to be in any mac distro, so you have no worries about having to correct these. If they weren't such; if they were libraries you had built yourself and were going to include in your app, you would have to correct these as well. So, the output for my otool -L libboost_regex.dylib was:

libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.0.0)

The first line, is the one that needs to be corrected to look inside my executable. You're correct that install_name_tool is the right thing to fix this. What I used to fix this was (with my terminal in the same directory as my boost dylib):

install_name_tool -id "@executable_path/../Frameworks/libboost_regex.dylib" libboost_regex.dylib

Respectively, the first parameter there (after the -id flag) is the new path, and the second parameter is the dylib file to be modified.

If you needed to do a similar modification to one of the dependencies, you'd use:

install_name_tool -change oldpath newpath currentfile

And this would have to be reapplied for each separate dependency.

I hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文