忍者ブログ
プログラミングとか日常とかの覚書っぽいなにか
[40] [39] [38] [37] [36] [35] [34]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

DLL版のC/C++ランタイムライブラリ(CRT)を使用したGoogle Testを使ったときに、テストコードビルド時のリンクエラー「エントリー ポイントを定義しなければなりません。」を解消するのに以外と手間取ったので、メモ代わりの記事です。

Google Testに含まれるWindows Visual Studio向けのソリューションファイルおよびプロジェクトファイル(msvcフォルダ配下にある「gtest.sln」とそれに含まれるプロジェクトファイル)は、既定ではランタイムライブラリオプションが「/MT」、すなわちスタティックリンクされるCRT(C/C++ランタイムライブラリ)を使用するように設定されています。

今回、外部のライブラリを使用してのテストコードを書くため、DLL版CRTを使用したGoogle Testのライブラリが必要となりました。

幸い、Google Testにはすでにそのためのソリューションファイルおよびプロジェクトファイル(msvcフォルダ配下にある「gtest-md.sln」とそれに含まれるプロジェクトファイル)が存在するので、それをビルドしてライブラリ「gtest.lib」「gtest_main-md.lib」を作成。これはあっさり完了。(手持ちの環境がVS2010なのでプロジェクトファイルの変換ウィザードが最初に実行されましたが、そこは既定のままの処理を実行しました。)

次にテストコード側のビルド設定の変更。

普段、テストコードは先にmakefileを作っておいて、コマンドプロンプト上で
> nmake && test
と打ち込んでテストを実行することが多いので、makefileを書き換えることになりました。

普段のスタティックリンクCRT版のGoogle Testを使う時のmakefileがだいたい以下のようなもの。
TARGET = test.exe
OBJECTS = test.obj

GTEST_ROOT = D:\gtest
GTEST_INCLUDE = $(GTEST_ROOT)\include
GTEST_LIB = $(GTEST_ROOT)\msvc\gtest\Release

CPPFLAGS = /nologo /MT /EHsc /c /I"$(GTEST_INCLUDE)"
LINKFLAGS = /nologo /out:$(TARGET) /LIBPATH:"$(GTEST_LIB)"

LIBS = gtest_main.lib gtest.lib

CC = @cl.exe
LK = @link.exe
RM = @del

all : $(TARGET)

$(TARGET): $(OBJECTS)
	$(LK) $(LIBS) $(OBJECTS) $(LINKFLAGS)

.cpp.obj:
	$(CC) $(CPPFLAGS) $>

clean:
	$(RM) *.obj *.pdb $(TARGET).pdb $(TARGET).exe

rebuild: clean all

今回はDLL版CRTを使うようにするため、
  • コンパイルオプション「/MT」→「/MD」
  • リンク対象libファイル「gtest_main.lib」→「gtest_main-md.lib」
  • libファイル検索パス「msvc\gtest\Release」→「msvc\gtest-md\Release」
という変更を加えました。(余談ですが、gtest.libの方には「-md」が付加されるようにはなっていないんですよね。なぜかしら。)

TARGET = test.exe
OBJECTS = test.obj

GTEST_ROOT = D:\gtest
GTEST_INCLUDE = $(GTEST_ROOT)\include
GTEST_LIB = $(GTEST_ROOT)\msvc\gtest-md\Release

CPPFLAGS = /nologo /MD /EHsc /c /I"$(GTEST_INCLUDE)"
LINKFLAGS = /nologo /out:$(TARGET) /LIBPATH:"$(GTEST_LIB)"

LIBS = gtest_main-md.lib gtest.lib

CC = @cl.exe
LK = @link.exe
RM = @del

all : $(TARGET)

$(TARGET): $(OBJECTS)
	$(LK) $(LIBS) $(OBJECTS) $(LINKFLAGS)

.cpp.obj:
	$(CC) $(CPPFLAGS) $<

clean:
	$(RM) *.obj *.pdb $(TARGET).pdb $(TARGET).exe

rebuild: clean all

さてこれでビルドしてみると、あら不思議。スタティックリンクCRTバージョンでは発生しなかった以下のリンクエラーが発生するようになってしまいました。
LINK : fatal error LNK1561: エントリー ポイントを定義しなければなりません。
これが言ってるのは、つまるところ「main がいねえ!」ってことですよね。
しかし、main関数は gtest_main-md.lib の中に入っているはず。元となるソースを見ても確かに書かれています。

試行錯誤したり、検索したりで以下のページを発見。

http://www.dreamincode.net/forums/topic/179230-fatal-error-lnk1561-entry-point-must-be-defined/

ここにあるやり取りから、リンカオプションに /SUBSYSTEM:CONSOLE を追加すればよいということが判明した次第でした。

それにしても、リンカは /SUBSYSTEM オプションなしの場合は、シンボル「main」または「wmain」が存在する場合は CONSOLE が、「WinMain」または「wWinMain」が存在する場合は WINDOWS がデフォルトで採用されることになっていたはずなんですが、それが .lib に含まれる場合にはまた動作が異なるということなんでしょうかね。しかも「/MT」の場合と「/MD」の場合でさらに動作が違うという…やれやれです。

拍手

PR

コメント


コメントフォーム
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字


忍者ブログ [PR]
プロフィール
HN:
はむぱい
職業:
ソフト作ったりしてる人
Twitter
最新CM
[06/09 replica rolex oyster perpetual datejust]
[06/09 bracelets imitation cartier love]
[06/09 replica the oyster perpetual datejust]
[06/09 datejust rolex oyster perpetual]
[06/09 replica gold love bangle]
カレンダー
11 2017/12 01
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
ブログ内検索
あ~いい漢字