如何部署依赖动态库的应用程序?
我正在开发一个使用 GStreamer 库的应用程序。为了简化部署,我想将所有 GStreamer 库收集到本地捆绑包中。为此,我编写了一个小脚本,它执行以下操作:
- 递归遍历依赖项(使用 otool -L )
- 将所有依赖项复制到本地目录
- 使所有依赖项路径相对于 @executable_path (使用 install_name_tool )
(如果您有兴趣,可以查看 Ruby 脚本。)
但是,我现在在 gst_init
调用上看到运行时错误:
(process:22843): GLib-GObject-CRITICAL **: gtype.c:2458: initialization assertion failed, use g_type_init() prior to this function
(process:22843): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0' failed
这些错误仅在我使用本地化库时才会发生。
使用 install_name_tool 时是否存在某些“常见陷阱”?有谁知道我可能做错了什么?如果您需要了解某些细节,请随时询问。
更新
我更改了一些内容:
- 对于依赖库,我现在仅更改 dylib 路径而不是 id(仅使用
install_name_tool -change
而不是install_name_tool -id
)。 - 对于主库,我设置了相对于可执行路径的 id 值 (
@executable_name/components/Video.dylib
)。
这两个改变使其发挥作用。然而我还不清楚它为什么有效。我在理解“id”属性的含义时遇到一些困难。它似乎是路径名形式的标识符。为什么更改依赖库会导致运行时错误?我将尝试通过进一步的实验来找到这些问题的答案......
I am developing an application that uses the GStreamer library. In order to ease deployment I would like to collect all the GStreamer libraries in a local bundle. For this I wrote a little script that does the following:
- recursively traverse dependencies (using
otool -L
) - copy all dependencies to a local directory
- make all the dependency paths relative to @executable_path (using
install_name_tool
)
(If you're interested you can have a look at the Ruby script.)
However, I'm now seeing runtime errors on the gst_init
call:
(process:22843): GLib-GObject-CRITICAL **: gtype.c:2458: initialization assertion failed, use g_type_init() prior to this function
(process:22843): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0' failed
These errors only occur if I use the localized libraries.
Are there certain 'common pitfalls' when it comes to using install_name_tool? Does anyone have an idea what I could be doing wrong? If you need to know certain details then feel free to ask.
Update
I changed a few things:
- For the dependent libraries I now only change the dylib paths and not the id (only use
install_name_tool -change
and notinstall_name_tool -id
). - For the main library I set the id value relative to the executable path (
@executable_name/components/Video.dylib
).
These two changes make it work. However it is not yet clear to me why it works. I have some trouble understanding the meaning of the "id" property. It seems to be identifier in the form of a pathname. Why did changing it for the dependent libraries cause runtime errors? I'll try to find answers to those questions with some further experimentation...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许您应该考虑对代码进行静态编译。
这会将您的依赖项更好地附加到您的程序中
如果您使用 gcc,只需添加
-static
,maybe you should consider a static compilation of your code.
this will attach your dependencies to your program much better
if you're using gcc just add
-static
GStreamer 是一个复杂的系统,具有很多依赖性。使用工具可以找到 GStreamer 直接需要的共享库,但它们肯定会错过动态加载的库、配置文件和翻译数据。
此网站可能包含一些有关创建的有用信息独立的 GStreamer 包,可以简化捆绑过程。
GStreamer is a complex system, with a lot of dependencies. Using tools will find out shared libraries directly required by GStreamer, but they'll surely miss libraries loaded dynamically, configuration files, and also translation data.
This site probably contains some usefull info on creating a stand-alone GStreamer package, which could simplify the bundling prpcess.