Ich verwende Google Mock für mein Projekt, und die Anweisungen sagen, es ist besser, die Bibliothek zusammen mit dem Projekt zu erstellen, da verschiedene Compiler-Flags Fehler verursachen können. Ich möchte das Verzeichnis gmock/nicht zu meinem Repository hinzufügen. Ich hätte lieber die Quellen als externe Abhängigkeit und stecke sie in meinen Build-Prozess. Das bringt mich zu meiner Frage: Wie kann ich CMake anweisen, das externe Quellverzeichnis in den Build zu ziehen (d. H. Es im Build-Verzeichnis meines Projekts zu erstellen)? Ich habe eine similar question hier gefunden, aber die Antworten erfordern eine starre Verzeichnisplatzierung, und ich würde eher konfigurierbar haben. Irgendeine andere Möglichkeit, es zu tun?Hinzufügen eines externen Quellverzeichnisses zu einem CMake-Build
Antwort
Ich sehe, dass Google Mock CMake unterstützt. In diesem Fall können Sie nur diese Zeile hinzufügen
add_subdirectory(${GOOGLE_MOCK_SOURCE_DIR})
in die Wurzel CMakeLists.txt
und lassen Sie Benutzer eingestellt GOOGLE_MOCK_SOURCE_DIR
Variable bei der Konfiguration Schritt:
set(GOOGLE_MOCK_SOURCE_DIR "" CACHE PATH "Path to the GMock source")
if(NOT ${GOOGLE_MOCK_SOURCE_DIR} OR NOT EXISTS "${GOOGLE_MOCK_SOURCE_DIR}/CMakeLists.txt")
message(FATAL_ERROR "GOOGLE_MOCK_SOURCE_DIR isn't set properly!")
endif()
Sie ExternalProject_Add
dafür verwenden könnten, da es Sie ermöglicht zum Download Konfigurieren Sie gmock in der Baumstruktur Ihres Projekts, und erstellen Sie sie, und verknüpfen Sie sie anschließend mit den gmock-Bibliotheken.
@ arrowdodgers answer ist wahrscheinlich der üblichere Weg, dies jedoch zu tun. Mit seiner Methode haben Sie normalerweise nicht die Gmock-Quellen in Ihrer Build-Struktur. Dies kann gut oder schlecht sein, je nachdem, was Sie wollen.
Mit ExternalProject_Add
werden die Gmock-Quellen jedes Mal, wenn Sie gmock oder ein abhängiges Ziel erstellen, abgerufen (svn update). Dies macht den Build etwas langsamer, aber hält die Quellen auf dem neuesten Stand und ist bequem (es ist eine Abhängigkeit weniger, um Entwickler zu installieren). Für ein Projekt wie gmock, das sich nicht oft ändert, ist der Aufwand für die Aktualisierung allzeit zu groß.
Die folgende CMakeLists.txt funktioniert mit Visual Studio 2010 & 2012 - es möglicherweise für andere Plattformen angepasst werden muss. Insbesondere kann gtest derzeit die Box nicht mit Visual Studio 2012 aufbauen (siehe bug report), daher die Patch-Datei und PATCH_COMMAND
im ExternalProject_Add
Aufruf.
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
project(Test)
# Create main.cpp which uses gmock
file(WRITE src/main.cpp "#include \"gmock/gmock.h\"\n\n")
file(APPEND src/main.cpp "struct A {\n virtual void Do() {}\n};\n\n")
file(APPEND src/main.cpp "struct MockA : public A {\n MOCK_METHOD0(Do, void());\n};\n\n")
file(APPEND src/main.cpp "TEST(A, Do) {\n")
file(APPEND src/main.cpp " MockA mock_a;\n")
file(APPEND src/main.cpp " EXPECT_CALL(mock_a, Do()).Times(testing::AtLeast(1));\n")
file(APPEND src/main.cpp " mock_a.Do();\n}\n\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 643)\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")
file(APPEND gtest.patch "Index: include/gtest/internal/gtest-tuple.h\n")
file(APPEND gtest.patch "===================================================================\n")
file(APPEND gtest.patch "--- include/gtest/internal/gtest-tuple.h (revision 643)\n")
file(APPEND gtest.patch "+++ include/gtest/internal/gtest-tuple.h (working copy)\n")
file(APPEND gtest.patch "@@ -1,3 +1,4 @@\n")
file(APPEND gtest.patch "+#include <tuple> /*\n")
file(APPEND gtest.patch " // This file was GENERATED by command:\n")
file(APPEND gtest.patch " // pump.py gtest-tuple.h.pump\n")
file(APPEND gtest.patch " // DO NOT EDIT BY HAND!!!\n")
file(APPEND gtest.patch "@@ -197,8 +198,8 @@\n")
file(APPEND gtest.patch " class tuple<> {\n")
file(APPEND gtest.patch " public:\n")
file(APPEND gtest.patch " tuple() {}\n")
file(APPEND gtest.patch "- tuple(const tuple& /* t */) {}\n")
file(APPEND gtest.patch "- tuple& operator=(const tuple& /* t */) { return *this; }\n")
file(APPEND gtest.patch "+ tuple(const tuple& t) {}\n")
file(APPEND gtest.patch "+ tuple& operator=(const tuple&) { return *this; }\n")
file(APPEND gtest.patch " };\n")
file(APPEND gtest.patch " \n")
file(APPEND gtest.patch " template <GTEST_1_TYPENAMES_(T)>\n")
file(APPEND gtest.patch "@@ -946,7 +947,7 @@\n")
file(APPEND gtest.patch " template <>\n")
file(APPEND gtest.patch " struct SameSizeTuplePrefixComparator<0, 0> {\n")
file(APPEND gtest.patch " template <class Tuple1, class Tuple2>\n")
file(APPEND gtest.patch "- static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {\n")
file(APPEND gtest.patch "+ static bool Eq(const Tuple1&, const Tuple2&) {\n")
file(APPEND gtest.patch " return true;\n")
file(APPEND gtest.patch " }\n")
file(APPEND gtest.patch " };\n")
else()
file(WRITE gtest.patch "")
endif()
# Enable ExternalProject CMake module
include(ExternalProject)
# Set default ExternalProject root directory
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/ThirdParty)
# Add gmock
ExternalProject_Add(
googlemock
SVN_REPOSITORY http://googlemock.googlecode.com/svn/trunk/
TIMEOUT 30
PATCH_COMMAND svn patch ${CMAKE_SOURCE_DIR}/gtest.patch ${CMAKE_BINARY_DIR}/ThirdParty/src/googlemock/gtest
# 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_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 for googlemock and googletest
ExternalProject_Get_Property(googlemock source_dir)
include_directories(${source_dir}/include)
include_directories(${source_dir}/gtest/include)
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 googlemock
add_dependencies(MainTest googlemock)
# Specify MainTest's link libraries
ExternalProject_Get_Property(googlemock binary_dir)
target_link_libraries(MainTest
debug ${binary_dir}/DebugLibs/${CMAKE_FIND_LIBRARY_PREFIXES}gmock${CMAKE_FIND_LIBRARY_SUFFIXES}
optimized ${binary_dir}/ReleaseLibs/${CMAKE_FIND_LIBRARY_PREFIXES}gmock${CMAKE_FIND_LIBRARY_SUFFIXES})
Wenn Sie dies als CMakeLists.txt in ein leeres Verzeichnis (zB MyTest) erstellen, dann:
cd MyTest
mkdir build
cd build
cmake ..
Dies sollte eine grundlegende main.cpp in MyTest/src erstellen und eine Projektdatei erstellen (MyTest/build/Test.sln unter Windows)
Wenn Sie das Projekt erstellen, sollte es die Gmock-Quellen in MyTest/build/ThirdParty/src/googlemock herunterladen und in MyTest/build/ThirdParty/src/erstellen. googlemock-build. Sie sollten dann in der Lage sein, das MainTest-Ziel erfolgreich auszuführen.
Für weitere Informationen über das ExternalProject_Add
Befehl finden this article entitled Building External Projects with CMake 2.8
a gist dieses CMakeLists.txt Ist hier enthalten
CMake ignoriert 'CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG' und' CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE' wenn es um den Aufbau von googlemock geht . Ich habe versucht, goglemocks CMakeLists.txt 'cmake_minimum_required' auf' cmake_minimum_required (VERSION 2.8.10) 'zu patchen. Es hat immer noch keinen Effekt. Ich denke nicht, dass es möglich ist, unterschiedliche Debug- und Release-/optimierte Builds von googletest oder googlemock zu haben. Entfernen Sie die 'debug' und' DebugLibs' Teile (und die ganze 'optimierte' Zeile) und dies wird erstellt. – gotgenes
Welche Plattform? Dies funktioniert wie oben mit separaten Ausgabeordnern unter Windows mit VC++ 2010 und mit VC++ 2012 mit einigen kleineren Patches, die zu gtest hinzugefügt wurden. – Fraser
Ich habe jetzt auch den Patch-Code für VC++ 2012 hinzugefügt. – Fraser
+1 Obwohl Sie noch ein paar 'include_directories' für' $ {GOOGLE_MOCK_SOURCE_DIR} Anrufe bräuchten/googlemock/include' und '$ {GOOGLE_MOCK_SOURCE_DIR}/googlemock/gtest/include' denke ich. – Fraser
Auch das "zieht das externe Quellverzeichnis nicht wirklich in den Build", aber das ist vielleicht nicht wichtig. – Fraser
Es wird nicht funktionieren, es sei denn, das Quellverzeichnis befindet sich in meiner Struktur (ist es nicht). Das ist das erste, was ich ausprobiert habe. :-) –