2

Visual Studio C ++ 2008 Expressの使用:

次のようにコンパイルされたビルドで最後のリンクステップを実行しようとしています。

  • ライブラリfoo.libは、スイッチを使用して静的にコンパイルされます(ビルドはを生成しません.dll/MD。のビルドはfoo.lib成功します。ファイルとヘッダーは.lib、以下のライブラリのプロジェクトがそれらを見つけることができるディレクトリに出荷されます。foo.libソースはアンマネージC++で記述されています。

  • ライブラリは、スイッチbar.dllを備えたダイナミックライブラリとしてコンパイルされます。エクスポートされたシンボルに依存します。とは両方とも、VS2008Expressツールチェーンの同じバイナリとバイナリを使用してソースから構築されます。ソースはアンマネージC++で記述されています。/MD /LDbar.dllfoo.libbar.dllfoo.libcl.exelink.exebar.dll

  • ビルドのすべての.objファイルはbar.dll正常にビルドされますが、それを最後に実行link.exeするとbar.dll、未定義の外部ファイルに関する何千ものエラーが発生します。LNK2001未定義の外観はすべて、標準C ++ライブラリにあると私が期待するものです。std::basic_stringコンストラクター、std::_Throwクラス、ostreamオーバーロードされた演算子などです。未定義の外観は!内で未定義でlink.exeあると言いますfoo.lib

  • 目標は、bar.dll静的にリンクされたコード全体foo.libとそれ自体のオブジェクトを含めることですが、実行時の存在/解決に動的に依存MSVCR90.dllMSVCP90.dllます。

このビルドで不可能な状況を設定しようとしていますか、それとも単に何か間違ったことをしていますか?これが理論的にまったく機能しない場合は、私に知らせてください。foo.libそれ以外の場合は、最後のリンク手順でC++ライブラリシンボルを使用できない理由を特定するためにどのような診断を試みることができるかを教えてください。

編集:より具体的な情報:LLVM 3.1でありfoo.lib、ブランチからのMesaの()ビルドです(目標はで実行されるものを生成することです)。次のように、すべてのビルド依存関係を満たしました。bar.dlllibgl-gdillvmpipemasteropengl32.dllllvmpipe

  • LLVMビルドは、ビルドシステムとしてのCMakeとPython2.7に依存しています。
  • Mesaビルドは、ビルドシステムとしてSCons、LLVM 2.6以降、Python 2.7、pywin32、python-libxml2、bison、およびflexに依存しています。上記のうち、実行時にLLVMのみが出荷されます。残りは、ビルドプロセス中に使用される単なる「ツール」です。

また、プロジェクトごとにビルドをカスタマイズして、環境変数を設定し、スイッチのみを一貫して使用し/MD/MT間違ったCランタイムライブラリを選択するために他のスイッチを使用しないようにしました。

4

3 に答える 3

1

MSDNヘルプから:

ランタイムルーチンのマルチスレッド固有バージョンとDLL固有バージョンの両方が標準の.hファイルから選択されるように、_MT_DLLを定義します。このオプションにより、コンパイラーはライブラリー名MSVCRT.libを.objファイルに配置します。このオプションでコンパイルされたアプリケーションは、MSVCRT.libに静的にリンクされます。このライブラリは、リンカが外部参照を解決できるようにするコードのレイヤーを提供します。実際に機能するコードはMSVCR71.DLLに含まれており、実行時にMSVCRT.libにリンクされたアプリケーションで使用できる必要があります。

/ MDを_STATIC_CPPLIB定義(/ D_STATIC_CPPLIB)で使用すると、アプリケーションは動的バージョン(msvcprt.lib)ではなく静的マルチスレッド標準C ++ライブラリ(libcpmt.lib)にリンクしますが、それでもメインCRTに動的にリンクします。 msvcrt.lib。

より具体的には、この抜粋:「このオプションでコンパイルされたアプリケーションは、MSVCRT.libに静的にリンクされています

言い換えれば、foo.libをmsvcrt.libにリンクする必要があります。

于 2012-08-03T19:10:56.260 に答える
0

これは、ビジュアルスタジオプロジェクトとの混同の一般的なポイントです。

/MDは静的ライブラリを構築しません。これは、Visual Studio(lib、dll、exe)からの任意のバイナリ出力で使用できるフラグです。これは、静的CRT(Cランタイム)を使用するようにバイナリに指示していることを意味します。これは、一般的なケースでは間違った選択であり、CRTを静的にリンクしないアプリケーションまたはDLLにリンクするときにリンクの問題が発生します(ダイナミックCRTを使用)。

詳細については、こちらをご覧ください。

http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=vs.71).aspx

[構成プロパティ]/[一般]/[構成タイプ]のプロジェクト設定の下に設定があるはずです。これは、作成しているバイナリの種類を判別するために使用しているものである必要があります

于 2012-08-03T19:10:36.367 に答える
0

これがあなたがやろうとしていることをする実用的なサンプルです。

foo.h:

#ifndef FOO_H
#define FOO_H

extern void print_foo();

#endif

foo.cpp:

#include "foo.h"

#include <iostream>

void print_foo() {
  std::cout << "foo" << std::endl;
}

動的ランタイムライブラリに依存する静的ライブラリにfoo.cppをビルドします。

cl /c /MD /EHsc foo.cpp
lib foo.obj

bar.h:

#ifndef BAR_H
#define BAR_H

#ifdef BAR_DLL
#define BARAPI __declspec(dllexport)
#else
#define BARAPI __declspec(dllimport)
#endif

BARAPI void print_bar();

#endif

bar.cpp:

#include "bar.h"

#include <iostream>
#include "foo.h"

BARAPI void print_bar() {
  std::cout << "bar" << std::endl;
  print_foo();
}

bar.cppを、foo.libからコードをプルし、ダイナミックランタイムライブラリに依存するDLLにビルドします。

cl /c /MD /EHsc /DBAR_DLL bar.cpp
link /DLL bar.obj foo.lib

そして、それが機能することを示すための単純なmain.cpp:

#include "bar.h"

int main() {
  print_bar();
  return 0;
}

次のように作成します。

cl /c /MD /EHsc main.cpp
link main.obj bar.lib

(/ MDオプションは動的ランタイムライブラリを必要とするものとしてオブジェクトファイルにタグを付けているはずなので、ランタイムライブラリは自動的に入るはずです。)

main.exe出力:

bar
foo
于 2012-08-03T20:59:16.427 に答える