Home > Article > Backend Development > Introduction to Nuitka: A better way to compile and distribute Python
Translator | Li Rui
Reviewer | Sun Shujuan
As Python becomes more and more popular, its limitations become more and more obvious. On the one hand, writing Python applications and distributing them to people who don't have Python installed can be very difficult.
The most common way to solve this problem is to package the program with all its supporting libraries and files and the Python runtime. There are tools that can do this, such as PyInstaller, but they require a lot of caching to work properly. What's more, it's often possible to extract the source code of a Python program from the generated package. In some cases, this can be a deal breaker.
Third-party project Nuitka offers a radical solution. It compiles a Python program into a C binary - not by packaging the CPython runtime with the program bytecode, but by translating Python instructions into C. The results can be distributed in a compressed package or packaged into an installer with other third-party products.
Nuitka also tries to maintain maximum compatibility with the Python ecosystem, so third-party libraries such as NumPy can work reliably. Nuitka also makes performance improvements to compiled Python programs wherever possible, but again without sacrificing overall compatibility. Speedups are not guaranteed, so they vary widely between workloads, and some programs may not experience any significant performance improvements. In general, it's best not to rely on Nuitka for performance, but as a bundled solution.
Nuitka can be used with Python 2.6 to 2.7 and Python 3.3 to 3.10. It can compile binaries for Microsoft Windows, macOS, Linux and FreeBSD/NetBSD. It's important to note that developers must build the binaries on the target platform; cross-compiling is not possible.
For each platform, in addition to the Python runtime, a C compiler is also required. On Microsoft Windows, Visual Studio 2022 or higher is recommended, but MinGW-w64 C11 (gcc 11.2 or higher) can also be used. For other platforms, you can use gcc 5.1 or higher, g 4.4 or higher, clang or clang cl on Windows under Visual Studio.
It is important to note that if using Python 3.3 or Python 3.4, Python 2.7 will be required due to tool dependencies. All of these should be reasons to use the latest version of Python if you can.
It is best to install Nuitka in a virtual environment along with the project as a development dependency rather than a distribution dependency. Nuitka itself is not bundled with or used by projects; it performs bundling.
After installing Nuitka, use Nuitka or python-m nuitka to call it.
The first thing developers want to do with Nuitka is to verify that the entire tool chain is working properly, including the C compiler. To test this, you can compile a simple "Hello world" Python program, name it main.py:
print ("Hello world")
When compiling a Python program using Nuitka, change the entry point module The name is passed to Nuitka as a parameter, for example Nuitka main.py. When called like this, Nuitka will receive main.py and build an executable from it.
It should be noted that because it is only testing the functionality of Nuitka, it will only compile the Python file into an executable file. It does not compile anything else, nor does it bundle anything for redistribution. But compiling a file should be enough to determine if Nuitka's toolchain is set up correctly.
After compilation is completed, you should see the binary executable file located in the same directory as the Python program. Run the executable to make sure it works properly.
It is also possible to automatically run Nuitka-compiled applications by passing --run as a command line flag.
If the "Hello world" test executable is valid, you can try to package it as a redistributable file. This process is explained below.
It is important to note that when running the first test compilation using Nuitka, it may take a few seconds to complete. And this only compiles one module, not the entire program. Compiling a complete program with Nuitka can take several minutes or longer, depending on the number of modules used by the program.
By default, Nuitka only compiles specified modules. If the module has imports from elsewhere in the program, from the standard library, or from third-party packages, you need to specify that these imports should also be compiled.
Consider a modified "Hello world" program with an adjacent module named greet.py:
def greet(name): print ("Hello ", name)
and a modified main.py:
import greet greet.greet("world")
To compile these two modules, you can use the --follow-imports switch:
nuitka --follow-imports main.py
This switch ensures that the entire program requires All imports are tracked from the import statement and compiled together.
Another option --nofollow-import-to allows to exclude specific subdirectories from the import process. This option is useful for filtering out test suites or modules that you know have never been used. It also allows wildcards to be provided as parameters.
图1.使用Nuitka编译大型复杂程序。这个示例涉及编译Pyglet模块以及标准库中的许多模块,这需要几分钟的时间
(1)包括动态导入
现在出现了Python用户在尝试打包Python应用程序以进行分发时经常遇到的问题之一。--follow-imports选项仅遵循通过import语句在代码中显式声明的导入。它不处理动态导入。
为了解决这个问题,可以使用--include-plugin-directory开关为动态导入的模块提供一个或多个路径。例如,对于包含动态导入代码的名为mods的目录,可以使用:
nuitka--follow-imports--include-plugin-directory=modsmain.py
(2)包括数据文件和目录
如果Python程序使用在运行时加载的数据文件,Nuitka也无法自动检测这些文件。要将单个文件和目录包含在Nuitka打包程序中,可能使用--include-data-files和--include-data-dir。
--include-data-files允许为要复制的文件指定通配符以及要将它们复制到的位置。例如,--include-data dir=/path/to/data=data会将/path.to/data中的所有内容复制到分发目录中的匹配目录数据。
-include-data-dir的工作方式大致相同,只是它不使用通配符;它只允许传递要复制的路径和要将其复制到的分发文件夹中的目标。例如,--include-data dir=/path/to/data=data会将/path.to/data中的所有内容复制到分发目录中的匹配目录数据。
(3)包括Python包和模块
指定导入的另一种方法是使用Python样式的包命名空间而不是文件路径,使用--include-package选项。例如,以下命令将包括mypackage,它在磁盘上的任何位置(假设Python可以找到它),以及它下面的所有内容:
nuitka --include-package=mypackage main.py
如果包需要自己的数据文件,可以使用--include-package-data选项包含这些文件:
nuitka --include-package=mypackage --include-package-data=mypackage main.py
该命令告诉Nuitka获取包目录中实际上不是代码的所有文件。
如果只想包含单个模块,可以使用--include-module:
nuitka --include-module=mypackage.mymodule main.py
该命令告诉Nuitka只包含mypackage.mymodule,而不包含其他内容。
当想用Nuitka编译Python程序以进行重新分发时,可以使用命令行开关--standalone来处理大部分工作。此开关自动跟随所有导入并生成一个dist文件夹,其中包含已编译的可执行文件和所需的任何支持文件。要重新分发程序,只需要复制此目录即可。
不要指望--standalone的程序在第一次运行时就可以工作。Python程序的一般动态性几乎保证了需要使用上述其他一些选项来确保编译的程序正常运行。例如,如果有一个需要特定字体的GUI应用程序,可能必须使用--include-data-files或--include-data-dir将它们复制到发行版中。
此外,如上所述,--standalone应用程序的编译时间可能比测试编译长得多。一旦对测试独立构建的应用程序需要多长时间有所了解,就为测试独立构建的应用程序所需的构建时间进行预算。
最后,Nuitka提供了另一个构建选项--onefile。对于那些熟悉PyInstaller的人来说,--onefile的工作方式与该程序中的相同选项相同:它将整个应用程序(包括其所有依赖文件)压缩为单个可执行文件,无需重新分发其他文件。但是,重要的是要知道--onefile在Linux和Microsoft Windows上的工作方式不同。在Linux上,它使用存档的内容安装一个虚拟文件系统。在Windows上,它会将文件解压缩到一个临时目录中并从那里运行它们,它必须为程序的每次运行执行这一操作。在Windows上使用--onefile可能会显著降低启动程序所需的时间。
原文标题:Intro to Nuitka: A better way to compile and distribute Python,作者:Serdar Yegulalp
The above is the detailed content of Introduction to Nuitka: A better way to compile and distribute Python. For more information, please follow other related articles on the PHP Chinese website!