C++ :如何链接 libA.so 而不是 libA-XYZso
我有一个我开发的库 A。 当我将它部署到机器上时,相应的libA.so和libA-XYZso被放入/usr/lib中(XYZ是版本号)。
现在我开发了一个库B,它使用A。当我链接B时,我使用标志-lA。 然后“ldd libB.so”给了我:
(...)
libA-X.Y.Z.so => /usr/lib/libA-X.Y.Z.so
(...)
我的问题是,当我发布新版本的 A (XYZZ) 时,我还必须发布新版本的 B。否则,有人安装最新版本A 将无法安装 B,而 B 将寻找不存在的版本 XYZ。
我该如何解决这个问题? 我如何告诉 B 寻找 libA.so 而不是 libA-XYZso ? 或者说这样做是错误的吗? 甚至不安全?
更新1:库A(我从其他人继承的)使用自动工具。
更新2:当我构建库A时,我可以看到:“-Wl,-soname -Wl,libA-0.6.1.so”。 如果我理解正确的话,这意味着我们强制soname为libA-0.6.1.so。 是对的吗 ? 现在我的问题是我不知道如何在使用自动工具的项目中修改此行为。 我用谷歌搜索了一段时间,但找不到任何有用的信息。 我应该修改configure.in还是Makefile.am?
I have a library A, that I develop. When I deploy it on a machine, the corresponding libA.so and libA-X.Y.Z.so are put in /usr/lib (X.Y.Z being the version number).
Now I develop a library B, which uses A. When I link B, I use the flag -lA. Then "ldd libB.so" gives me :
(...)
libA-X.Y.Z.so => /usr/lib/libA-X.Y.Z.so
(...)
My problem is that when I release a new version of A (X.Y.ZZ), I also have to release a new version of B. Otherwise, someone installing the latest A won't be able to install B which will be looking for the version X.Y.Z which doesn't exist.
How do I solve this problem ? How can I tell B to look for libA.so and not libA-X.Y.Z.so ? Or is it wrong to do so ? even unsafe ?
Update 1 : library A (that I inherited from someone else) uses autotools.
Update 2 : when I build library A, I can see : "-Wl,-soname -Wl,libA-0.6.1.so". If I understand properly that means that we are forcing the soname to be libA-0.6.1.so. Is that right ? Now my problem is that I have no clue how to modify this behaviour in a project which uses autotools. I googled for a while but can't find any useful information. Should I modify configure.in or a Makefile.am ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
创建 libA.so 时,将 -soname 选项传递给链接器(如果通过 gcc 链接,请使用 -Wl,-soname)。 然后,当 B 被链接时,链接器通过其soname(而不是通过其文件名)引用A。 在目标系统上,确保有从 soname 到真实文件的链接。 请参阅
http://www.linux.org/文档/ldp/howto/Program-Library-HOWTO/shared-libraries.html
When you create libA.so, pass the -soname option to the linker (if you linking through gcc, use -Wl,-soname). Then, when B gets linked, the linker refers to A through its soname, not through its filename. On the target system, make sure you have a link from the soname to the real file. See
http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html
这在 Windows 中也可以作为“DLL 地狱”运行:)。
如果 B 需要 A 的特定版本,并且您链接到 libA 而不是 libA-XYZ,则仅用较新版本替换 libA 可能会导致 B 无法加载或崩溃。
当然,您可以进行从 libA-XYZ 到 libA-X1.Y1.Z1 的符号链接。 如果没有 API 发生变化而只有实现,那么您应该是安全的。
This also works in Windows as "DLL hell" :).
If B needs a specific version of A and you would link to libA not libA-X.Y.Z then only substituting libA with newer version might cause B not to load or crash.
But of course you can do a symlink from libA-X.Y.Z to libA-X1.Y1.Z1. If no APIs changed and only implementations than you should be safe.
回答我的第二次更新:
在libA的Makefile.am中,我将_la_LDFLAGS从-release修改为-avoid-version。 这创建了一个没有版本号的共享库,然后我重新编译了 libB,它成功链接到这个未版本化的共享库。
Answering to my second update :
In the Makefile.am of libA, I modified _la_LDFLAGS from -release to -avoid-version. This created a shared library without version number and I then recompiled libB which successfully linked against this unversioned shared library.