美文网首页
Nuitka打包

Nuitka打包

作者: ZAK_ML | 来源:发表于2023-09-24 10:00 被阅读0次

    nuitka使用参考(windows)

    官方文档

    安装

    安装C编译器

    mingw64下载页面

    页面拉到最下面,目前最新版本为8.1.0,

    x86_64-posix-sjlj

    x86_64-posix-seh

    x86_64-win32-sjlj

    x86_64-win32-seh

    i686-posix-sjlj

    i686-posix-dwarf

    i686-win32-sjlj

    i686-win32-dwarf

    附上版本区别详解供参考

    64位系统建议选择x86_64-posix-sjlj

    32位系统建议选择i686-posix-sjlj

    官方文档中说要设置一下环境变量,实际使用过程中发现不设置也可以正常使用

    安装python

    下载python,同样按自己系统下载对应的版本

    安装nuitka

    python -m pip install nuitka

    如果是anaconda

    conda install -c conda-forge nuitka

    简单测试

    新建hello.py

    def talk(message):

        return "Talk " + message

    先直接用python运行,看看有没有语法错误

    python hello.py

    然后进行构建

    nuitka  hello.py

    命令结束后会生成一个exe,运行exe和执行上面第一条命令效果一样。

    复杂一点的测试,引用一个模块

    为了测试模块引用,我们将上面的文件拆分成两部分

    新建mdl.py

    def talk(message):

        return "Talk " + message

    hello.py

    from mdl import talk

    def main():

        print( talk("Hello World"))

    if __name__ == "__main__":

        main()

    同样按上面的顺序进行构建

    先直接用python运行,看看有没有语法错误

    python hello.py

    然后进行构建

    nuitka  hello.py

    使用这条命令生成的exe可以正常运行。

    但如果将生成的exe拷贝到其他路径执行,将会执行失败,提示找不到mdl模块,这是因为使用上述命令生成的exe里面是并不包含上面的mdl模块,于是在执行该exe的时候,它会尝试去调用mdl.py,如果找不到mdl.py,当然就会提示找不到模块,这和py文件的执行原理是一样的。

    exe同级目录下面会有一个python3x.dll文件,执行exe文件时,如果需要调用外部模块,需要这个文件的支持。

    关于python3x.dll

    python3x.dll是与版本相对应的,如果是python3.8.3,那么就是python38.dll。实际上,这个文件和python安装目录下面的python3x.dll是同一个文件(的拷贝)。python3x.dll相当于一个运行时(runtime),类似于javac,或者微软的framwork,python代码通过nuitka生成了二进制代码(exe或者pyd),但仍然通过python3x.dll保留了python的特性,比如调用一个python模块

    现在将整个目录拷贝到其他路径,可以发现exe能够正常执行,因为此时exe文件能够通过python3x.dll找到mdl.py。

    如果不想借助python3x.dll去调用模块,就要将这个模块打包进exe

    nuitka --follow-import-to=mdl hello.py

    再次将生成的exe单独拷贝到其他地方执行,可以看到能够正常运行,此时不再需要拷贝python3x.dll和其他任何的文件。

    打包模块与follow import

    上面的命令中使用了参数--follow-import-to,这个参数位于Control the recursion into imported modules这一部分,这部分参数一共有五个

        --follow-stdlib, --recurse-stdlib

                            Also descend into imported modules from standard

                            library. This will increase the compilation time by a

                            lot. Defaults to off.

        --nofollow-imports, --recurse-none

                            When --recurse-none is used, do not descend into any

                            imported modules at all, overrides all other recursion

                            options. Defaults to off.

        --follow-imports, --recurse-all

                            When --recurse-all is used, attempt to descend into

                            all imported modules. Defaults to off.

        --follow-import-to=MODULE/PACKAGE, --recurse-to=MODULE/PACKAGE

                            Recurse to that module, or if a package, to the whole

                            package. Can be given multiple times. Default empty.

        --nofollow-import-to=MODULE/PACKAGE, --recurse-not-to=MODULE/PACKAGE

                            Do not recurse to that module name, or if a package

                            name, to the whole package in any case, overrides all

                            other options. Can be given multiple times. Default

                            empty.

    这一部分参数可以说是nuitka的核心。nuitka能够根据py文件中的import语句找到所有引用的库,然后将这些库文件打包进二进制文件中。找到import,然后follow,所以是follow import。所有被导入的库可以看作一个列表,而这部分参数的作用就是让用户在这个列表中进行选择,只有被选中的部分会被打包进exe

    全选

    --follow-imports, --recurse-all

    不选

    --nofollow-imports, --recurse-none

    仅选择标准库

    --follow-stdlib, --recurse-stdlib

    仅选择指定模块/包

    --follow-import-to=MODULE/PACKAGE, --recurse-to=MODULE/PACKAGE

    不选择指定模块/包,这个选项会覆盖其他递归选项,也就是说最后用

    --nofollow-import-to=MODULE/PACKAGE, --recurse-not-to=MODULE/PACKAGE

    如果某些库没有被打包进exe,程序仍会试图通过python3x.dll去搜索路径中查找这些库,然后进行调用,调用方式跟py文件一模一样。

    nuitka打包相对来说是比较耗费时间的,特别是针对像pandas这样的大家伙,所以在最终发布之前,可以暂时不对这些库进行打包(--nofollow-imports),而是将这些库手动拷贝到搜索路径中,比如exe同级目录。只要能够找到这些库,程序就能正常运行,否则会提示no module named xxx

    注意:这部分参数仅仅能够处理py或者pyc文件,如果遇到pyd或者dll则会跳过

    模块搜索路径

    python程序如果引用了其他模块(代码中使用了import语句),就会到搜索路径中去查找这些模块,如果找不到就会提示

    no module named xxx

    搜索路径有很多个,而python使用环境变量sys.path管理这些路径,可以在入口代码最开头使用

    import sys print(sys.path)

    查看运行环境中的sys.path,看看缺失的库是否存在于搜索路径当中。

    发布一个程序

    如果python程序中仅仅使用了一些自定义的模块,那么参数--follow-imports就足以达到发布的效果,一个exe外加一个python3x.dll就可以在任何电脑上运行,无论是否安装python(当然架构要对应),然而实际情况往往比较复杂,稍微强大一点的程序都会调用一些第三方库,比如pyqt,numpy,这些模块中调用了大量的pyd或者dll文件。这个时候就需要使用参数--standalone

    参数--standalone默认包含参数--follow-imports,即会尝试对所有的引用到的库都进行打包,将这些库中的py或者pyc打包进exe,然后再将所依赖的二进制文件(dll或者pyd)拷贝到exe所在文件夹。只要命令能够执行完成不出错,生成的exe就可以完全脱离python环境独立运行。

    depends.exe

    在第一次使用--standalone时,会提示安装Dependency Walker,nuitka需要使用这个工具来解析所有的依赖,从而决定拷贝哪些文件(dll,pyd)到exe目录。命令进行的过程中会自动检测该工具是否存在,没有的话会自动提示进行下载,网络没问题的时候直接回车或者输入yes就行了,但是如果网络状况不佳,就需要提前手动下载,否则命令会因此中断。

    具体步骤:手动下载和系统相匹配的版本(32位或64位),解压得到以下两个文件

    depends.exe depends.dll

    然后放置到对应的目录 x86的路径

    C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\x86\

    X64的路径

    C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\x86_64\

    ps:我尝试过将工具放在path中,没有用,只能放在上面的路径里面

    可以通过参数--windows-dependency-tool=DEPENDENCY_TOOL将其修改为其他依赖解析工具,比如pefile,但是不建议修改。参数--windows-dependency-tool=DEPENDENCY_TOOL仅限windows系统使用

    参数--mingw64

    实际上 --mingw64与--msvc=MSVC是一对孪生参数,这两个参数二选一,用于指定编译器,如果当前环境既安装了mingw64,又安装了msvc,可以使用该参数选择兼容性最好的编译器,建议使用mingw64。如果不存在上面两种编译器都存在的情况,就不需要显式设置这个参数,默认会调用系统中能用的编译器。

    参数plugin control

    这部分参数用于设置对某些第三方库或者python功能进行支持,在使用--standalone时才会用到

    如果程序中使用了pyqt或者pyside,那么

    --plugin-enable=qt-plugins

    如果程序中使用了numpy, scipy, pandas, matplotlib,那么

    --plugin-enable=numpy

    如果使用了这些库或功能,但是忘了进行插件参数设置,命令运行过程中会以红字今天提醒,按照提醒对命令进行调整即可

    如果有多个插件需要启用

    --plugin-enable=numpy  --plugin-enable=qt-plugins  --plugin-enable=tensorflow

    可以使用 nuitka --plugin-list查看可用的插件

    C:\Users\Administrator\Desktop\a>nuitka  --plugin-list

            The following optional standard plugins are available in Nuitka

    --------------------------------------------------------------------------------

    data-files

    dill-compat

    enum-compat

    eventlet          Required by the eventlet package

    gevent            Required by the gevent package

    implicit-imports

    multiprocessing  Required by Python's multiprocessing module

    numpy            Required for numpy, scipy, pandas, matplotlib, etc.

    pbr-compat

    pmw-freezer      Required by the Pmw package

    pylint-warnings  Support PyLint / PyDev linting source markers

    qt-plugins        Required by the PyQt and PySide packages

    tensorflow        Required by the tensorflow package

    tk-inter          Required by Python's Tk modules

    torch            Required by the torch / torchvision packages

    参数Output choices

    -o FILENAME

    指定生成的可执行文件的文件名,但是生成pyd的时候无法使用,也就是在使用--module的时候无法为pyd文件指定一个其他的文件名

    --output-dir=DIRECTORY

    指定打包好的文件存放的目录,默认为当前目录

    --remove-output

    使用nuitka进行打包的过程中,会生成一个用于build的中间临时目录,若可以使用该参数,命令完成后会自动删除build目录

    --no-pyi-file

    不生成pyi文件。pyi文件主要用于生成pyd文件时进行隐式import的检测

    参数--show-progress 和--show-scons

    用来显示详细打包过程,看得懂的话就加上吧,这部分还有几个参数,感兴趣的可以试试

        --show-scons        Operate Scons in non-quiet mode, showing the executed

                            commands. Defaults to off.

        --show-progress    Provide progress information and statistics. Defaults

                            to off.

        --show-memory      Provide memory information and statistics. Defaults to

                            off.

        --show-modules      Provide a final summary on included modules. Defaults

                            to off.

        --verbose          Output details of actions taken, esp. in

                            optimizations. Can become a lot. Defaults to off.

    数 --windows-disable-console

    禁用终端窗口,当程序有一个图形化界面的时候经常用到,仅限windows系统

    参数 --windows-icon=ICON_PATH

    设定程序的图标,仅限windows系统

    ----------------------------------------------------------- 深水区警告 --------------------------------------------------------------------

    对反射的支持

    python的反射机制,简而言之,就是可以通过字符串,动态调用一些库或者模块,诸如根据用户的输入调用插件等。

    pack_name=input("input the package name:")

    pack=__import__(pack_name)

    上面这种情况,pack到底是哪个库,完全依赖于用户输入,nuitka没法利用follow import这部分参数确定可能会被用到的库。这种情况下可以不对这些库进行打包,那么打包好的exe只要在搜索路径中能够找到这些库,程序依然可以正常运行。

    但如果希望能够将这些模块打包为二进制(exe或者pyd),那么就要用到--include这部分参数

    nuitka --follow-imports --include-package=testPackage mx.py

    nuitka就会将这个package强行打包进exe,如果运行的时需要进行调用,程序就会在exe里面进行寻找,看看有没有这个package

    include部分有四个具体的参数

    指定一个package

    --include-package=PACKAGE

    指定一个module

    --include-module=MODULE

    指定一个目录,里面包含的所有包/模块都会被打包(覆盖其他递归选项)

    --include-plugin-directory=MODULE/PACKAGE

    与pattern匹配的所有文件都会被打包(覆盖其他递归选项)

    --include-plugin-files=PATTERN

    使用参数--module打包生成pyd文件

    使用--module参数,将包/模块打包为二进制的pyd文件。module在这里可能会有点歧义,实际上借助--include参数,对于包/模块/目录(package/module/directory),都能打包为pyd。

    打包一个package

    nuitka --module --include-package=PACKAGE  PACKAGE 

    打包一个module

    nuitka --module --include-module=MODULE    MODULE

    打包一个目录

    nuitka --module --include-plugin-directory=DIRECTORY    DIRECTORY

    打包一堆零散文件,与pattern匹配的所有文件都会被打包

    nuitka --module --include-plugin-files=PATTERN    mods

    打包pyd文件,必须借助--include参数,这是因为打包pyd的时候没有入口文件,所以就没有import可以follow,因此就必须要用到include对整个包进行指定,否则打包出来的pyd文件里面不会有任何的内容,引用这个pyd文件会提示找不到模块

    ps:打包pyd过程中如果出现类似警告提示

    Nuitka:WARNING:Recursed to package 'TestPackage' at 'C:\Users\Administrator\Desktop\a\TestPackage' twice.

    作者说不用管,原话如下

    I think this one is actually described in the user manual.

    We compile the filename you give as a module, even if it is a package, giving an empty package. Then you get to force inclusion of a whole module, which makes it see the top level twice, ignoring it, which triggers the warning.

    常见错误

    (逐渐添加)

    **ImportError: DLL load failed while importing xxxxx: %1 is not a valid Win32 application.**

    加载pyd模块时发生

    原因:vscode没有正确初始化

    解决方法:直接在终端中运行python

    编译模块时候发生

    ImportError: dynamic module does not define module export function (PyInit_TestPackage2)

    原因:使用参数--module编译出来的pyd文件,不能更改文件名

    处理机制。

    编译过程需联网添加部份组件,建议挂上梯子,网址可能被墙掉的,编译过程大概率卡在下载

    winlibs-x86_64-posix-seh-gcc-11.3.0-llvm-14.0.3-mingw-w64msvcrt-10.0.0-r3.zip

    组件,复制该网址自行下载提示无效的,需自行下载

    下载

    下载后参考cmd里面提示的路径把压缩包里的目录提取到类拟

    Nuitka\Nuitka\Cache\downloads\gcc\x86_64\11.3.0-14.0.3-10.0.0-msvcrt-r3

    这样的路径下,然后强行关掉cmd再重新编译,除这个外其它的组件都能顺利下载,编译后py文件同级目录下多了两个目录,其中带dist里的exe就是执行文件,把该目录复制就可以独立使用exe文件了。

    nuitka参数列表

    输入nuitka,回车之后会显示nuitka的参数列表

    Usage: __main__.py [--module] [--run] [options] main_module.py

    Options:

      --version            show program's version number and exit

      -h, --help            show this help message and exit

      --module              Create an extension module executable instead of a

                            program. Defaults to off.

      --standalone          Enable standalone mode in build. This allows you to

                            transfer the created binary to other machines without

                            it relying on an existing Python installation. It

                            implies these option: "--recurse-all". You may also

                            want to use "--python-flag=no_site" to avoid the

                            "site.py" module, which can save a lot of code

                            dependencies. Defaults to off.

      --python-arch=PYTHON_ARCH

                            Architecture of Python to use. One of "x86" or

                            "x86_64". Defaults to what you run Nuitka with

                            (currently "x86_64").

      --python-debug        Use debug version or not. Default uses what you are

                            using to run Nuitka, most likely a non-debug version.

      --python-flag=PYTHON_FLAGS

                            Python flags to use. Default uses what you are using

                            to run Nuitka, this enforces a specific mode. These

                            are options that also exist to standard Python

                            executable. Currently supported: "-S" (alias

                            "nosite"), "static_hashes" (do not use hash

                            randomization), "no_warnings" (do not give Python

                            runtime warnings), "-O" (alias "noasserts"). Default

                            empty.

      --python-for-scons=PYTHON_SCONS

                            If using Python3.3 or Python3.4, provide the path of a

                            Python binary to use for Scons. Otherwise Nuitka can

                            use what you run Nuitka with or a "scons" binary that

                            is found in PATH, or a Python installation from

                            Windows registry.

      --warn-implicit-exceptions

                            Enable warnings for implicit exceptions detected at

                            compile time.

      --warn-unusual-code  Enable warnings for unusual code detected at compile

                            time.

      --assume-yes-for-downloads

                            Allow Nuitka to download code if necessary, e.g.

                            dependency walker on Windows.

      Control the inclusion of modules and packages:

        --include-package=PACKAGE

                            Include a whole package. Give as a Python namespace,

                            e.g. ``some_package.sub_package`` and Nuitka will then

                            find it and include it and all the modules found below

                            that disk location in the binary or extension module

                            it creates, and make it available for import by the

                            code. Default empty.

        --include-module=MODULE

                            Include a single module. Give as a Python namespace,

                            e.g. ``some_package.some_module`` and Nuitka will then

                            find it and include it in the binary or extension

                            module it creates, and make it available for import by

                            the code. Default empty.

        --include-plugin-directory=MODULE/PACKAGE

                            Include the content of that directory, no matter if

                            it's used by the given main program in a visible form.

                            Overrides all other recursion options. Can be given

                            multiple times. Default empty.

        --include-plugin-files=PATTERN

                            Include into files matching the PATTERN. Overrides all

                            recursion other options. Can be given multiple times.

                            Default empty.

      Control the recursion into imported modules:

        --follow-stdlib, --recurse-stdlib

                            Also descend into imported modules from standard

                            library. This will increase the compilation time by a

                            lot. Defaults to off.

        --nofollow-imports, --recurse-none

                            When --recurse-none is used, do not descend into any

                            imported modules at all, overrides all other recursion

                            options. Defaults to off.

        --follow-imports, --recurse-all

                            When --recurse-all is used, attempt to descend into

                            all imported modules. Defaults to off.

        --follow-import-to=MODULE/PACKAGE, --recurse-to=MODULE/PACKAGE

                            Recurse to that module, or if a package, to the whole

                            package. Can be given multiple times. Default empty.

        --nofollow-import-to=MODULE/PACKAGE, --recurse-not-to=MODULE/PACKAGE

                            Do not recurse to that module name, or if a package

                            name, to the whole package in any case, overrides all

                            other options. Can be given multiple times. Default

                            empty.

      Immediate execution after compilation:

        --run              Execute immediately the created binary (or import the

                            compiled module). Defaults to off.

        --debugger, --gdb  Execute inside "gdb" to automatically get a stack

                            trace. Defaults to off.

        --execute-with-pythonpath

                            When immediately executing the created binary

                            (--execute), don't reset PYTHONPATH. When all modules

                            are successfully included, you ought to not need

                            PYTHONPATH anymore.

      Dump options for internal tree:

        --xml              Dump the final result of optimization as XML, then

                            exit.

      Code generation choices:

        --full-compat      Enforce absolute compatibility with CPython. Do not

                            even allow minor deviations from CPython behavior,

                            e.g. not having better tracebacks or exception

                            messages which are not really incompatible, but only

                            different. This is intended for tests only and should

                            not be used for normal use.

        --file-reference-choice=FILE_REFERENCE_MODE

                            Select what value "__file__" is going to be. With

                            "runtime" (default for standalone binary mode and

                            module mode), the created binaries and modules, use

                            the location of themselves to deduct the value of

                            "__file__". Included packages pretend to be in

                            directories below that location. This allows you to

                            include data files in deployments. If you merely seek

                            acceleration, it's better for you to use the

                            "original" value, where the source files location will

                            be used. With "frozen" a notation "<frozen

                            module_name>" is used. For compatibility reasons, the

                            "__file__" value will always have ".py" suffix

                            independent of what it really is.

      Output choices:

        -o FILENAME        Specify how the executable should be named. For

                            extension modules there is no choice, also not for

                            standalone mode and using it will be an error. This

                            may include path information that needs to exist

                            though. Defaults to <program_name> on this platform.

                            .exe

        --output-dir=DIRECTORY

                            Specify where intermediate and final output files

                            should be put. The DIRECTORY will be populated with C

                            files, object files, etc. Defaults to current

                            directory.

        --remove-output    Removes the build directory after producing the module

                            or exe file. Defaults to off.

        --no-pyi-file      Do not create a ".pyi" file for extension modules

                            created by Nuitka. This is used to detect implicit

                            imports. Defaults to off.

      Debug features:

        --debug            Executing all self checks possible to find errors in

                            Nuitka, do not use for production. Defaults to off.

        --unstripped        Keep debug info in the resulting object file for

                            better debugger interaction. Defaults to off.

        --profile          Enable vmprof based profiling of time spent. Not

                            working currently. Defaults to off.

        --graph            Create graph of optimization process. Defaults to off.

        --trace-execution  Traced execution output, output the line of code

                            before executing it. Defaults to off.

        --recompile-c-only  This is not incremental compilation, but for Nuitka

                            development only. Takes existing files and simply

                            compile them as C again. Allows compiling edited C

                            files for quick debugging changes to the generated

                            source, e.g. to see if code is passed by, values

                            output, etc, Defaults to off. Depends on compiling

                            Python source to determine which files it should look

                            at.

        --generate-c-only  Generate only C source code, and do not compile it to

                            binary or module. This is for debugging and code

                            coverage analysis that doesn't waste CPU. Defaults to

                            off. Do not think you can use this directly.

        --experimental=EXPERIMENTAL

                            Use features declared as 'experimental'. May have no

                            effect if no experimental features are present in the

                            code. Uses secret tags (check source) per experimented

                            feature.

        --disable-dll-dependency-cache

                            Disable the dependency walker cache. Will result in

                            much longer times to create the distribution folder,

                            but might be used in case the cache is suspect to

                            cause errors.

        --force-dll-dependency-cache-update

                            For an update of the dependency walker cache. Will

                            result in much longer times to create the distribution

                            folder, but might be used in case the cache is suspect

                            to cause errors or known to need an update.

      Backend C compiler choice:

        --clang            Enforce the use of clang. On Windows this requires a

                            working Visual Studio version to piggy back. Defaults

                            to off.

        --mingw64          Enforce the use of MinGW64 on Windows. Defaults to

                            off.

        --msvc=MSVC        Enforce the use of specific MSVC version on Windows.

                            Allowed values are e.g. 14.0, specify an illegal value

                            for a list of installed compilers.  Defaults to the

                            most recent version.

        -j N, --jobs=N      Specify the allowed number of parallel C compiler

                            jobs. Defaults to the system CPU count.

        --lto              Use link time optimizations if available and usable

                            (gcc 4.6 and higher). Defaults to off.

      Tracing features:

        --show-scons        Operate Scons in non-quiet mode, showing the executed

                            commands. Defaults to off.

        --show-progress    Provide progress information and statistics. Defaults

                            to off.

        --show-memory      Provide memory information and statistics. Defaults to

                            off.

        --show-modules      Provide a final summary on included modules. Defaults

                            to off.

        --verbose          Output details of actions taken, esp. in

                            optimizations. Can become a lot. Defaults to off.

      Windows specific controls:

        --windows-dependency-tool=DEPENDENCY_TOOL

                            When compiling for Windows, use this dependency tool.

                            Defaults to depends.exe, other allowed value is

                            'pefile'.

        --windows-disable-console

                            When compiling for Windows, disable the console

                            window. Defaults to off.

        --windows-icon=ICON_PATH

                            Add executable icon (Windows only).

      Plugin control:

        --plugin-enable=PLUGINS_ENABLED, --enable-plugin=PLUGINS_ENABLED

                            Enabled plugins. Must be plug-in names. Use --plugin-

                            list to query the full list and exit. Default empty.

        --plugin-disable=PLUGINS_DISABLED, --disable-plugin=PLUGINS_DISABLED

                            Disabled plugins. Must be plug-in names. Use --plugin-

                            list to query the full list and exit. Default empty.

        --plugin-no-detection

                            Plugins can detect if they might be used, and the you

                            can disable the warning via --plugin-disable=plugin-

                            that-warned, or you can use this option to disable the

                            mechanism entirely, which also speeds up compilation

                            slightly of course as this detection code is run in

                            vain once you are certain of which plug-ins to use.

                            Defaults to off.

        --plugin-list      Show list of all available plugins and exit. Defaults

                            to off.

        --user-plugin=USER_PLUGINS

                            The file name of user plugin. Can be given multiple

                            times. Default empty.

    python库版本信息查询

    Archived: Python Extension Packages for Windows - Christoph Gohlke (uci.edu)

    相关文章

      网友评论

          本文标题:Nuitka打包

          本文链接:https://www.haomeiwen.com/subject/aqmfbdtx.html