CMake:检测python解释器和python库

news2024/9/27 21:28:39

CMake:检测python解释器和python库

  • 导言
  • 检测python解释器
    • CMakeLists.txt
    • 输出
    • 附录
  • 检测python库
    • 项目结构
    • CMakeLists.txt
    • 相关源码
    • 附录

导言

python是一种非常流行的语言。许多项目用python编写的工具,从而将主程序和库打包在一起,或者在配置或构建过程中使用python脚本。这种情况下,确保运行时对python解释器的依赖也需要得到满足。本篇将展示如何检测和使用python解释器。

除此之外,还有其他方法可以将解释语言(如python)与编译语言(如CC++)组合在一起使用。一种是扩展python,通过编译成共享库的CC++模块在这些类型上提供新类型和新功能。另一种是将python解释器嵌入到CC++程序中。两种方法都需要下列条件:

  • python解释器的工作版本
  • python头文件python.h的可用性
  • python运行时库libpython

检测python解释器

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter3/01

CMakeLists.txt

在这里插入图片描述

find_package(PythonInterp REQUIRED)

使用find_package命令找到python解释器。

find_package是用于发现和设置包的CMake模块的命令。这些模块包含CMake命令,用于标识系统标准位置中的包。CMake模块文件称为Find<name>.cmake,当调用find_package(<name>)时,模块中的命令将会运行。

除了在系统上实际查找包模块之外,查找模块还会设置了一些有用的变量,反映实际找到了什么,也可以在自己的CMakeLists.txt中使用这些变量。对于python解释器,相关模块为FindPythonInterp.cmake附带的设置了一些CMake变量:

  • PYTHONINTERP_FOUND:是否找到解释器
  • PYTHON_EXECUTABLEpython解释器到可执行文件的路径
  • PYTHON_VERSION_STRINGpython解释器的完整版本信息
  • PYTHON_VERSION_MAJORpython解释器的主要版本号
  • PYTHON_VERSION_MINORpython解释器的次要版本号
  • PYTHON_VERSION_PATCHpython解释器的补丁版本号

可以强制CMake,查找特定版本的包。例如,要求python解释器的版本大于或等于2.7find_package(PythonInterp 2.7)

CMake有很多查找软件包的模块。建议在CMake在线文档中查询Find<package>.cmake模块,并在使用它们之前详细阅读它们的文档。find_package命令的文档可以参考 :

https://cmake.org/cmake/help/v3.5/command/find_ackage.html

execute_process(
  COMMAND
      ${PYTHON_EXECUTABLE} "-c" "print('Hello, world!')"
  RESULT_VARIABLE _status
  OUTPUT_VARIABLE _hello_world
  ERROR_QUIET
  OUTPUT_STRIP_TRAILING_WHITESPACE
  )

执行python命令并捕获它的输出和返回值。

输出

-- Found PythonInterp: /usr/bin/python3.8 (found version "3.8.10") 
-- RESULT_VARIABLE is: 0
-- OUTPUT_VARIABLE is: Hello, python interpreter!
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jiangli/repo/tutorials/cmake-tutorial/chapter3/01/build

附录

软件包没有安装在标准位置时,CMake无法正确定位它们。用户可以使用-D参数传递相应的选项,告诉CMake查看特定的位置。python解释器可以使用以下配置:

$ cmake -D PYTHON_EXECUTABLE=/custom/location/python ..

这将指定非标准/custom/location/python安装目录中的python可执行文件。

注意:每个包都是不同的,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!"

检测python库

项目结构

.
├── CMakeLists.txt
└── hello_embedded_python.c

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter3/02

CMakeLists.txt

在这里插入图片描述
为了确保可执行文件、头文件和库都有一个匹配的版本。这对于不同版本,可能在运行时导致崩溃。通过FindPythonInterp.cmake中定义的PYTHON_VERSION_MAJORPYTHON_VERSION_MINOR来实现:

find_package(PythonInterp REQUIRED)
find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED)

可执行文件包含python.h头文件。因此,这个目标的include目录必须包含pythoninclude目录,可以通过PYTHON_INCLUDE_DIRS变量进行指定:

target_include_directories(hello_embedded_python
  PRIVATE ${PYTHON_INCLUDE_DIRS}
)

将可执行文件链接到python库,通过PYTHON_LIBRARIES变量访问:

target_link_libraries(hello_embedded_python
  PRIVATE ${PYTHON_LIBRARIES}
)

相关源码

