Bootstrap

Nuitka打包python为.exe时遇到的坑

一、知乎入坑

写了一个小程序需要打包成exe,试了pyinstaller,打包出来超过1G,看知乎上Nuitka效果很好,决定尝试一下。
作者在使用时设定了非常多的限制条件,比如要用不带Anaconda、多个python版本的电脑,甚至还用上了虚拟机。
我是有Anaconda,决定尝试一下。

二、创建python≤3.8版本虚拟环境

因为Anaconda自带的base虚拟环境中python版本3.10,于是在Anaconda Prompt下面使用:

conda create -n gui python==3.7

创建一个名叫gui的虚拟环境,至于为什么python版本这么低,原因参看链接中Requirements部分

三、安装Nuitka所需的C编译器——Mingw64

这里下载MinGW64,然后选择与Python匹配的64位或32位,一般选择x86_64-win32-sjlj。将其安装到C:\MinGW64或\MinGW64(与Nuitka运行相同的磁盘根目录)以自动找到它。具体安装步骤参考这里第1-3步

四、安装Nuitka

进入Anaconda Prompt里面,激活之前的虚拟环境:

conda activate gui

然后,再安装,如下三选一

pip install nuitka
# 或者
python -m pip install nuitka
# 或者
conda install -c conda-forge nuitka

五、创建一个hello.py程序

import time
def job():
    print("hello")


if __name__ == "__main__":
    while True:
        job()
        time.sleep(1)

加个延时是为了后面显示需要,我看很多示例程序都是只用一句print,打包好程序exe,点击运行一下就退出,根本看不到输出信息。

六、打包

利用Anaconda Prompt激活虚拟环境,切换到py程序所在文件夹,然后

nuitka --mingw64 --show-progress --show-scons hello.py

标题七、遇到的坑

第一个坑:

ModuleNotFoundError("No module named 'colorama'").

解决办法:
激活虚拟环境,pip install colorama

第二个坑:

Nuitka-Scons:INFO: CC 'C:\\mingw64\\bin\\gcc.exe' version check gives (8, 1, 0)
Nuitka-Scons:INFO: Initial CC: 'gcc'
Nuitka-Scons:INFO: Initial CCVERSION: (8, 1, 0)
Nuitka-Scons:INFO: Checking usability of 'C:\\mingw64\\bin\\gcc.exe' from 'gcc'
Nuitka-Scons:INFO: Too old gcc 'C:\\mingw64\\bin\\gcc.exe' ((8, 1, 0) < (11, 2)) ignored!
Nuitka-Scons:INFO: No usable C compiler, attempt fallback to winlibs gcc.

解决办法:
这个可以查看虚拟环境文件夹下/Lib/site-packages/nuitka/build/SconsCompilerSettings.py,其中checkWindowsCompilerFound函数说明Remove compiler of wrong arch or too old gcc and replace with downloaded winlibs gcc,移除旧的gcc编译器(在mingw64/bin下面的gcc.exe),下载winlibs gcc编译器,但是我下载半天都没下载下来,于是修改代码,将min_version版本设置为我们的gcc.exe版本,这样下面的判断gcc_version < min_version就不满足,就不需要换别的编译器。

        if compiler_path is not None:
            the_cc_name = os.path.basename(compiler_path)

            if isGccName(the_cc_name):
                gcc_version = myDetectVersion(env, compiler_path)

                min_version = (8, 1, 0)
                if gcc_version is not None and (
                    gcc_version < min_version
                    or "force-winlibs-gcc" in env.experimental_flags
                ):
                    scons_logger.info(
                        "Too old gcc %r (%r < %r) ignored!"
                        % (compiler_path, gcc_version, min_version)
                    )

                    # This also will trigger using it to use our own gcc in branch below.
                    compiler_path = None
                    env["CC"] = None

第三个坑:

    import SCons.Script  # pylint: disable=import-error
ModuleNotFoundError: No module named 'SCons'

解决方法:
这个模块导入是在/Lib/site-packages/nuitka/build/inline_copy/bin/scons.py中,同样使用激活虚拟环境,pip install Scons

第四个坑:

Nuitka-Scons:INFO: CC 'C:\\mingw64\\bin\\gcc.exe' version check gives (8, 1, 0)
Nuitka-Scons:INFO: Initial CC: 'gcc'
Nuitka-Scons:INFO: Initial CCVERSION: (8, 1, 0)
Nuitka-Scons:INFO: Checking usability of 'C:\\mingw64\\bin\\gcc.exe' from 'gcc'
Scons: Compiler used C:\mingw64\bin\gcc.exe
Nuitka-Scons:INFO: Backend C compiler: gcc (gcc).
Nuitka-Scons:INFO: LTO mode auto was resolved to mode: 'no' (not known to be supported).
Nuitka-Scons:INFO: Using C11 mode: True
Nuitka-Scons:INFO: Using resource mode: 'win_resource' (default for Windows).
Nuitka-Scons:INFO: Told to run compilation on 8 CPUs.
Nuitka-Scons:INFO: Checking if ccache is at 'C:\Users\CNXIGAO13\.conda\envs\gui\bin\ccache.exe' guessed path.
Nuitka-Scons:INFO: Checking if ccache is at 'C:\Users\CNXIGAO13\.conda\envs\gui\scripts\ccache.exe' guessed path.
Nuitka will make use of ccache to speed up repeated compilation.

Is it OK to download and put it in 'C:\Users\CNXIGAO13\AppData\Local\Nuitka\Nuitka\ccache\v3.7.12'.

No installer needed, cached, one time question.

Proceed and download? [Yes]/No
Yes
Nuitka:INFO: Downloading 'https://github.com/ccache/ccache/releases/download/v3.7.12/ccache-3.7.12-windows-32.zip'.
FATAL: Failed to download 'https://github.com/ccache/ccache/releases/download/v3.7.12/ccache-3.7.12-windows-32.zip'. Contents should manually be copied to 'C:\Users\CNXIGAO13\AppData\Local\Nuitka\Nuitka\ccache\v3.7.12\ccache-3.7.12-windows-32.zip'.

解决方法:
缺少ccache.exe,下载又失败,去github自己手动下载,按报错最后一句放到指定文件夹下(路径可能因人而异)

第五个坑:
打包好exe之后,点击运行报错,说缺少python37.dll
解决方法:
去虚拟环境文件夹下复制一个python37.dll放到hello.py程序所在文件夹,问题解决,这是一个比较简单的尝试,后面遇到复杂的问题会继续记录下来。

;