Googletestをダウンロードし、CMakeでメイクファイルを生成してビルドしました。次に、テストプロジェクトで使用する必要があります。
CMakeでは、(_include _directories
_または_link_directories
_を使用して)gtestライブラリを直接指すのではなく、代わりにfind_package()
を使用することをお勧めします。
問題は、生成されたgtest makefileのインストールターゲットがないことです。 find_package(GTest REQUIRED)
が何らかのインストールなしでどのように機能するか理解できません。また、プロジェクトにgtestフォルダーをサブフォルダーとして配置することはできません。
助けてくれてありがとう。
これは異常なケースです。ほとんどのプロジェクトはインストールルールを指定します。
CMakeのExternalProject_Add
モジュールは、おそらくこの仕事に最適なツールです。これにより、プロジェクト内からgtestをダウンロード、構成、ビルドし、gtestライブラリにリンクできます。
WindowsでVisual Studio 10および11を使用し、GCC 4.8およびClang 3.2を使用してUbuntuで次のCMakeLists.txtをテストしました-他のプラットフォーム/コンパイラ用に調整する必要がある場合があります。
cmake_minimum_required(VERSION 2.8.7 FATAL_ERROR)
project(Test)
# Create main.cpp which uses gtest
file(WRITE src/main.cpp "#include \"gtest/gtest.h\"\n\n")
file(APPEND src/main.cpp "TEST(A, B) { SUCCEED(); }\n")
file(APPEND src/main.cpp "int main(int argc, char **argv) {\n")
file(APPEND src/main.cpp " testing::InitGoogleTest(&argc, argv);\n")
file(APPEND src/main.cpp " return RUN_ALL_TESTS();\n")
file(APPEND src/main.cpp "}\n")
# Create patch file for gtest with MSVC 2012
if(MSVC_VERSION EQUAL 1700)
file(WRITE gtest.patch "Index: cmake/internal_utils.cmake\n")
file(APPEND gtest.patch "===================================================================\n")
file(APPEND gtest.patch "--- cmake/internal_utils.cmake (revision 660)\n")
file(APPEND gtest.patch "+++ cmake/internal_utils.cmake (working copy)\n")
file(APPEND gtest.patch "@@ -66,6 +66,9 @@\n")
file(APPEND gtest.patch " # Resolved overload was found by argument-dependent lookup.\n")
file(APPEND gtest.patch " set(cxx_base_flags \"\${cxx_base_flags} -wd4675\")\n")
file(APPEND gtest.patch " endif()\n")
file(APPEND gtest.patch "+ if (MSVC_VERSION EQUAL 1700)\n")
file(APPEND gtest.patch "+ set(cxx_base_flags \"\${cxx_base_flags} -D_VARIADIC_MAX=10\")\n")
file(APPEND gtest.patch "+ endif ()\n")
file(APPEND gtest.patch " set(cxx_base_flags \"\${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32\")\n")
file(APPEND gtest.patch " set(cxx_base_flags \"\${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN\")\n")
file(APPEND gtest.patch " set(cxx_exception_flags \"-EHsc -D_HAS_EXCEPTIONS=1\")\n")
else()
file(WRITE gtest.patch "")
endif()
# Enable ExternalProject CMake module
include(ExternalProject)
# Set the build type if it isn't already
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
# Set default ExternalProject root directory
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/ThirdParty)
# Add gtest
ExternalProject_Add(
googletest
SVN_REPOSITORY http://googletest.googlecode.com/svn/trunk/
SVN_REVISION -r 660
TIMEOUT 10
PATCH_COMMAND svn patch ${CMAKE_SOURCE_DIR}/gtest.patch ${CMAKE_BINARY_DIR}/ThirdParty/src/googletest
# Force separate output paths for debug and release builds to allow easy
# identification of correct lib in subsequent TARGET_LINK_LIBRARIES commands
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs
-Dgtest_force_shared_crt=ON
# Disable install step
INSTALL_COMMAND ""
# Wrap download, configure and build steps in a script to log output
LOG_DOWNLOAD ON
LOG_CONFIGURE ON
LOG_BUILD ON)
# Specify include dir
ExternalProject_Get_Property(googletest source_dir)
include_directories(${source_dir}/include)
# Add compiler flag for MSVC 2012
if(MSVC_VERSION EQUAL 1700)
add_definitions(-D_VARIADIC_MAX=10)
endif()
# Add test executable target
add_executable(MainTest ${PROJECT_SOURCE_DIR}/src/main.cpp)
# Create dependency of MainTest on googletest
add_dependencies(MainTest googletest)
# Specify MainTest's link libraries
ExternalProject_Get_Property(googletest binary_dir)
if(MSVC)
set(Suffix ".lib")
else()
set(Suffix ".a")
set(Pthread "-pthread")
endif()
target_link_libraries(
MainTest
debug ${binary_dir}/DebugLibs/${CMAKE_FIND_LIBRARY_PREFIXES}gtest${Suffix}
optimized ${binary_dir}/ReleaseLibs/${CMAKE_FIND_LIBRARY_PREFIXES}gtest${Suffix}
${Pthread})
これをCMakeLists.txtとして空のディレクトリ(たとえばMyTest
)に作成すると、次のようになります。
cd MyTest
mkdir build
cd build
cmake ..
これにより、MyTest/src
に基本的なmain.cppが作成され、プロジェクトファイル(WindowsではMyTest/build/Test.sln
)が作成されます。
プロジェクトをビルドすると、gtestソースがMyTest/build/ThirdParty/src/googletest
にダウンロードされ、MyTest/build/ThirdParty/src/googletest-build
にビルドされます。その後、MainTestターゲットを正常に実行できるはずです。
元の質問が尋ねられるのはもう昔ですが、他の人のために、ExternalProject
を使用してgtestソースをダウンロードし、add_subdirectory()
を使用してビルドに追加することができます。これには次の利点があります。
通常の方法で使用すると、ExternalProjectは構成時(つまりCMakeの実行時)にダウンロードと解凍を行いませんが、そうすることはできます。これを行う方法に関するブログ記事を書きました。これには、gtestだけでなく、CMakeをビルドシステムとして使用する外部プロジェクトで機能する一般化された実装も含まれています。ここで見つけることができます:
https://crascit.com/2015/07/25/cmake-gtest/
更新:上記のアプローチは、現在も googletestドキュメントの一部 です。
私の答えは firegurafik からの答えに基づいています。次の方法で変更しました。
CMAKE_ARGS
呼び出しにExternalProject_Add
を追加して、msvcで動作するようにしました。INTERFACE_INCLUDE_DIRECTORIES
がまだ存在しない場合に、設定時にset_target_propertiesの呼び出しが機能しないという問題に対処しました。ソースを直接プロジェクトに追加するよりも、gtestを外部プロジェクトとして保持することを好みます。理由の1つは、コードを検索するときにgtestソースコードを含めるのが好きではないからです。 gtestのビルド時にも使用する必要がある私のコードに必要な特別なビルドフラグは、CMAKE_ARGS
の呼び出しでExternalProject_Add
の定義に追加できます。
ここに私の修正されたアプローチがあります:
include(ExternalProject)
# variables to help keep track of gtest paths
set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
set(GTEST_LOCATION "${GTEST_PREFIX}/src/GTestExternal-build")
set(GTEST_INCLUDES "${GTEST_PREFIX}/src/GTestExternal/include")
# external project download and build (no install for gtest)
ExternalProject_Add(GTestExternal
URL ${CMAKE_CURRENT_SOURCE_DIR}/../googletest
PREFIX "${GTEST_PREFIX}"
# cmake arguments
CMAKE_ARGS -Dgtest_force_shared_crt=ON
# Disable install step
INSTALL_COMMAND ""
# Wrap download, configure and build steps in a script to log output
LOG_DOWNLOAD ON
LOG_CONFIGURE ON
LOG_BUILD ON
)
# variables defining the import location properties for the generated gtest and
# gtestmain libraries
if (MSVC)
set(GTEST_IMPORTED_LOCATION
IMPORTED_LOCATION_DEBUG "${GTEST_LOCATION}/Debug/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}"
IMPORTED_LOCATION_RELEASE "${GTEST_LOCATION}/Release/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}"
)
set(GTESTMAIN_IMPORTED_LOCATION
IMPORTED_LOCATION_DEBUG "${GTEST_LOCATION}/Debug/${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}"
IMPORTED_LOCATION_RELEASE "${GTEST_LOCATION}/Release/${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}"
)
else()
set(GTEST_IMPORTED_LOCATION
IMPORTED_LOCATION "${GTEST_LOCATION}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(GTESTMAIN_IMPORTED_LOCATION
IMPORTED_LOCATION "${GTEST_LOCATION}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()
# the gtest include directory exists only after it is build, but it is used/needed
# for the set_target_properties call below, so make it to avoid an error
file(MAKE_DIRECTORY ${GTEST_INCLUDES})
# define imported library GTest
add_library(GTest IMPORTED STATIC GLOBAL)
set_target_properties(GTest PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDES}"
IMPORTED_LINK_INTERFACE_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}"
${GTEST_IMPORTED_LOCATION}
)
# define imported library GTestMain
add_library(GTestMain IMPORTED STATIC GLOBAL)
set_target_properties(GTestMain PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES GTest
${GTESTMAIN_IMPORTED_LOCATION}
)
# make GTest depend on GTestExternal
add_dependencies(GTest GTestExternal)
#
# My targets
#
project(test_pipeline)
add_executable(${PROJECT_NAME} test_pipeline.cpp)
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(${PROJECT_NAME} ${TBB_LIBRARIES})
target_link_libraries(${PROJECT_NAME} GTest)
ExternalProject
モジュールとcmake
のインポートされたライブラリ機能を使用して、少し複雑ではないソリューションがあります。リポジトリからコードをチェックアウトし、ビルドし、ビルドされた静的ライブラリからターゲットを作成します(私のシステムでは_libgtest.a
_と_libgtest_main.a
_です)。
_find_package(Threads REQUIRED)
include(ExternalProject)
set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
ExternalProject_Add(GTestExternal
SVN_REPOSITORY http://googletest.googlecode.com/svn/trunk
SVN_REVISION -r HEAD
TIMEOUT 10
PREFIX "${GTEST_PREFIX}"
INSTALL_COMMAND "")
set(LIBPREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
set(LIBSUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(GTEST_LOCATION "${GTEST_PREFIX}/src/GTestExternal-build")
set(GTEST_INCLUDES "${GTEST_PREFIX}/src/GTestExternal/include")
set(GTEST_LIBRARY "${GTEST_LOCATION}/${LIBPREFIX}gtest${LIBSUFFIX}")
set(GTEST_MAINLIB "${GTEST_LOCATION}/${LIBPREFIX}gtest_main${LIBSUFFIX}")
add_library(GTest IMPORTED STATIC GLOBAL)
set_target_properties(GTest PROPERTIES
IMPORTED_LOCATION "${GTEST_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDES}"
IMPORTED_LINK_INTERFACE_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
add_library(GTestMain IMPORTED STATIC GLOBAL)
set_target_properties(GTestMain PROPERTIES
IMPORTED_LOCATION "${GTEST_MAINLIB}"
IMPORTED_LINK_INTERFACE_LIBRARIES
"${GTEST_LIBRARY};${CMAKE_THREAD_LIBS_INIT}")
add_dependencies(GTest GTestExternal)
_
ここで_SVN_REVISION
_を置き換えるか、_LOG_CONFIGURE
_および_LOG_BUILD
_オプションを追加できます。 GTest
およびGTestMain
ターゲットを作成したら、次のように使用できます。
_add_executable(Test
test1.cc
test2.cc)
target_link_libraries(Test GTestMain)
_
または、独自のmain()
関数がある場合:
_add_executable(Test
main.cc
test1.cc
test2.cc)
target_link_libraries(Test GTest)
_
libgtest-dev
パッケージを取得すると
Sudo apt install libgtest-dev
ソースは/usr/src/googletest
の場所に保存されます
CMakeLists.txt
をそのディレクトリにポイントするだけで、必要な依存関係を見つけることができます
次のようなもの
add_subdirectory(/usr/src/googletest gtest)
target_link_libraries(your_executable gtest)