在这里插入图片描述
此代码将在程序中初始化python解释器的实例,并使用pythonprint函数,打印字符串。

附录

python不在标准安装目录中,如何确定python头文件和库的位置是正确的?

对于python解释器,可以通过-D选项传递PYTHON_LIBRARYPYTHON_INCLUDE_DIR选项来强制CMake查找特定的目录。这些选项指定了以下内容:

  • PYTHON_LIBRARY:指向python库的路径
  • PYTHON_INCLUDE_DIRpython.h所在的路径

这样,就能获得所需的python版本。

注意:有时需要将-D PYTHON_EXECUTABLE-D PYTHON_LIBRARY-D PYTHON_INCLUDE_DIR传递给CMake CLI,以便找到及定位相应的版本的组件。

要将python解释器及其开发组件匹配为完全相同的版本可能非常困难,对于那些将它们安装在非标准位置或系统上安装了多个版本的情况尤其如此。CMake 3.12版本中增加了新的python检测模块,来解决这个问题。CMakeLists.txt的检测部分也将简化为:

find_package(Python COMPONENTS Interpreter Development REQUIRED)

最后:用积极的态度面对生活,正面面对生活中的任何人、事!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/838290.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业集团员工内部食堂餐厅食材预定订餐统计系统开发

内部食堂是针对员工食堂设计的预定系统 可以提前进行点餐,统计餐食人数 定量制作,避免浪费食材。 首页预定菜单提前显示一周菜单 用户可以提前预定想要购买的餐品 在用餐时取餐核销 食堂平台方用餐时对用户的菜品进行核销 通过后台预订信息 根据报餐统计做出对应数量…

Example: Beam Allocation in Multiuser Massive MIMO阅读笔记一

文章目录 A Machine Learning FrameworkApplication of Supervised Learning to Resource AllocationResearch Challenges and Open IssuesLow-Complexity ClassifierMulti-BS CooperationFast Evolution of Scenarios Conclusion A Machine Learning Framework 对于现有的云计…

python在函数中更改外部变量值

目录 前言 列表、字典&#xff08;可变对象&#xff09; 元组&#xff08;不可变对象&#xff09; 全局变量 前言 今天在写LeetCode题时&#xff0c;发现一个问题我并没有掌握&#xff0c;那就是如何在Python的函数中更改变量值&#xff08;包括列表&#xff0c;字典&…

C++ - 模板分离编译

模板分离编译 我们先来看一个问题&#xff0c;我们用 stack 容器的声明定义分离的例子来引出这个问题&#xff1a; // stack.h // stack.h #pragma once #include<deque>namespace My_stack {template<class T, class Container std::deque<T>>class stack…

Python 开发工具 Pycharm —— 使用技巧Lv.3

单步执行调试 1&#xff1a; 鼠标左键单击红点是断点行 2&#xff1a;甲虫样式是进行调试方式运行&#xff0c;鼠标左键单击点击 3&#xff1a; 单步运行图标&#xff0c;点击让程序运行一行 4&#xff1a; 步入步出&#xff0c;可以进入当前代码行函数内 5&#xff1a;重新运行…

JSON.stringify()与JSON.parse()没有你想的那样简单

重新学习这两个API的起因 在本周五有线上的项目&#xff0c;16:30开始验证线上环境。 开始都是顺顺利利&#xff0c;一帆风顺。 大概17:50左右&#xff0c;我正在收拾东西。 准备下班去王者峡谷骑着我的船溜达一圈。 可是天降意外&#xff0c;给我派了一个bug。 测试给我说&am…

山西电力市场日前价格预测【2023-08-06】

日前价格预测 预测明日&#xff08;2023-08-06&#xff09;山西电力市场全天平均日前电价为411.77元/MWh。其中&#xff0c;最高日前电价为457.52元/MWh&#xff0c;预计出现在19: 30。最低日前电价为370.37元/MWh&#xff0c;预计出现在13: 15。 价差方向预测 1&#xff1a; 实…

海外应用商店优化实用指南之关键词

和SEO一样&#xff0c;关键词是ASO中的一个重要因素。就像应用程序标题一样&#xff0c;在Apple App Store和Google Play中处理应用程序关键字的方式也有所不同。 关键词研究。 对于Apple&#xff0c;我们的所有关键词只能获得100个字符&#xff0c;Google Play没有特定的关键…

数据结构10 -查找_树表查找

