当前位置: 首页 > news >正文

gcc配合cython编译python源代码

以前我们一般用Nuitka或者Pyinstaller来将python源码编译成二进制可执行文件。今天我们学习如何直接用gcc来编译。

很简单的一个python程序,结构如下。包含一个model.py和main.py
在这里插入图片描述

步骤1:处理main.py

处理main.py。即主程序入口

cython -D -2 --embed main.py
gcc -c -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o main.o main.c
gcc -I/usr/include/python2.7 -o main main.o -lpython2.7

这三行命令用于将一个 Python 脚本 (main.py) 编译成一个可执行的 C 程序,使用了 Cython 工具。下面逐行解释每个命令的作用:

1. cython -D -2 --embed main.py

  • cython: Cython 是一个编译器,可以将 Python 代码转换为 C 代码,以提高性能。
  • -D: 这个选项启用调试信息,方便调试生成的 C 代码。
  • -2: 表示使用 Python 2 语法来编译。如果你的代码是用 Python 3 编写的,可以将其改为 -3
  • –embed: 这个选项指示 Cython 生成一个可以作为嵌入式 Python 解释器的 C 程序的主函数。生成的 main.c 文件将包含一个 main() 函数,使其可以直接运行。
  • main.py: 这是要编译的 Python 脚本的名称。

2. gcc -c -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o main.o main.c

  • gcc: GNU C 编译器,用于编译 C 代码。
  • -c: 这个选项指示 GCC 只编译源文件,而不进行链接操作。它会生成一个目标文件(.o 文件)。
  • -fPIC: 生成位置无关代码(Position Independent Code),通常用于共享库。
  • -fwrapv: 使编译器在处理整数溢出时遵循 Python 的行为。
  • -O2: 启用优化级别 2,以提高生成代码的性能。
  • -Wall: 启用所有警告信息,帮助发现潜在问题。
  • -fno-strict-aliasing: 禁用严格别名规则,避免可能的未定义行为。
  • -I/usr/include/python2.7: 指定 Python 头文件的路径,以便编译器能够找到 Python 的 C API。
  • -o main.o: 指定生成的目标文件的名称为 main.o
  • main.c: 这是之前由 Cython 生成的 C 源文件。

3. gcc -I/usr/include/python2.7 -o main main.o -lpython2.7

  • gcc: 再次调用 GNU C 编译器。
  • -I/usr/include/python2.7: 同样指定 Python 头文件的路径,以便链接时找到 Python C API。
  • -o main: 指定生成的可执行文件的名称为 main
  • main.o: 指定要链接的目标文件。
  • -lpython2.7: 链接 Python 2.7 的共享库,使生成的可执行文件能够调用 Python 的函数和对象。

总结

这三行命令的整体作用是将一个 Python 脚本编译为一个 C 程序,并生成可执行文件 main。首先,使用 Cython 将 Python 代码转换为 C 代码,然后编译该 C 代码为目标文件,最后链接目标文件生成可执行程序。这样可以提高执行效率,并允许在 C 程序中嵌入 Python 解释器。

步骤2: 处理model.py

处理model.py。因为它不是程序的入口,所以我们将它编译成动态链接库

cython -D -2 model.py
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o model.so model.c

这两句命令用于将一个 Python 脚本 (model.py) 编译成一个共享库(.so 文件),使用 Cython 进行转换。下面逐句分析每个命令的作用:

1. cython -D -2 model.py

  • cython: Cython 是一个将 Python 代码转换为 C 代码的编译器,能够提高 Python 代码的执行效率。
  • -D: 启用调试信息,生成的 C 代码会包含调试符号,有助于调试。
  • -2: 指定使用 Python 2 的语法。如果您的代码是用 Python 3 编写的,可以将其改为 -3
  • model.py: 这是要编译的 Python 脚本的名称。运行此命令后,Cython 会生成一个名为 model.c 的 C 源文件。

2. gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o model.so model.c

  • gcc: GNU C 编译器,用于编译 C 代码。
  • -shared: 创建一个共享库,而不是一个可执行文件。这个选项会生成 .so 文件,允许其他程序使用这个库。
  • -pthread: 启用 POSIX 线程支持,允许在共享库中使用多线程功能。
  • -fPIC: 生成位置无关代码(Position Independent Code),适用于共享库的创建。
  • -fwrapv: 使编译器在处理整数溢出时遵循 Python 的行为。
  • -O2: 启用优化级别 2,以提高生成的代码性能。
  • -Wall: 启用所有警告信息,有助于发现潜在问题。
  • -fno-strict-aliasing: 禁用严格别名规则,以避免可能导致未定义行为的情况。
  • -I/usr/include/python2.7: 指定 Python 头文件的路径,以便编译器能够找到 Python 的 C API。
  • -o model.so: 指定生成的共享库的名称为 model.so
  • model.c: 这是由 Cython 生成的 C 源文件,包含了 model.py 的实现。

总结

这两句命令的整体作用是将一个 Python 脚本编译为一个共享库 (model.so),以便可以在其他 C/C++ 程序中调用其中的 Python 函数和对象。首先,使用 Cython 将 Python 代码转换为 C 代码,然后使用 GCC 编译该 C 代码生成共享库,提供给其他程序使用。

步骤3:验证

编译后的目录如下
在这里插入图片描述
其实现在我们只需要main和model.so这两个文件即可,效果如下。即现在已经不再需要依赖python源文件了。
在这里插入图片描述


http://www.mrgr.cn/news/31504.html

相关文章:

  • QTCreator 调试:unknown debugger type “No engine“
  • C++11——lambda
  • 伊犁-linux root 密码忘记咋办
  • LDD学习2--Scull(TODO)
  • JAIN SLEE 中Container Managed Persistent (CMP)
  • 第一百零三周周报
  • 人工智能与量子计算:进展与未来挑战
  • SharePoint Online Plan 2 部署方案
  • Codeforces Round 973 (Div. 2) F1. Game in Tree (Easy Version)(思维题 博弈)
  • 目标检测中的非极大值抑制(NMS):步骤与Python实现
  • Pybullet 安装过程
  • 无人机视角电力巡检资产检测与异常判别数据集
  • C++11——function与bind
  • QTableWidget的setRowCount
  • 【ShuQiHere】 探索 IEEE 754 浮点数标准:以 57.625 和 -57.625 为例
  • JVM基础
  • 【有啥问啥】OpenAI o1的思考之前训练扩展定律、后训练扩展定律与推理扩展定律:原理与应用详解
  • 基于Python与K-Means的自动化视频分类方法
  • 举例说明偏差的计算方式和在计算协方差中的作用
  • 欠款管理代码———未来之窗行业应用跨平台架构