descarga - CMake: ¿En qué orden se analizan los archivos(caché, cadena de herramientas, etc.)?
cmake vs make (1)
No hay documentación oficial sobre este funcionamiento interno particular de CMake, por lo que encontrará a continuación un resumen de lo que he aprendido sobre CMake hasta ahora ...
Los archivos que se analizan dependen de
- El sistema operativo host y de destino
- El compilador objetivo
- El entorno de su computadora host (variables, registro, software instalado)
-
Los archivos de script CMake de su proyecto, que podrían incluir
- Su archivo de cadena de herramientas
- Los lenguajes de programación seleccionados.
- Cualquier proyecto externo / bibliotecas / archivos / scripts
Hay muchas combinaciones posibles de esos parámetros, pero la mayoría de las veces CMake hace toda la magia de detectar automáticamente la configuración correcta para usted y no necesita preocuparse por cómo se hace. La buena noticia es que, cuando necesita saberlo, sigue ciertos patrones intrínsecos.
Es interesante que solo depende marginalmente del generador CMake que esté seleccionando.
Paso inicial: detección y verificación del compilador
Esto comienza principalmente con el comando
project()
.
Tomando el lenguaje
CXX
como ejemplo, los archivos principales para la detección del compilador son (ver también los archivos raíz en la salida de rastreo de la pregunta):
-
share/cmake-xy/Modules/CMakeDetermineCXXCompiler.cmake
Básicamente, esto intenta determinar la ubicación del ejecutable del compilador y lo llama para obtener una identificación de compilador más específica.
Además, por ejemplo, define extensiones de archivo de origen / salida basadas en el entorno de la computadora host y el sistema operativo de destino.
-
share/cmake-xy/Modules/CMakeCXXCompiler.cmake.in
Esta es la plantilla para almacenar el resultado de la detección del compilador en
${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/xyz/CMakeCXXCompiler.cmake
.Principalmente esas variables son:
CMAKE_CXX_COMPILER
,CMAKE_CXX_SOURCE_FILE_EXTENSIONS
,CMAKE_CXX_IGNORE_EXTENSIONS
yCMAKE_CXX_COMPILER_ENV_VAR
-
share/cmake-xy/Modules/CMakeCXXInformation.cmake
Este archivo establece los indicadores básicos para el compilador. También es donde el compilador, el host y el destino tienen la mayor influencia en la configuración con llamadas como esta:
include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX OPTIONAL) include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL) include(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
-
share/cmake-xy/Modules/CMakeTestCXXCompiler.cmake
Esto prueba todo y, por ejemplo, determina las características del compilador al llamar al compilador en un simple proyecto CMake generado.
Los resultados de esos pasos se almacenan en variables almacenadas en caché y esos archivos son especiales en tal caso, ya que están protegidos por variables como
CMAKE_CXX_COMPILER_LOADED
,
CMAKE_CXX_INFORMATION_LOADED
o
CMAKE_CXX_COMPILER_WORKS
para que no se ejecuten con cada paso de configuración CMake consecutivo nuevamente.
Archivos de configuración del proyecto: modificar los valores predeterminados
Hay varias formas de cambiar los valores predeterminados de CMake sin tener que tocar los archivos
CMakeLists.txt
su proyecto.
-
Opción de línea de comando
-C <initial-cache>
Esto se puede usar si desea dar algunos valores preestablecidos (normalmente daría la opción
-D ...
) a través de varios proyectos una y otra vez. Al igual que algunas rutas de búsqueda de la biblioteca en su computadora o algunos ajustes preestablecidos utilizados en su empresa. -
CMakeCache.txt
través de, por ejemplo,cmake-gui
cmake-gui
permite modificar manualmente las opciones de su proyecto (editando todas las variables no internas enCMakeCache.txt
) antes de que finalmente genere el entorno de compilación. -
Se utiliza principalmente para cross-compiling , pero puede describirse más generalmente como valores preestablecidos por cadena de herramientas compiladora utilizada.
-
PreLoad.cmake
Más o menos lo mismo que la opción "caché inicial" (ver arriba), pero no se da a través de una opción de línea de comando. Solo tiene que estar en el mismo directorio que
CMakeLists.txt
su proyecto.Nota : Es compatible con todos los comandos de script CMake como
if()
llama, peroPreLoad.cmake
tiene su-
alcance variable propio (todo lo que no está en caché aquí no es visible en su
CMakeLists.txt
principal) -
limita lo que ya se sabe (se ejecuta antes que todo lo demás, por lo que en su mayoría puede verificar con
CMAKE_GENERATOR
)
-
alcance variable propio (todo lo que no está en caché aquí no es visible en su
-
CMAKE_USER_MAKE_RULES_OVERRIDE
,CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG>
Esto permite modificar los valores predeterminados no almacenados en caché después de la detección automática por CMake.
Example : extensión de las extensiones de archivo fuente CXX válidas mediante archivos
.c
MakeRulesOverwrite.cmake
list(APPEND CMAKE_CXX_SOURCE_FILE_EXTENSIONS c)
Entonces puedes llamar a
cmake
con algo como> cmake -D CMAKE_USER_MAKE_RULES_OVERRIDE:PATH=../MakeRulesOverwrite.cmake ..
-
CMAKE_PROJECT_ParserTest_INCLUDE
Esto está destinado a "inyectar código personalizado en las compilaciones del proyecto sin modificar su fuente" directamente después de que se procesó el comando
project()
(y se detectó el entorno de compilación).
Toolchain.cmake: Analizado varias veces
Un archivo de cadena de herramientas se lee varias veces al determinar el sistema, el compilador, etc.
Importante saber es:
-
Se lee con cada llamada
try_compile()
. Y dado que try compile debe producir un ejecutable válido, es posible que necesite, si está compilando, por ejemplo,-
CMAKE_TRY_COMPILE_TARGET_TYPE
aSTATIC_LIBRARY
(CMake versión 3.6 o superior) -
Verifique la propiedad global
IN_TRY_COMPILE
para agregar opciones adicionales
-
-
Si cambia su archivo de cadena de herramientas, CMake volverá a activar la detección del compilador (como en el seguimiento anterior). Lo que ayuda profundamente a jugar con la configuración de tu compilador.
Reconfiguraciones de CMake: todo proviene de la caché
Por último, pero no menos importante, es importante saber que la traza anterior solo muestra el paso inicial. Todas las configuraciones de proyecto consecutivas tomarán casi todo de las variables en caché y, por lo tanto, leerán mucho menos archivos en las ejecuciones de reconfiguración.
Referencias
Esto parece una pregunta trivial, ya que CMake es un lenguaje de script, la respuesta general es: estrictamente secuencial. Pero me encontré con varios casos en los que era importante cuándo o en qué orden CMake está analizando ciertos archivos. Entonces me pregunto:
- ¿Existe una documentación disponible que describa el orden en que se analizan los archivos (incluidos los archivos internos CMake)?
- ¿El orden de los archivos depende de la versión de CMake o de algunas opciones / configuraciones / entorno de CMake incl. El generador elegido o el entorno host?
Los casos que encontré hasta ahora, donde la información anterior era importante:
- El archivo de la cadena de herramientas se analiza antes de identificar el compilador, por lo que primero debe completar ciertas variables de CMake en la caché / en el archivo de la cadena de herramientas: la compilación cruzada de CMake con un enlazador específico no pasa argumentos a armlink
- El archivo de la cadena de herramientas se analiza varias veces, por lo tanto, por ejemplo, la impresión de mensajes del archivo de la cadena de herramientas se muestra varias veces: CMake toolchain incluye varios archivos
-
Se puede llamar a la vigilancia variable desde un ámbito fuera de su archivo
CMakeLists.txt
principalCMakeLists.txt
se ha analizado el comando o macro en CMake como el último paso antes de que finalice el paso ''configurar''
Tal vez sabes aún más.
Para encontrar una respuesta, he intentado lo siguiente: he configurado un CMakeLists.txt principal simple como se muestra a continuación y ejecuto
cmake --trace …
para analizar el orden de análisis.
cmake_minimum_required(VERSION 2.8)
include(BeforeProjectCmd.cmake)
project(ParserTest CXX)
add_subdirectory(LibTarget1)
add_subdirectory(LibTarget2)
add_executable(ExeTarget Test.cpp)
variable_watch(CMAKE_BACKWARDS_COMPATIBILITY)
Cuando ejecuto, por ejemplo,
cmake --debug-output --trace -G"Visual Studio 12 2013" -DCMAKE_TOOLCHAIN_FILE:FILE_PATH=Toolchain.txt
una larga traza que intenté resumir:
# Begin try to read
CMakeCache.txt
${CMAKE_BINARY_DIR}/CMakeCache.txt
PreLoad.cmake
${CMAKE_BINARY_DIR}/PreLoad.cmake
# End try to read
┌ CMakeLists.txt(1): cmake_minimum_required(VERSION 2.8 )
│ CMakeLists.txt(3): include(BeforeProjectCmd.cmake )
│
├─ BeforeProjectCmd.cmake
│
│ CMakeLists.txt(5): project(ParserTest CXX )
├┬ share/cmake-3.2/Modules/CMakeDetermineSystem.cmake
││
│└─ Toolchain.txt
│
├┬ ${CMAKE_PLATFORM_INFO_DIR}/CMakeSystem.cmake
││
│└─ Toolchain.txt
│
├─ share/cmake-3.2/Modules/CMakeSystemSpecificInitialize.cmake
├┬ share/cmake-3.2/Modules/CMakeDetermineCXXCompiler.cmake
│├┬ share/cmake-3.2/Modules/CMakeDetermineCompiler.cmake
││├ share/cmake-3.2/Modules/Platform/Windows-CXX.cmake
…
││├ share/cmake-3.2/Modules/CMakeDetermineCompilerId.cmake
││├─ share/cmake-3.2/Modules/CMakeCompilerIdDetection.cmake
…
││├ share/cmake-3.2/Modules/Compiler/MSVC-DetermineCompiler.cmake
…
│├ ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/3.2.2/CMakeCXXCompiler.cmake
│├ share/cmake-3.2/Modules/CMakeSystemSpecificInformation.cmake
│├┬ share/cmake-3.2/Modules/CMakeGenericSystem.cmake
││├ share/cmake-3.2/Modules/Platform/Windows.cmake
││└─ share/cmake-3.2/Modules/Platform/WindowsPaths.cmake
│├ share/cmake-3.2/Modules/CMakeCXXInformation.cmake
│├┬ share/cmake-3.2/Modules/Compiler/MSVC-CXX.cmake
││├ share/cmake-3.2/Modules/Platform/Windows-MSVC-CXX.cmake
││├┬ share/cmake-3.2/Modules/Platform/Windows-MSVC.cmake
│││└─ share/cmake-3.2/Modules/CMakeRCInformation.cmake
││└ share/cmake-3.2/Modules/CMakeCommonLanguageInclude.cmake
│├ share/cmake-3.2/Modules/CMakeTestCXXCompiler.cmake
│├┬ share/cmake-3.2/Modules/CMakeTestCompilerCommon.cmake
││├ share/cmake-3.2/Modules/CMakeDetermineCompilerABI.cmake
││├ share/cmake-3.2/Modules/CMakeDetermineCompileFeatures.cmake
││├ share/cmake-3.2/Modules/Internal/FeatureTesting.cmake
││└ share/cmake-3.2/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
│└ ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/3.2.2/CMakeCXXCompiler.cmake
│
│ CMakeLists.txt(7): add_subdirectory(LibTarget1 )
│
├─ LibTarget1/CMakeLists.txt
│
│ CMakeLists.txt(8): add_subdirectory(LibTarget2 )
│
├─ LibTarget2/CMakeLists.txt
│
│ CMakeLists.txt(10): add_executable(ExeTarget Test.cpp )
│ CMakeLists.txt(12): variable_watch(CMAKE_BACKWARDS_COMPATIBILITY )
│
│ CMake Debug Log in CMakeLists.txt:
│ Variable "CMAKE_BACKWARDS_COMPATIBILITY" was accessed using UNKNOWN_READ_ACCESS with value "".
-- Configuring done
-- Generating ${CMAKE_BINARY_DIR}
-- Generating ${CMAKE_BINARY_DIR}/LibTarget1
-- Generating ${CMAKE_BINARY_DIR}/LibTarget2
-- Generating done
# Writes
${CMAKE_BINARY_DIR}/CMakeCache.txt
Entonces, al ver el resultado anterior, llegué, hasta ahora, a la siguiente conclusión (que espero sea cierta y algo genérica):
- El archivo CMakeCache.txt solo se lee una vez cuando se inicia la configuración y se escribe una vez finalizada la generación. Simplemente persiste el estado de la caché de "variables globales".
-
El comando
project()
activa la mayor parte de la magia de detección de CMake (incluida la lectura del archivoToolchain.txt
). -
El archivo de la cadena de herramientas se lee dos veces.
Una vez antes de que se detecte el sistema de
CMakeSystem.cmake
/ compilación y una vez dentro delCMakeSystem.cmake
generado. -
El gancho
variable_watch()
puede activarse en cualquier momento, por lo que el alcance en el que se llama al "comando a ejecutar" óptimo no está definido.