创建二叉搜索树 二叉搜索树 二叉搜索树是有数值的了&#xff0c;二叉搜索树是一个有序树。 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它的根结点的值&#xff1b; 若它的右子树不空&#xff0c;则右子树上所有结点的值均大于它的根结点的值&#xff1b; 它…

47.Linux学习day01 基础命令详解1(很全面)

目录 一、Linux和Windows的区别 二、Linux系统目录结构 常见目录说明 三、Linux常见的基础命令 1.pwd 2.cd 3.ls 4.man 5. touch 6.mkdir 7. rmdir 今天正式学习了linux的一些基础操作和基础知识&#xff0c;以及linux和windows的区别。 一、Linux和Windows的区…

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接 背景目标依赖配置文件如下项目结构如下相关配置如下启动代码如下Controller如下启动成功接口调用成功 背景 工作做了一段时间&#xff0c;回忆起之前有个公司有线下笔试&#xff0c;要求考生做一个什么功能&#x…

建设全球研发中心城市,长沙与人才何以双向奔赴?

跨越山涧峡谷&#xff0c;需要搭建钢铁桥梁&#xff0c;跨越文化沟通&#xff0c;需要搭建互相理解的桥梁&#xff0c;那么&#xff0c;一座城市与人才之间的联系&#xff0c;应该搭建怎样的桥梁&#xff1f; 近日&#xff0c;长沙出台了重磅文件《中共长沙市委长沙市人民政府…

XSS漏洞原理及利用跨站请求伪造CSRF

XSS漏洞原理及利用&跨站请求伪造CSRF XSS一、案例二、什么是XSS三、XSS危害四、XSS的分类4.1、反射型XSS4.1.1、介绍4.1.2、利用过程 4.2、存储型XSS4.2.1、介绍4.2.2、利用过程4.2.3、案例 4.3、DOM型XSS4.3.1、介绍4.3.2、常用的DOM方法4.3.3、案例4.3.3.1、代码分析4.3.…

Spring源码之XML文件中Bean标签的解析1

读取XML文件&#xff0c;创建对象 xml文件里包含Bean的信息&#xff0c;为了避免多次IO&#xff0c;需要一次性读取xml文件中所有bean信息&#xff0c;加入到Spring工厂。 读取配置文件 new ClassPathResource("applicationContext.xml")ClassPathResource是Sprin…

vue动态生成行

vue代码 <el-table :data"form.lineInfos" :bordertrue style"width: 99.99%;"> <el-table-column type"index" label"序号" width"50"></el-table-column> <el-table-column prop"unitPrice&qu…

【Linux 网络】 传输层协议之TCP协议 TCP的三次握手和四次挥手

TCP协议 TCP协议段格式谈谈什么是 “可靠” 和 “不可靠”TCP协议段——序号与确认序号TCP协议段——窗口大小TCP协议段 —— 六个标志位确认应答机制&#xff08;ACK&#xff09;超时重传机制连接管理机制TCP 的三次握手四次挥手TCP三次握手四次挥手总结图 滑动窗口流量控制拥…

18. SpringBoot 如何在 POM 中引入本地 JAR 包

❤️ 个人主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;成功解决 BUG 合集 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; Spring Boot 是一种基于 Spring 框架的轻量级应用程序开发框架&#xff0c;它提供了快速开发应用程…

第126天:内网安全-隧道技术SSHDNSICMPSMB上线通讯LinuxMac

知识点 #知识点&#xff1a; 1、入站规则不出网上线方案 2、出站规则不出网上线方案 3、隧道技术-SMB&ICMP&DNS&SSH 4、控制上线-Linux&Mac&IOS&Android-连接方向&#xff1a;正向&反向&#xff08;基础课程有讲过&#xff09; -内网穿透&#xf…

vue2-vue项目中你是如何解决跨域的?

1、跨域是什么&#xff1f; 跨域本质是浏览器基于同源策略的一种安全手段。 同源策略&#xff08;sameoriginpolicy&#xff09;&#xff0c;是一种约定&#xff0c;它是浏览器最核心也是最基本的安全功能。 所谓同源&#xff08;即指在同一个域&#xff09;具有以下三个相同点…

Java对象的前世今生

文章目录 一、创建对象的步骤二、类加载机制三、内存分配指针碰撞 (内存连续)空闲列表 (内存不连续) 四、创建对象的5种方法五、浅拷贝与深拷贝 以下一行代码内部发生了什么&#xff1f; Person person new Person();一、创建对象的步骤 根据JLS中的规定&#xff0c;Java对象…