CMake:文件的解析顺序(缓存、工具链等)?
这似乎是一个无关紧要的问题,因为CMake是一种脚本语言,一般的答案是:严格顺序。但我遇到了几个案例,其中CMake解析某些文件的时间或顺序非常重要。所以我想知道:CMake:文件的解析顺序(缓存、工具链等)?,cmake,Cmake,这似乎是一个无关紧要的问题,因为CMake是一种脚本语言,一般的答案是:严格顺序。但我遇到了几个案例,其中CMake解析某些文件的时间或顺序非常重要。所以我想知道: 是否有文档描述了使用的顺序 是否解析文件(包括内部CMake文件) 文件顺序是否取决于CMake版本或某些CMake选项/设置/环境(包括所选的生成器或主机) 环境 到目前为止,我遇到的案例中,上述信息非常重要: 在识别编译器之前会解析工具链文件,因此必须首先在缓存中/在工具链文件中填充某些CMake变量: 工具链文件会被多次解析
- 在识别编译器之前会解析工具链文件,因此必须首先在缓存中/在工具链文件中填充某些CMake变量:
- 工具链文件会被多次解析,因此,例如,打印工具链文件中的消息会多次显示:
- 可以从主
文件已解析的范围之外的范围调用变量watch:CMakeLists.txt
cmake--trace…
来分析解析顺序
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)
然后,当我运行例如cmake--debug output--trace-g“Visual Studio 12 2013”-DCMAKE_TOOLCHAIN_FILE:FILE_PATH=TOOLCHAIN.txt时,我得到了一个很长的跟踪,我试图对其进行总结:
# 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
因此,看到上述结果,到目前为止,我得出了以下结论(我希望这些结论是正确的,并且有些通用):
CMAKECHACHE.txt文件仅在配置启动时读取一次,并在生成完成后写入。它只是保持“全局变量”缓存的状态
project()
工具链文件将被读取两次。一次在检测到生成/编译系统之前,一次在随后生成的CMakeSystem.cmake
中
变量_watch()
钩子可以随时触发,因此调用最佳“要执行的命令”的范围未定义
目前还没有关于CMake这个特殊内部工作的官方文档,所以请在下面找到我到目前为止对CMake的了解的摘要
解析哪些文件取决于
主机和目标操作系统
目标编译器
主机的环境(变量、注册表、已安装的软件)
项目的CMake脚本文件,其中可能包括
你的工具链文件
您选择的编程语言
任何外部项目/库/文件/脚本
这些参数有很多可能的组合,但大多数情况下,CMake会自动为您检测正确的设置,而您不需要担心如何完成。好消息是——当你需要知道的时候——它遵循某些固有的模式
有趣的是,它只在一定程度上取决于您选择的对象
初始步骤:编译器检测和验证
这主要从命令开始。以CXX
语言为例,编译器检测的主要文件有(另请参见问题跟踪输出中的根文件):
share/cmake-x.y/Modules/CMakeDetermineCXXCompiler.cmake
这基本上是试图确定编译器可执行文件的位置,并调用它以获得更具体的编译器id
此外,它还定义了基于主机环境和目标操作系统的源/输出文件扩展名
share/cmake-x.y/Modules/cmakecxcompiler.cmake.in
这是将编译器检测结果存储在${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/x.y.z/cmakecxcompiler.CMAKE
中的模板
这些变量主要是:,和CMAKE\u CXX\u COMPILER\u ENV\u VAR
share/cmake-x.y/Modules/CMakeCXXInformation.cmake
此文件设置编译器的基本标志。这也是编译器、主机和目标对设置影响最大的地方,调用如下:
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)
共享/cmake-x.y/Modules/cmaketestcxcompiler.cmake
这会测试所有内容,例如,通过在简单生成的CMake项目中实际调用编译器来确定编译器功能
这些步骤的结果存储在缓存的变量中,这些文件是特殊的,在这种情况下,它们由变量保护,例如,CMAKE\u CXX\u INFORMATION\u LOADED
或CMAKE\u CXX\u COMPILER\u工作
以避免在每个连续的CMAKE配置步骤中再次运行
项目配置文件:修改默认值
有几种方法可以更改CMake默认值,而无需实际接触项目的CMakeLists.txt
文件
- 命令行选项
如果您想通过多个项目反复给出一些预设值(通常通过
-D…
选项给出),可以使用此选项。例如计算机上的某些库搜索路径或公司中使用的某些预设
cmakcache.txt
通过例如
cmakegui
允许您在最终生成生成环境之前手动修改项目的选项(在CMakeCache.txt
中编辑所有非内部变量)
-
主要用于,但它可以更一般地描述为每个编译器工具链使用的预设值
预加载.cmake
与“初始缓存”选项(见上文)大致相同,但它是n
list(APPEND CMAKE_CXX_SOURCE_FILE_EXTENSIONS c)
> cmake -D CMAKE_USER_MAKE_RULES_OVERRIDE:PATH=..\MakeRulesOverwrite.cmake ..