Unix の ld コマンド(GNU の ld コマンド固有かもしれないけど)には --whole-archive というオプションがあって、スタティックライブラリの中のオブジェクトファイルを、どこからも参照されていなくても出力ファイルに含めることができます。これは、スタティックライブラリをシェアードライブラリに変換する手法としても知られています。

で、Visual C++ の場合に同様のことをやる方法ですが、バージョンによってちょっと違います。

2013 以前の場合

アプリケーション (EXE) あるいは DLL プロジェクトのプロパティの「共通プロパティ」の「参照」で「ライブラリ依存関係の入力の使用」を「True」にすると、そのライブラリを普通にリンクするのではなく、そのライブラリを構成する元のオブジェクトファイル全てをリンクするようになります。つまり、 staticlib.lib が a.cpp と b.cpp から構成される場合、通常は staticlib.lib をリンクしますが、「ライブラリ依存関係の入力の使用」を「True」にした場合は a.obj と b.obj をリンクするようになります。

また、「構成プロパティ」-「リンカー」-「全般」にも「ライブラリ依存関係の入力の使用」の設定があり、これを「はい」にすると全ての依存するスタティックライブラリに対して効果があるようです。(なんで「True」だったり「はい」だったり一定しないんですかね?)

これはリンカそのものの機能ではなく MSBuild あるいはビルドツールの方の機能として実装されているようで、あくまでも同じソリューションに含まれるスタティックライブラリプロジェクトに対してのみ効果がありますす。単に .lib ファイルだけある場合には使えません。

2015の場合

2015 の場合、依存するスタティックライブラリごとに「ライブラリ依存関係の入力の使用」をオンオフすることができません。というか依存関係を設定するUI自体が各プロジェクトのプロパティの中には無く(「共通プロパティ」自体が無い)、プロジェクトのコンテキストメニューの「参照」から設定するように変わっています(この記事を書こうとして初めて気づいた)。全体に対して「ライブラリ依存関係の入力の使用」を設定することはできます。

代わりに、Update 2 で LINK コマンドに /WHOLEARCHIVE というそのものズバリなオプションが追加されました。挙動はは ld コマンドの --whole-archive と同様ですが、こちらはオプションに対してどのライブラリを対象にするか指定するようになっているので、オプションの順番を気にする必要はありません。

Trackback

no comment untill now

Add your comment now