問題を説明するために、簡単なリンクの使用方法から始めたいと思います。共有ライブラリlibz.dll(D:/libs/z/shared/libz.dll)または静的ライブラリlibz.a(D:/ libs /にコンパイルできるライブラリz
があると仮定しましょう。 z/static/libz.a)。
それに対してリンクしたいので、これを行います:
gcc -o main.exe main.o -LD:/libs/z/static -lz
このドキュメント によると、gccはlibz.aを検索します。
メンバーがオブジェクトファイルであるアーカイブファイル
次のこともできます。
gcc -o main.exe main.o -LD:/libs/z/shared -lz
上記のドキュメントでは、-l
フラグがlib<name>.so
を検索することは言及されていません。
Libz.aとlibz.dllが同じディレクトリにある場合はどうなりますか?ライブラリはプログラムとどのようにリンクされますか? -Wl,-Bstatic
が共有ライブラリと静的ライブラリの両方を検索する場合、フラグ-Wl,-Bdynamic
および-l
が必要な理由
共有ライブラリディストリビューションをコンパイルする場合に、同じモジュールに対して.aファイルと.dllファイルを提供する開発者がいるのはなぜですか?
たとえば、Qtはbinディレクトリの.dllファイルとlibディレクトリの.aファイルを提供します。それは同じライブラリですが、それぞれ共有および静的のように構築されていますか?または、.aファイルは、実際のライブラリ実装がある共有ライブラリとのリンクを提供するダミーライブラリの一種ですか?
別の例は、Windows上のOpenGLライブラリです。なぜすべてのコンパイラーが、MingWのlibopengl32.aのような静的OpenGLライブラリーを提供する必要があるのですか?
.dll.aおよび.la拡張子を持つファイルは何に使用されますか?
追伸ここには多くの質問がありますが、それぞれが前の質問に依存していると思うので、質問をいくつかの質問に分ける必要はありません。
ldおよびWIN32(cygwin/mingw) をご覧ください。特に、LDのWindowsポートでの-l
フラグの動作の詳細については、dllへの直接リンクセクション。エキス:
たとえば、ldが引数-lxxxを指定して呼び出された場合、検索パスの最初のディレクトリで、
libxxx.dll.a xxx.dll.a libxxx.a cygxxx.dll (*) libxxx.dll xxx.dll
検索パスの次のディレクトリに移動する前に。
(*)実際には、これは
cygxxx.dll
ではありませんが、実際には<prefix>xxx.dll
です。<prefix>
はldオプション-dll-search-prefix=<prefix>
によって設定されます。 cygwinの場合、標準のgcc仕様ファイルには-dll-search-prefix=cyg
が含まれているため、実際にはcygxxx.dll
を検索します。
注:これまでにMinGWでBoostを構築したことがある場合、Boostライブラリの命名は上記のリンクで説明したパターンに従っていることを思い出すでしょう。
過去にMinGWに*.dll
に直接リンクする問題があったため、lib*.a
からエクスポートされたシンボルで静的ライブラリ*.dll
を作成し、代わりにリンクすることをお勧めしました。このMinGW wikiページへのリンクは現在無効になっているため、*.dll
に対して直接リンクしても問題ないと思います。さらに、私は最新のMinGW-w64ディストリビューションで何度か自分でやったが、まだ問題はなかった。
リンクフラグ-Wl,-Bstatic
および-Wl,-Bdynamic
が必要なのは、たとえば同じ名前の動的ライブラリが検索パスに存在する場合など、静的リンクを強制する場合があるためです。
gcc object1.o object2.o -lMyLib2 -Wl,-Bstatic -lMyLib1 -Wl,-Bdynamic -o output
上記のスニペットは、-l
フラグのデフォルトのリンク優先度がMyLib1
に対してオーバーライドされることを保証します。つまり、MyLib1.dll
が検索パスに存在する場合でも、LDリンクするlibMyLib1.a
を選択しますMyLib2
LDの場合は再び動的バージョンが優先されます。
注:MyLib2
がMyLib1
に依存する場合、MyLib1
に関係なく、-Wl,-Bstatic
も動的にリンクされます(つまり、この場合は無視されます)。これを防ぐには、MyLib2
も静的にリンクする必要があります。