ビルド スクリプトで静的ライブラリをビルドし、それらの静的ライブラリを最終的な実行可能ファイルのリンクに使用したい場合、ファイルを指定する順序.a
が重要です。
g++ main.o hw.a gui.a -o executable
gui.a
リンクで定義されたものを使用すると失敗します。これhw.a
は、その時点hw.a
で処理されるため、リンカーは後で定義が必要であることをまだ認識しておらず、それを being.generated 実行可能ファイルに含めないためです。リンカー行を手動でいじるのは実用的ではないため、解決策は--start-group
andを使用することです--end-group
。これにより、未定義のシンボルが見つからなくなるまで、リンカーがライブラリを 2 回実行します。
g++ main.o -Wl,--start-group hw.a gui.a -Wl,--end-group -o executable
ただし、GNU ld マニュアルには次のように書かれています
このオプションを使用すると、パフォーマンスが大幅に低下します。2 つ以上のアーカイブ間で避けられない循環参照がある場合にのみ使用することをお勧めします。
したがって、すべてのファイルを取得して、ファイルをリンクする必要がある順序を示すインデックス ( GNU ar のオプション) を使用.a
して 1 つのファイルにまとめた方がよいのではないかと考えました。次に、その 1 つのファイルのみを に渡します。.a
-s
.a
g++
しかし、グループコマンドを使用するよりも速いか遅いかは疑問です。そして、そのアプローチに問題はありますか?また、これらの相互依存性の問題を解決するためのより良い方法はありますか?
編集:ファイルのリストを.a
取得してマージされたファイルを生成するプログラムを作成しました.a
。GNU 共通ar
フォーマットで動作します。LLVM のすべての静的ライブラリをまとめてパックすると、次のように機能します
$ ./arcat -o combined.a ~/usr/llvm/lib/libLLVM*.a
すべてのファイルを手動で解凍し、インデックスを再計算して新しいファイル.a
に入れる場合と速度を比較しました。私のツールを使用すると、約 500 ミリ秒の一貫したランタイムが得られます。手動の方法を使用すると、時間は大きく異なり、約 2 秒かかります。だから価値があると思います。.a
ar
arcat
コードはこちらです。私はそれをパブリックドメインに入れました:)