Estoy usando Google Mock para mi proyecto, y las instrucciones dicen que es mejor construir la biblioteca junto con el proyecto, porque diferentes indicadores de compilación pueden presentar errores. No quiero agregar el directorio gmock/a mi repositorio; Prefiero tener las fuentes como una dependencia externa y conectarlo a mi proceso de compilación. Lo que me lleva a mi pregunta: ¿cómo puedo instruir a CMake para que extraiga el directorio fuente externo en la compilación (es decir, compilarlo en el directorio de compilación de mi proyecto)? Encontré un similar question aquí, pero las respuestas requieren una ubicación de directorio rígida, y prefiero tener ese configurable. ¿Alguna otra forma de hacerlo?Agregue un directorio fuente externo a una compilación de CMake
Respuesta
Veo que Google Mock es compatible con CMake. En este caso sólo se puede añadir esta línea
add_subdirectory(${GOOGLE_MOCK_SOURCE_DIR})
en la raíz CMakeLists.txt
y dejar que el usuario establece GOOGLE_MOCK_SOURCE_DIR
variable durante la etapa de configuración:
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()
usted podría utilizar ExternalProject_Add
para esto, ya que le permite descargar , configure y cree gmock desde el árbol de compilación de su proyecto, y luego vincule a las bibliotecas de gmock.
@ arrowdodger's answer es probablemente la forma más habitual de hacerlo. Usando su método, normalmente no tienes las fuentes de gmock en tu árbol de compilación. Esto podría ser bueno o malo dependiendo de lo que quieras.
Utilizando ExternalProject_Add
, las fuentes de gmock se extraen (actualización svn) cada vez que se crea gmock o un objetivo dependiente. Esto hace que la compilación sea un poco más lenta, pero claramente mantiene las fuentes actualizadas y es conveniente (es una dependencia menos para que los desarrolladores se instalen). Para un proyecto como gmock que no cambia a menudo, la sobrecarga de actualizar todo el tiempo puede ser demasiado para ti.
El siguiente CMakeLists.txt funciona con Visual Studio 2010 & 2012 - puede ser necesario ajustarlo para otras plataformas. En particular, gtest actualmente no puede construir el cuadro utilizando Visual Studio 2012 (consulte este bug report), de ahí el archivo de parche y PATCH_COMMAND
en la llamada ExternalProject_Add
.
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})
Si crea esto como CMakeLists.txt en un directorio vacío (por ejemplo MyTest), entonces:
cd MyTest
mkdir build
cd build
cmake ..
Esto debe crear un main.cpp básica en MyTest/src y crear un archivo de proyecto (MyTest/build/Test.sln en Windows)
Al compilar el proyecto, debe descargar las fuentes de gmock a MyTest/build/ThirdParty/src/googlemock y compilarlas en MyTest/build/ThirdParty/src/googlemock-build. Entonces debería poder ejecutar el objetivo MainTest con éxito.
Para más información sobre el comando ExternalProject_Add
, ver this article entitled Building External Projects with CMake 2.8
Aquí está a gist que contiene este CMakeLists.txt
CMake ignora 'CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG' y' CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE' cuando va a compilar googlemock . He intentado parchear googleack's CMakeLists.txt 'cmake_minimum_required' a' cmake_minimum_required (VERSIÓN 2.8.10) '. Todavía no tiene efecto. No creo que sea posible tener distintas depuraciones y versiones optimizadas de googletest o googlemock. Elimine las porciones 'debug' y' DebugLibs' (y toda la línea 'optimizada') y esto se compilará. – gotgenes
¿Qué plataforma? Esto funciona como anteriormente con carpetas de salida separadas en Windows con VC++ 2010 y con VC++ 2012 con un par de parches menores agregados a gtest. – Fraser
He agregado el código de parche para VC++ 2012 ahora también. – Fraser
- 1. Cmake: directorio de compilación en incluir ruta
- 2. gcov con CMake utilizando un directorio de compilación independiente
- 3. Agregar fuente en un subdirectorio a un proyecto de cmake
- 4. Agregue permanentemente un directorio a PYTHONPATH
- 5. Agregue el archivo de compilación generado a classpath
- 6. Compilación de CMake Multiarchitecture
- 7. Cmake error de compilación
- 8. ¿Cómo generar un encabezado en la fuente con cmake?
- 9. cmake: estadísticas de compilación
- 10. Compilación de fuente a fuente con LLVM
- 11. ¿Puede CMake generar scripts de compilación que * no * usan cmake?
- 12. Incluir archivo MAKE externo con CMake
- 13. Adjuntar fuente a un contenedor externo en un proyecto de eclipse de android
- 14. Configuraciones de compilación CMake Eclipse
- 15. ¿Cómo soluciono una compilación CMake aparentemente corrupta?
- 16. Agregue una fuente personalizada en Qt
- 17. C++ CMake (agregue archivos no construidos)
- 18. Compilación para iOS con CMake
- 19. cmake, imprime comandos de compilación/enlace
- 20. Agregue la imagen destacada de wordpress a la fuente RSS
- 21. Agregue más de un directorio de recursos al embarcadero
- 22. Cabal: dir de compilación con fuente
- 23. ¿Cómo incluir todos los archivos de un directorio con cmake?
- 24. Agregue la fuente .otf a la aplicación iphone
- 25. Agregue color de fuente css con jquery
- 26. Compilación LaTex fuente babero
- 27. CMake add_custom_command/_target en diferentes directorios para la compilación cruzada
- 28. Python, agregue una barra inclinada a una cadena de directorio, os independientemente
- 29. Xcode 4 proyecto de compilación externo y depuración
- 30. Cómo recolectar archivos fuente con CMake sin englobar?
1 Aunque todavía se necesitaría un par de '' include_directories' pide $ {} GOOGLE_MOCK_SOURCE_DIR/googlemock/include' y '$ {GOOGLE_MOCK_SOURCE_DIR}/googlemock/gtest/include', creo. – Fraser
Además, esto realmente no "lleva el directorio de origen externo a la compilación", pero eso quizás no sea importante. – Fraser
No funcionará, a menos que el directorio fuente esté dentro de mi árbol (no lo es). Eso es lo primero que intenté. :-) –