10

繰り返しますが、同じVisual-C++ バージョンのライブラリ間の ABI 互換性を探しています。

異なるプロジェクト ファイルで異なる時期にビルドされた、異なるチームのいくつかの内部 C++ DLL を組み合わせて一致させたいと考えています。ビルド時間が長いため、各チームが別のチームのライブラリのソース コードを再コンパイルする大規模なモノリシック ビルドは避けたいと考えています。

C++ インターフェイスで C++ DLL を使用する場合、すべての DLL が同じコンパイラ/Visual Studio バージョンでコンパイルされている場合にのみこれを実行できることは明らかです

私にはすぐにはわかりませんが、ABI の互換性を得るには、正確に同じにする必要があります。

  • debug ( _DEBUG) と release ( NDEBUG) を混在させることはできませんが、これらが異なるバージョンの共有ランタイムにリンクしていることからも明らかです。
  • まったく同じバージョンのコンパイラが必要ですか、それとも結果の DLL が同じ共有C++ ランタイム (つまり、基本的に同じ再配布可能ファイル) にリンクされていれば十分ですか? (完全なC++オブジェクトを渡すと、静的は飛ばないと思います)
  • 同じ vc++ バージョンの 2 つの C++ DLL が互換性を持つために同じである必要がある コンパイラ(およびリンカー) オプションのリストは文書化されていますか?
    • たとえば、同じ/Oスイッチが必要ですか?最適化レベルは ABI の互換性に影響しますか? (そうではないことは確かです。)
    • または、両方のバージョンで同じ/EHスイッチを使用する必要がありますか?
    • それとも/volatile:ms|iso...?

基本的に、ABI の互換性を説明する Visual-C++ DLL に関連付ける (メタ) データのセットを作成したいと考えています。

違いがある場合、現時点では VS2015 のみに焦点を当てています。

4

1 に答える 1

3

ここ数日、これについて考えてきました。私が行ったことは、開発者がバイナリの互換性を確保するために C++ ビルドを分類する必要があるユースケースが存在するかどうかを確認することでした。

そのような場所の 1 つは、nuget のネイティブ パッケージです。そこで、あるパッケージ、特にcpprestsdkを調べました。

ダウンロード可能なパッケージのバイナリは、次のように分割されています。

native\v120\windesktop\msvcstl\dyn\rt-dyn\x64\Release\
        ^      ^         ^      ^    ^     
  VS version   |       not sure |    uses cpp-runtime dynamically
               |               lib itself dynamic (as opposed to static)
    or WinXP or WinApp(WinRT?)
                 

他のドキュメントが見つからなかったため、この例からこれを引き出しました。また、ブースト バイナリのビルド ディレクトリも同様に分離されていることを知っています。

したがって、ABI の互換性を識別するためのメタデータのリストを取得するには、次のリストを事前にリストすることができます。

  • VC バージョン (つまり、使用されている C および CPP ランタイム ライブラリのバージョン)
    • ここでのポイントの 1 つは、たとえばvc140、最近では十分なはずです。CRT がどのようにリンクされているかを考えると、バージョン管理された CRT コンポーネントに対するすべての可能なバグ修正はとにかく ABI 互換でなければならないため、特定のプリコンパイル済みライブラリがどのバージョンでビルドされたかは問題ではありません。
  • 純粋なネイティブ | マネージド (/CLI) | WinRT
  • CRT の消費方法 (静的/動的)
  • ビット数 / プラットフォーム (Win32、x64、ARM など)
  • リリースまたはデバッグ バージョン (つまり、リンク先の CRT のバージョン)
  • プラス:_ITERATOR_DEBUG_LEVEL...誰もがデフォルトを使用する場合は問題ありません。プロジェクトがそうでない場合は、そう宣言する必要があります

さらに、次の項目に関する私の最善の推測:

  • /O重要ではありません - 私たちは常にバイナリを異なる最適化設定でミックス&マッチさせています - 具体的には、これは同じバイナリ内のオブジェクトファイルに対しても機能しています
  • /volatile- これはコード生成の問題であるため、これがどのように ABI を破壊するか想像するのに苦労しています
  • /EH- すべての例外を無効にするオプションを除いて、その場合、スローされるものは何も呼び出せませんが、これは ABI の観点からは救われると確信しています: ここには落とし穴がある可能性がありますが、実際にはできないと思いますABI互換に分類されます。(おそらく、いくつかの複雑なコールバック チェーンは、ABI 非互換であると言えるかもしれませんが、確かではありません)

その他:

  • デフォルトの呼び出し規約 ( /G..) :これは、破損したエクスポート シンボルとヘッダー宣言が一致しない場合、リンク時に壊れると思います。
  • /Zc:wchar_t- リンク時に壊れます (実際には ABI 互換ですが、シンボルは一致しません。)
  • RTTI を有効にする ( /GR) - これについてはよくわかりません - これを無効にして作業したことはありません。
于 2016-10-26T20:18:27.570 に答える