2011-03-03 10 views
13

たとえばBoostで。私はディレクトリをMSVC++ 2010のBoostルートディレクトリに設定し、ソースコードに#include <boost/regex.hpp>を設定しました。どのような.libにどの関数が含まれているかをC++リンカーがどのように知っていますか?

 
libboost_regex-vc100-s-1_46.lib 
libboost_regex-vc100-mt-gd-1_46.lib 
libboost_regex-vc100-mt-1_46.lib 
libboost_regex-vc100-mt-s-1_46.lib 
libboost_regex-vc100-mt-s.lib 
libboost_regex-vc100-s.lib 
libboost_regex-vc100-mt.lib 
libboost_regex-vc100-mt-gd.lib

どうMSVCは、右のすべてのlibファイルのどの知っているん:ブーストのために、各Boostライブラリのためのいくつかのこれらの::正規表現を - 私はboost\stage\libライブラリディレクトリを設定しますが、ファイルの数百人がそこにあります1?それが正しい関数シグネチャをすべてスキャンした場合、同じ名前とパラメータを持つ関数を定義する2つの異なるソース(互いにリンクされていない)からコンパイルされた2つの異なるライブラリが1つのlibフォルダに存在しないことを意味しますか?

そして、どのようにそれらの正規表現.libの中で正しいことが分かっていますか?そして、ファイル名に1_46の各ファイルはそれぞれのファイルと同じではないようですが、2つのうちの1つを安全に削除できますか?

+3

'regex.hpp'を見れば、何十個もの' #pragma library'ステートメントが見つかるでしょう。(正確な構文は忘れてしまいます) –

答えて

16

ブーストライブラリでは、ヘッダとコンパイラオプションからリンクするライブラリを選択するために、ダークマジックを使用します。私は本当に詳細を知っているわけではありませんが、追加情報としてboost/config/auto_link.hppヘッダーを見ることができます。特に

、これはパズルの重要な部分であるように思わ:

# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") 
+1

うーん、いいね。私はなぜ彼らが名前に "アドレスタイプ"(32/64ビット)を含めないのか疑問に思うだけです。両方のバージョンでモジュールをコンパイルすることは、ライブラリパスをデフォルト(boost \ stage \ lib)にすることができないため、手作業で行われます。 –

2

同じ機能を含む2つのライブラリは問題ありません。リンカーは、見るように指示されたライブラリだけを見ます。 のうち2つがの場合、エラーメッセージが表示されます(これは、通常、標準ライブラリとの静的リンクと動的リンクの競合が原因で、かなり一般的です)。

リンカには、リンカのコマンドライン(IDEによって生成される可能性があります)と、#pragma comment(lib, "libname.lib")を介して、多くの方法で見られるライブラリが最も一般的です。

+0

Jerryはほぼ真実です。 2つのライブラリに2つの同じ名前の関数を持たせることは完全に有効です。両方のライブラリはリンクされています。私はこれをmallocの独自の実装を自由にするためにこれを行います...しかし、(大きなですが)ライブラリ内の2番目の定義からのすべての外部シンボル。リンカがシンボル名を解決すると、シンボルの2回目の出現を探しません。 – Patrick

4

ほとんどlibファイルは、目次を持っています。リンカーはシンボルを検索しているときにこのテーブルを検索します。シンボルが見つからない場合は、次のライブラリに移動します。以下同様に、すべてのライブラリが検索されます。

一部のリンカーは、すべてのライブラリから目次を作成することを決定する場合があります。このテーブルには、シンボル名とそれが関連付けられているライブラリが含まれます。これにより、シンボルの検索が高速化されます。

検索順序は、リンカーの製造元によって異なります。これには標準も要件もありません。リンカーは、先にで検索し、最初にコマンドラインで指定された通りを提供します。 最終ライブラリ指定またはその他の方法。ドキュメントの条件を確認してください。

name manglingも検索してください。これは、コンパイラがシンボル命名の競合を解決するために使用する手法です。

最後に、1つだけが使用されていても、リンカーはライブラリ内のすべての機能を含むことがあります。一部のリンカーには、その関数のコードしか含まれていません。リンカの製造元によって異なります。たとえば、putsを解決するときにリンカにI/Oライブラリ全体が含まれているか、必要な機能だけが含まれていますか?ライブラリ全体を含めるとビルド時間は短縮されますが、実行ファイルは膨大になります。必要なコードのみを含めると、ビルドプロセスは遅くなりますが、実行可能ファイルのサイズは縮小されます。

一般に、リンクフェーズは、翻訳プロセスの中で高速な部分の1つです。ビルド時間を心配している場合は、その日の終わりにビルドを開始するか、ビルドを開始してから散歩に行くようにしてください。 ;-)

+0

これはリンカーの一般的な動作を説明していますが、質問には答えません。 Boostはプログラマが指定しなくてもright_libファイルとマジックリンクしますが、どうすればいいですか? – bjhend

関連する問題