Boostを使用する下位互換性のあるABIを備えたライブラリを作成する 質問する

Boostを使用する下位互換性のあるABIを備えたライブラリを作成する 質問する

私は特定の C++ ライブラリ (またはフレームワーク) に取り組んでいます。API 互換性だけでなく ABI も維持しながら、以前のバージョンとの下位互換性を確保したいと考えています (Qt が行っている素晴らしい作業のように)。

私は Boost の多くの機能を使用していますが、ユーザーに Boost のまったく同じバージョン (場合によっては古いバージョン) を強制しない限り、下位互換性は不可能になると思われます。

Boost のユーザー バージョンに干渉しないように、名前空間の周囲に何らかの「プレフィックス」を作成したり、名前を変更したりする方法 (Boost の半分を書き換えずに) はありますか?

たとえば、私の libXYZ は Boost 1.33 を使用しており、クラスがありますboost::foo。バージョン 1.35 ではboost::fooアップグレードされ、新しいメンバーが追加されたため、boost::foo1.33 と 1.35 は ABI 互換ではありません。したがって、libXYZ のユーザーは Boost 1.33 を使用するか、libXYZ を Boost 1.35 で再コンパイルする必要があります (XYZ がコンパイルできない方法で一部の API が既に壊れている可能性があります)。

注記:私が話しているのは、ELF を使用する UNIX/Linux OS です。ELF では、動的リンクは静的リンクに似ているため、シンボルが干渉するため、2 つの異なるバージョンのライブラリをリンクすることはできません。

私が考えられる適切な解決策の 1 つは、Boost を他のプライベート名前空間に配置することです。つまり、libXYZ は::XYZ::boost::fooの代わりにを使用します::boost::foo。これにより、ユーザーが使用する可能性のある他のバージョンの Boost との衝突を防ぐことができます。

したがって、libXYZ は、次のことを前提として、他の名前空間内で Boost 1.33 と静的または動的にリンクされて引き続き動作します。

  • Boost API を外部に公開しません。
  • 公開された API の安定したプライベート バージョンを維持します。

Boost でそのようなことを実行する方法はありますか?

編集:最終的に、ソース内のすべてのブースト シンボルの名前をカスタム シンボルに変更するスクリプトを作成することにしました。

理由: ビルド プロセスの簡素化、コンパイラの可視性サポートに依存しない、また、可視性は動的ライブラリでのみ機能し、静的ライブラリでは機能しないため、ライブラリの種類ごとに個別のビルドと依存関係が必要になります。

スクリプトは次の場所で入手できます:http://art-blog.no-ip.info/files/rename.py

編集2:Boost BCP の最新バージョンは名前空間の名前変更をサポートしています。

ベストアンサー1

基本的には、ライブラリへのパブリック インターフェイスが Boost を公開しないようにするだけです。内部的にはいつでも好きなだけ使用できます。一般的に、ライブラリのインターフェイスが別のライブラリに依存するのはよくありません (STL などの標準ライブラリに依存している場合を除く)。Boost はほぼ「標準」ライブラリ カテゴリに当てはまりますが、その ABI は大きく変更されるため、インターフェイスでは使用しないでください。

Boost シンボルが公開されないようにするには、次の方法があります。

A. でコンパイルし-fvisibility=hidden、すべてのパブリック シンボルを でマークします__attribute__((visibility("default")))。マクロを使用すると、これを簡単に行うことができます。

#define ABI __attribute__((visibility("default")))

B. 次のようにします。

#pragma GCC visibility push(hidden)
#include <boost/whatever.hpp>
#pragma GCC visibility pop

また、エクスポートしたくない他のすべての内部シンボルを で囲むか、 で宣言する必要があります__attribute__((visibility("hidden")))。ここでも、マクロを使用すると簡単に行うことができます。

#define INTERNAL __attribute__((visibility("hidden")))

これらのオプションのうち、私は A の方が好きです。どのシンボルをエクスポートするかを明示的に考える必要があるため、不要なものを誤ってエクスポートすることがなくなるからです。

ちなみに、DSOの作成に関する詳しい情報は、Ulrich Drepperの共有ライブラリの書き方

おすすめ記事