这似乎是一个微不足道的问题,因为CMake是一种脚本语言,一般的答案是:严格顺序.但是我遇到了几个案例,其中重要的是CMake在何时或以何种顺序解析某些文件.所以我想知道:
到目前为止我遇到的案例,上述信息很重要:
CMakeLists.txt文件外部的作用域调用变量监视:在"配置"步骤完成之前,在CMake中执行命令或宏作为最后一步也许你知道更多.
为了找到答案,我尝试了以下内容:我已经设置了一个简单的主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)
Run Code Online (Sandbox Code Playgroud)
然后,当我运行时,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
Run Code Online (Sandbox Code Playgroud)
所以看到上面的输出,到目前为止,我得到了以下结论(我希望这是真的,有些通用):
project()命令触发了CMake的大部分检测魔法(包括从Toolchain.txt文件中读取).CMakeSystem.cmake.variable_watch()钩可以随时触发,所以在其中最优"命令来执行"被称为范围是未定义的.Flo*_*ian 18
关于CMake的这种特殊内部工作原理没有官方文档,所以请在下面找到我迄今为止所学到的关于CMake的内容的摘要......
解析的文件取决于
这些参数有很多可能的组合,但大多数情况下,CMake会为您自动检测正确的设置,并且您不必费心去做.好消息是 - 当你需要知道时 - 它遵循某些内在模式.
有趣的是,它只是略微取决于您选择的CMake生成器.
这主要从project()命令开始.以CXX语言为例,编译器检测的主要文件是(参见问题跟踪输出中的根文件):
share/cmake-x.y/Modules/CMakeDetermineCXXCompiler.cmake
这基本上试图确定编译器可执行文件的位置,并调用它来获取更具体的编译器ID.
此外,它例如基于主计算机环境和目标操作系统定义源/输出文件扩展名.
share/cmake-x.y/Modules/CMakeCXXCompiler.cmake.in
这是用于存储编译器检测结果的模板${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/x.y.z/CMakeCXXCompiler.cmake.
主要是那些变量是:CMAKE_CXX_COMPILER,CMAKE_CXX_SOURCE_FILE_EXTENSIONS,CMAKE_CXX_IGNORE_EXTENSIONS和CMAKE_CXX_COMPILER_ENV_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)
Run Code Online (Sandbox Code Playgroud)share/cmake-x.y/Modules/CMakeTestCXXCompiler.cmake
这会测试所有内容,例如通过在简单生成的CMake项目中实际调用编译器来确定编译器功能.
这些步骤的结果存储在缓存变量中,并且这些文件在这种情况下是特殊的,它们由变量保护CMAKE_CXX_COMPILER_LOADED,CMAKE_CXX_INFORMATION_LOADED或者CMAKE_CXX_COMPILER_WORKS不再与每个连续的CMake配置步骤一起运行.
有几种方法可以更改CMake默认值,而无需实际触摸项目的CMakeLists.txt文件.
-C <initial-cache> 命令行选项
如果您想要-D ...一次又一次地通过多个项目给出一些预设值(通常会通过选项提供),则可以使用此选项.就像您计算机上的某些库搜索路径或公司中使用的某些预设一样.
CMakeCache.txt 通过例如 cmake-gui
cmake-gui允许您CMakeCache.txt在最终生成构建环境之前手动修改项目的选项(编辑所有非内部变量).
主要用于交叉编译,但它通常可以描述为每个编译器工具链使用的预设值.
PreLoad.cmake
或多或少与"初始缓存"选项(见上文)相同,但它不是通过命令行选项提供的.它只需与您的项目位于同一目录中CMakeLists.txt.
注意:它支持所有CMake脚本命令,如if()调用,但PreLoad.cmake有它
CMakeLists.txt)CMAKE_GENERATOR)CMAKE_USER_MAKE_RULES_OVERRIDE, CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG>
这允许在CMake自动检测之后修改非限定的默认值.
示例:按.c文件扩展有效的CXX源文件扩展名
MakeRulesOverwrite.cmake
list(APPEND CMAKE_CXX_SOURCE_FILE_EXTENSIONS c)
Run Code Online (Sandbox Code Playgroud)
然后你可以cmake用类似的东西打电话
> cmake -D CMAKE_USER_MAKE_RULES_OVERRIDE:PATH=..\MakeRulesOverwrite.cmake ..
Run Code Online (Sandbox Code Playgroud)CMAKE_PROJECT_ParserTest_INCLUDE
这是为了project()在处理命令后直接"将自定义代码注入项目构建而不修改其源代码" (并检测到构建环境).
甲工具链文件被读出多个时间而确定系统,编译器,等
重要的是要知道:
每次try_compile()通话都会读到它.因为try compile必须生成一个有效的可执行文件,所以你可能需要 - 如果你是例如交叉编译 - 来
CMAKE_TRY_COMPILE_TARGET_TYPE至STATIC_LIBRARY(CMake版本3.6或以上)IN_TRY_COMPILE全局属性以添加其他选项如果更改工具链文件,CMake将重新触发编译器检测(如上面的跟踪).这对您的编译器设置有很大帮助.
最后但同样重要的是,重要的是要知道上面的跟踪仅显示了最初的步骤.所有连续的项目配置几乎都包含缓存变量,因此在重新配置运行中将读取更少的文件.
| 归档时间: |
|
| 查看次数: |
4767 次 |
| 最近记录: |