web-dev-qa-db-ja.com

CコードをC ++コードにリンクするときのg ++​​リンク順序の依存関係

今日まで、私は常に、リンク段階でオブジェクトとライブラリがg ++に渡される順序は重要ではないと信じていました。次に、今日、c ++コードからcコードへのリンクを試みました。すべてのCヘッダーをextern "C"ブロックでラップしましたが、リンカーはまだ、Cオブジェクトアーカイブにあることがわかっているシンボルを見つけるのが困難でした。

困惑して、リンクエラーを分離するための比較的単純な例を作成しましたが、驚いたことに、問題なくリンクした単純な例です。

少し試行錯誤した結果、簡単な例で使用したリンクパターンをエミュレートすることで、メインコードをリンクできるようになりました。パターンは、最初にオブジェクトコード、次にオブジェクトアーカイブでした。

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

なぜこれがそうなのかについて誰かがいくつかの光を当てることができますか?通常のc ++コードをリンクするときにこの問題を見たことはありません。

34
Gearoid Murphy

オブジェクトファイルとライブラリを指定する順序は、GCCで非常に重要です-魅力的な生活を送る前にこれに噛まれていない場合。リンカはシンボルを出現順に検索するため、ライブラリ関数の呼び出しを含むソースファイルがある場合は、ライブラリの前に配置する必要があります。そうしないと、リンカはそれを解決する必要があることを認識しません。ライブラリーの複雑な使用は、ライブラリーを複数回指定する必要があることを意味する場合があり、これは正しく行うための王室の痛みです。

45
anon

Gcc/g ++へのライブラリの順序パスは実際には重要です。 ABに依存する場合、Aを最初にリストする必要があります。その理由は、参照されていないシンボルを最適化するためです。そのため、ライブラリBが最初に表示され、その時点でだれもそれを参照していない場合、そこから何もリンクされません。

21
Mark B

静的ライブラリは、アーカイブにグループ化されたオブジェクトファイルのコレクションです。それに対してリンクするとき、リンカーは現在未定義のシンボルを解決するために必要なオブジェクトのみを選択します。オブジェクトはコマンドラインで指定された順序でリンクされるため、ライブラリのオブジェクトは、ライブラリがそれに依存するすべてのオブジェクトの後にある場合にのみ含まれます。

したがって、リンクの順序は非常に重要です。静的ライブラリを使用する場合は、依存関係を追跡するように注意する必要があり、ライブラリ間に循環依存関係を導入しないでください。

7
Mike Seymour

-start-group archives --end-groupを使用して、archivesの代わりに2つの依存ライブラリを書き込むことができます

gcc main.o -L。 -Wl、-start-group -lobj_A -lobj_b -Wl、-end-group

1
Hani