ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# 3.1 检测Python解释器 **NOTE**:*此示例代码可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-03/recipe-01 中找到。该示例在CMake 3.5版(或更高版本)中是有效的,并且已经在GNU/Linux、macOS和Windows上进行过测试。* Python是一种非常流行的语言。许多项目用Python编写的工具,从而将主程序和库打包在一起,或者在配置或构建过程中使用Python脚本。这种情况下,确保运行时对Python解释器的依赖也需要得到满足。本示例将展示如何检测和使用Python解释器。 我们将介绍`find_package`命令,这个命令将贯穿本章。 ## 具体实施 我们将逐步建立`CMakeLists.txt`文件: 1. 首先,定义CMake最低版本和项目名称。注意,这里不需要任何语言支持: ```cmake cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(recipe-01 LANGUAGES NONE) ``` 2. 然后,使用`find_package`命令找到Python解释器: ```cmake find_package(PythonInterp REQUIRED) ``` 3. 然后,执行Python命令并捕获它的输出和返回值: ```cmake execute_process( COMMAND ${PYTHON_EXECUTABLE} "-c" "print('Hello, world!')" RESULT_VARIABLE _status OUTPUT_VARIABLE _hello_world ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) ``` 4. 最后,打印Python命令的返回值和输出: ```cmake message(STATUS "RESULT_VARIABLE is: ${_status}") message(STATUS "OUTPUT_VARIABLE is: ${_hello_world}") ``` 5. 配置项目: ```shell $ mkdir -p build $ cd build $ cmake .. -- Found PythonInterp: /usr/bin/python (found version "3.6.5") -- RESULT_VARIABLE is: 0 -- OUTPUT_VARIABLE is: Hello, world! -- Configuring done -- Generating done -- Build files have been written to: /home/user/cmake-cookbook/chapter-03/recipe-01/example/build ``` ## 工作原理 `find_package`是用于发现和设置包的CMake模块的命令。这些模块包含CMake命令,用于标识系统标准位置中的包。CMake模块文件称为` Find<name>.cmake`,当调用`find_package(<name>)`时,模块中的命令将会运行。 除了在系统上实际查找包模块之外,查找模块还会设置了一些有用的变量,反映实际找到了什么,也可以在自己的`CMakeLists.txt`中使用这些变量。对于Python解释器,相关模块为`FindPythonInterp.cmake`附带的设置了一些CMake变量: * **PYTHONINTERP_FOUND**:是否找到解释器 * **PYTHON_EXECUTABLE**:Python解释器到可执行文件的路径 * **PYTHON_VERSION_STRING**:Python解释器的完整版本信息 * **PYTHON_VERSION_MAJOR**:Python解释器的主要版本号 * **PYTHON_VERSION_MINOR** :Python解释器的次要版本号 * **PYTHON_VERSION_PATCH**:Python解释器的补丁版本号 可以强制CMake,查找特定版本的包。例如,要求Python解释器的版本大于或等于2.7:`find_package(PythonInterp 2.7)` 可以强制满足依赖关系: ```cmake find_package(PythonInterp REQUIRED) ``` 如果在查找位置中没有找到适合Python解释器的可执行文件,CMake将中止配置。 **TIPS**:*CMake有很多查找软件包的模块。我们建议在CMake在线文档中查询`Find<package>.cmake`模块,并在使用它们之前详细阅读它们的文档。`find_package`命令的文档可以参考 https://cmake.org/cmake/help/v3.5/command/find_ackage.html 。在线文档的一个很好的替代方法是浏览 https://github.com/Kitware/CMake/tree/master/Modules 中的CMake模块源代码——它们记录了模块使用的变量,以及模块可以在`CMakeLists.txt`中使用的变量。* ## 更多信息 软件包没有安装在标准位置时,CMake无法正确定位它们。用户可以使用CLI的`-D`参数传递相应的选项,告诉CMake查看特定的位置。Python解释器可以使用以下配置: ```shell $ cmake -D PYTHON_EXECUTABLE=/custom/location/python .. ``` 这将指定非标准`/custom/location/python`安装目录中的Python可执行文件。 **NOTE**:*每个包都是不同的,`Find<package>.cmake`模块试图提供统一的检测接口。当CMake无法找到模块包时,我们建议您阅读相应检测模块的文档,以了解如何正确地使用CMake模块。可以在终端中直接浏览文档,本例中可使用`cmake --help-module FindPythonInterp`查看。* 除了检测包之外,我们还想提到一个便于打印变量的helper模块。本示例中,我们使用了以下方法: ```cmake message(STATUS "RESULT_VARIABLE is: ${_status}") message(STATUS "OUTPUT_VARIABLE is: ${_hello_world}") ``` 使用以下工具进行调试: ```cmake include(CMakePrintHelpers) cmake_print_variables(_status _hello_world) ``` 将产生以下输出: ```shell -- _status="0" ; _hello_world="Hello, world!" ``` 有关打印属性和变量的更多信息,请参考 https://cmake.org/cmake/help/v3.5/module/CMakePrintHelpers.html 。