2014年1月10日金曜日

Google Test を -std=c++11 でビルドするとエラーになっていたので修正した

たまたま、-std=c++11 でビルドしたらエラーが出たので対処してみました。

環境
・cygwin
・gcc 4.8.2
・Google Test 1.7.0

エラー出力
$ make CXXFLAGS="-std=c++11 -Wall -Wextra"
g++ -isystem ../include -std=c++11 -Wall -Wextra -c ../samples/sample1_unittest.
cc
In file included from ../include/gtest/internal/gtest-internal.h:40:0,
                 from ../include/gtest/gtest.h:58,
                 from ../samples/sample1_unittest.cc:48:
../include/gtest/internal/gtest-port.h: 関数 ‘int testing::internal::posix::Fil
eNo(FILE*)’ 内:
../include/gtest/internal/gtest-port.h:1741:51: エラー: ‘fileno’ was not decla
red in this scope
 inline int FileNo(FILE* file) { return fileno(file); }
                                                   ^
../include/gtest/internal/gtest-port.h: 関数 ‘char* testing::internal::posix::S
trDup(const char*)’ 内:
../include/gtest/internal/gtest-port.h:1747:57: エラー: ‘strdup’ was not decla
red in this scope
 inline char* StrDup(const char* src) { return strdup(src); }
                                                         ^
../include/gtest/internal/gtest-port.h: 関数 ‘FILE* testing::internal::posix::F
DOpen(int, const char*)’ 内:
../include/gtest/internal/gtest-port.h:1779:71: エラー: ‘fdopen’ was not decla
red in this scope
 inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
                                                                       ^
Makefile:79: recipe for target 'sample1_unittest.o' failed
make: *** [sample1_unittest.o] Error 1

-std=c++11 を指定すると、__STRICT_ANSI__ が定義されるため、strdup などの宣言がされなくなるため、ビルドエラーになってしまうようです。
strdup などは、Google Test の実装で実際に利用しているので、ダミーの空関数にするわけにもいきません。
strdup ならまだ自前実装できそうですが、fdopen などは大変そうです。

なので、良い方法なのかはさておき以下のように修正することで対応しました。

include/gtest/internal/gtest-port.h
// Environment variable utilities:
//   GetEnv()             - gets the value of an environment variable.
//   BoolFromGTestEnv()   - parses a bool environment variable.
//   Int32FromGTestEnv()  - parses an Int32 environment variable.
//   StringFromGTestEnv() - parses a string environment variable.

/**** ここから ****/
#ifdef __STRICT_ANSI__ 
#  undef __STRICT_ANSI__ 
#  include <cstdio>
#  include <string.h>
#  include <stdlib.h>
#  define __STRICT_ANSI__
#endif
/**** ここまで ****/
#include <ctype.h>   // for isspace, etc
#include <stddef.h>  // for ptrdiff_t
#include <stdlib.h>

src/gtest-main.cc
/**** ここから ****/
#ifdef __STRICT_ANSI__ 
#  undef __STRICT_ANSI__ 
#  include <stdio.h>
#  define __STRICT_ANSI__
#endif
/**** ここまで ****/

#include "gtest/gtest.h"

GTEST_API_ int main(int argc, char **argv) {

__STRICT_ANSI__ が定義されていたら、undef して必要なヘッダーを include しています。
これで -std=c++11 でもビルドが通るようになりました。

とりあえず、動作もしました。
$ ./sample1_unittest.exe
Running main() from gtest_main.cc
[==========] Running 6 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 3 tests from FactorialTest
[ RUN      ] FactorialTest.Negative
[       OK ] FactorialTest.Negative (0 ms)
[ RUN      ] FactorialTest.Zero
[       OK ] FactorialTest.Zero (0 ms)
[ RUN      ] FactorialTest.Positive
[       OK ] FactorialTest.Positive (0 ms)
[----------] 3 tests from FactorialTest (3 ms total)

[----------] 3 tests from IsPrimeTest
[ RUN      ] IsPrimeTest.Negative
[       OK ] IsPrimeTest.Negative (0 ms)
[ RUN      ] IsPrimeTest.Trivial
[       OK ] IsPrimeTest.Trivial (0 ms)
[ RUN      ] IsPrimeTest.Positive
[       OK ] IsPrimeTest.Positive (0 ms)
[----------] 3 tests from IsPrimeTest (11 ms total)

[----------] Global test environment tear-down
[==========] 6 tests from 2 test cases ran. (25 ms total)
[  PASSED  ] 6 tests.


github: https://github.com/srz-zumix/gtest_patch

0 件のコメント:

コメントを投稿