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
文件:
- 首先,定义 CMake 最低版本和项目名称。注意,这里不需要任何语言支持:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(recipe-01 LANGUAGES NONE)
- 然后,使用
find_package
命令找到 Python 解释器:find_package(PythonInterp REQUIRED)
- 然后,执行 Python 命令并捕获它的输出和返回值:
execute_process( COMMAND ${PYTHON_EXECUTABLE} "-c" "print('Hello, world!')" RESULT_VARIABLE _status OUTPUT_VARIABLE _hello_world ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE )
- 最后,打印 Python 命令的返回值和输出:
message(STATUS "RESULT_VARIABLE is: ${_status}") message(STATUS "OUTPUT_VARIABLE is: ${_hello_world}")
- 配置项目:
$ 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)
可以强制满足依赖关系:
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 解释器可以使用以下配置:
$ cmake -D PYTHON_EXECUTABLE=/custom/location/python ..
这将指定非标准 /custom/location/pytho
安装目录中的 Python 可执行文件。
NOTE : 每个包都是不同的, Find<package>.cmake
模块试图提供统一的检测接口。当 CMake 无法找到模块包时,我们建议您阅读相应检测模块的文档,以了解如何正确地使用 CMake 模块。可以在终端中直接浏览文档,本例中可使用 cmake --help-module FindPythonInterp
查看。
除了检测包之外,我们还想提到一个便于打印变量的 helper 模块。本示例中,我们使用了以下方法:
message(STATUS "RESULT_VARIABLE is: ${_status}") message(STATUS "OUTPUT_VARIABLE is: ${_hello_world}")
使用以下工具进行调试:
include(CMakePrintHelpers) cmake_print_variables(_status _hello_world)
将产生以下输出:
-- _status="0" ; _hello_world="Hello, world!"
有关打印属性和变量的更多信息,请参考 https://cmake.org/cmake/help/v3.5/module/CMakePrintHelpers.html 。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论