Cómo eliminar el duplicado de las mismas fonts de dependencies en proyectos dependientes

Tengo dos proyectos de cmake. Uno de ellos usa googletest y el segundo de ellos también lo usa. Además, utilicé el primer proyecto en el segundo proyecto.

Tengo un segundo proyecto en github y googletest también está en github. Así que quiero downloadlos cuando construyo mi primer proyecto usando

ExternalProject_Add

mando.


Esta es una estructura simplificada de carpetas:

ProjectA | build/ | include/ | src/ | modules/ | | ProjectB/ | | | CMakeLists.txt | | googletest/ | | | CMakeLists.txt | CMakeLists.txt 

Y estructura simplificada para ProjectB :

 ProjectB/ | build/ | include/ | src/ | modules/ | | googletest/ | | | CMakeLists.txt | CMakeLists.txt 

Y ahora tengo una pregunta importante: ¿es posible download el código googletest una vez? Por ahora lo descargo dos veces, una vez para ProjectA , y una segunda vez para ProjectB .

Puedo agregar el código simplificado CMakeLists.txt , pero no creo que sea necesario aquí.

Podría tratar googletest como un tercer proyecto externo y luego pasar su location a ambos proyectos como variables de caching CMake. Eso garantizaría que solo tuviera que download Googletest una vez, pero podría ser un poco less conveniente que tener Googletest construido directamente como parte de un proyecto. Podría crear un cuarto proyecto de nivel superior para reunir cada uno de los tres proyectos (googletest, projectA y projectB) para que pueda asegurarse de que googletest se construye antes de que necesite configurar projectA o projectB. ExternalProject para googletest instalaría los objectives gtest y gmock en su área de installation. A continuación, transfiere ese directory a ProjectA's y projectB's ExternalProjects como la location para search en google test. Puede usar el module FindGTest dentro de projectA y projectB para esto, teniendo su proyecto de nivel superior configurado la variable de caching GTEST_ROOT para projectA y projectB. Esta es probablemente la opción más fácil.

Otra opción sería download y comstackr googletest como parte de projectA (ver aquí el método que recomendaría para hacer esto), luego get projectB para reutilizar la fuente de googletest o, mejor aún, los objectives integrados de projectA. Podría traer projectA al projectB de la misma manera que el enlace anterior trae googletest en projectA si lo desea. Utilizamos un arreglo como este en el trabajo para reunir una serie de proyectos diferentes, cada uno de los cuales se puede build de forma independiente o como parte de otros proyectos. Una ventaja de este método es que si está utilizando un IDE como Visual Studio, Xcode o Qt Creator, puede ver las fonts de todos los proyectos en su list fuente y las herramientas de detección de problemas, refactorización, etc. del IDE tienden a tener una vista más completa de la construcción general. También tiende a minimizar la información que se debe pasar manualmente entre proyectos, ya que CMake ve el set completo de orígenes y destinos en la única compilation y, por lo tanto, no es necesario tratar explícitamente los nombres de las bibliotecas específicas de la plataforma, las diferentes estructuras de directory de salida de compilation , etc.

Si desea mantener projectA como un ExternalProject de projectB, entonces aún puede volver a utilizar la fuente de googletest de projectA, pero tendrá que configurar las dependencies entre los objectives muy cuidadosamente para asegurarse de que projectA se construya antes que cualquier cosa que necesite las fonts de googletest . Probablemente también tendrá que calcular manualmente dónde se descargan y se crean las cosas en el proyecto A, y eso podría ser un problema si su proyecto se basa en más de una plataforma. Parece que esto es lo más cercano a lo que está preguntando cómo hacer, pero probablemente sugeriría intentar uno de los dos enfoques anteriores.

Hay otras opciones, como usar un administrador de packages como cazador , pero eso puede estar alejándose demasiado del enfoque original de la pregunta.

Si no desea download el marco de testing de Google C ++ dos veces, puede simplemente usar el module de búsqueda adecuado de cmake y dejar que encuentre lo que necesita de su entorno.

Ver FindGTest .

Ejemplo de uso del enlace anterior:

 enable_testing() find_package(GTest REQUIRED) add_executable(foo foo.cc) target_link_libraries(foo GTest::GTest GTest::Main) add_test(AllTestsInFoo foo) 

Dicho esto, son diferentes proyectos con sus propios modules. Sería mejor ser explícito sobre ellos.
Todavía puede colocar un module de búsqueda de cmake personalizado en ProjectB que busque gtest dentro de ProjectA . De todos modos, es una solución frágil, ya que se interrumpirá tan pronto como cambien las dependencies en ProjectA .


Pregunta en los comentarios:

Parece realmente bueno para gtest, pero me pregunto si tengo proyectos diferentes a gtest (por ejemplo, ProjectC), ¿entonces qué debería hacer? Estoy buscando una solución más universal.

Si no puedo search dependencies en mi sistema a través de un module de búsqueda apropiado (junto con las versiones cuando sea necesario), generalmente prefiero ser explícito sobre ellas. Por lo tanto, agrego las dependencies requeridas a cada proyecto, incluso si esto significa recomstackrlos dos veces.
Una pregunta que puede responder a los por qué: ¿y si ProjectA depende de la label x para el module dado y ProjectB requiere que la label y funcione? Si las dos tags rompen la API de la otra (desafortunadamente a veces sucede), tendrá problemas a less que sea explícito sobre las dependencies para cada proyecto.