向下兼容ABI使用升压创建库 [英] Creating Library with backward compatible ABI that uses Boost
问题描述
我的工作有一定的C ++库(或更多框架)。我想使它落后
以previous版本preserving兼容,不仅API兼容性也ABI(如伟大的工作,Qt的一样)。
I'm working on a certain C++ library (or more framework). I want to make it backward compatible with previous versions preserving not only API compatibility but also ABI (like the great job Qt does).
我使用大量的Boost功能,似乎对我来说这使得向后兼容性只是不可能的,除非我强迫用户具有完全相同的(有时旧)加速版本。
I use lots of functionality of Boost and it seems for me that this makes backward compatibility just impossible, unless I force a user to have exactly the same (sometimes old) version of Boost.
有什么办法(无需重写升压的1/2),使一些preFIX围绕其命名空间/从加速的用户版本的干扰,以便其重命名为prevent呢?
Is there any way (without rewriting 1/2 of Boost) to make some "prefix" around its namespace/rename it in order to prevent it from interfering with a user version of Boost?
例如我libXYZ使用升压1.33,它具有类的boost :: foo的
。在版本1.35 的boost :: foo的
进行了升级,并加入新的成员,因此,的boost :: foo的
从1.33 1.35是
ABI不兼容。因此,libXYZ的用户必须使用升压1.33或重新编译libXYZ与
升压1.35(即可能已经打破的方式XYZ不会编译一些API)。
For example my libXYZ uses Boost 1.33 and it has class boost::foo
. In version 1.35 boost::foo
was upgraded and new member was added, so, boost::foo
from 1.33 and 1.35 are
not ABI compatible. So, a user of libXYZ must use Boost 1.33 or recompile libXYZ with
Boost 1.35 (that may be already had broken some API in a way XYZ would not compile).
注意:我说的是UNIX / Linux操作系统与ELF其中,动态链接类似于静态链接,所以你不能用两个不同版本的库链接,因为符号会干扰
Note: I'm talking about UNIX/Linux OS with ELF where dynamic linking is similar to static linking, so you can't link with two different versions of libraries because symbols would interfere.
一个合适的解决方案,我可以想到的是把加速在其他一些私人空间。因此,libXYZ会使用 :: XYZ ::提高:: foo的
而不是的::提高:: foo的
。这将prevent碰撞升压用户可以使用其他版本。
One suitable solution I may think of is putting Boost in some other private namespace. So, libXYZ would use ::XYZ::boost::foo
instead of ::boost::foo
. This would prevent collision with other version of Boost that user may use.
因此,libXYZ将继续与升压1.33静态或动态与它withing其他的命名空间,假设,它链接到工作:
So, the libXYZ would continue to work with Boost 1.33 statically or dynamically linked with it withing other namespace, assuming, that it:
- 会不会暴露加速API之外。
- 将保持公开的API的稳定的专用版本。
有没有办法做这样的事情升压?
Is there any way to do such things with Boost?
编辑:最后,我决定创建一个脚本,将在源头上一些自定义符号重命名所有升压符号
Finally I decided to create a script that would rename all boost symbols in the source to some custom symbol.
理由:构建过程的简化,独立的编译器知名度的支持,另外,它的知名度适用于动态库只,静态这也不行,所以我需要单独建立和依赖关系为每种类型的库
Rationale: simplification of build process, independent of compiler visibility support, also, it visibility works on dynamic libraries only, for static this does not work, so I need separate builds and dependencies for each type of libraries.
脚本可有: HTTP://art-blog.no- ip.info/files/rename.py
编辑2:最新升压BCP版本支持重命名空间
Edit 2: Latest version of Boost BCP supports namespace renaming.
推荐答案
基本上,只要确保的公共接口库中不公开提振。您可以随时使用它不过多你想要的内部。通常,具有一个库的接口取决于另一个库是坏的(除非它取决于像STL一个标准库)。升压几乎适合标准库类,但它的变化ABI这么多,你的接口应不会使用它。
Basically, just make sure the public interface to your library does not expose Boost. You can always use it however much you want internally. Generally, having the interface of a library depend on another library is bad (unless it depends on a standard library like STL). Boost almost fits into the "standard" library category, but its ABI changes so much that that your interface shouldn't use it.
要确保你没有揭露升压符号,有一些事情可以做:
To make sure you don't expose the Boost symbols, there are a few things you could do:
一个。与 -fvisibility隐藏=
编译和标记与所有公共符号__属性__((能见度(默认)))
。您可以使用宏来简化这一过程:
A. compile with -fvisibility=hidden
and mark all public symbols with __attribute__((visibility("default")))
. you could use a macro to make this easier:
#define ABI __attribute__((visibility("default")))
乙。做这样的事情:
#pragma GCC visibility push(hidden)
#include <boost/whatever.hpp>
#pragma GCC visibility pop
您也应该把这个包周围,你不想出口,或声明这个__属性__所有其他内部符号((能见度(隐藏)))
。同样,你可以使用宏来简化这一过程:
You should also wrap this around all other internal symbols that you don't want exported, or declare this with __attribute__((visibility("hidden")))
. Again, you could use a macro to make this easier:
#define INTERNAL __attribute__((visibility("hidden")))
在这些选项中,我喜欢一个更好的,因为它使你明确地想想哪些符号出口,所以你不小心导出你不想要的东西。
Of these options, I like A better, because it makes you explicitly think about which symbols are exported, so you don't accidentally export things you don't want.
顺便说一句,你可以找到关于乌尔里希Drepper的制作的DSO如何写更多的信息共享库。
By the way, you can find a lot more information about making DSOs in Ulrich Drepper's How to Write Shared Libraries.
这篇关于向下兼容ABI使用升压创建库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!