向下兼容ABI使用升压创建库 [英] Creating Library with backward compatible ABI that uses Boost

查看:179
本文介绍了向下兼容ABI使用升压创建库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作有一定的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