【Python】将Python代码写的tensorflow项目转换成exe可执行文件,并放到其他电脑上成功运行的踩坑记录

一、写在前面

最近做了一个使用tensorflow的机器学习项目,需要将Python的代码经过编译形成一个exe文件,一方面方便用户使用,另一方面可以隐藏自己的源码,一定程度上减少代码泄露的风险。(注意:可以使用ctrl + F搜索你所遇到的错误)

环境:Windows 10 专业版Python 3.6.6 64位

常见的将Python封装成exe文件的方法有:

1.1 使用pyinstaller进行封装

pyinstaller的封装方式较为简便,命令行中执行命令
pyinstaller -D xxx.py

即可将Python文件转换为exe文件,以及dist文件夹和build文件夹,如果要移植到其他电脑上运行,也是只需要将这两个文件夹复制到对方电脑上,即使对方没有python环境,也可以运行程序,具有较好的兼容性。

缺点就是,安全性不高,容易被反编译。

此处用到的工具:

exe反编译工具:pyinstxtractor.py:exe反编译工具下载

pyc反编译工具:Easy Python Decompiler 或者在线反编译pyc。

将pyinstxtractor.py放到exe文件相同目录,执行以下cmd命令:
python pyinstxtractor.py main.exe

详细请参照【PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译】

1.2 使用安全性较高的Nuitka进行封装

Nuitka安全性较高,且根据用户反映能够提升代码执行效率。

cmd中执行命令:
nuitka --recurse-all xxx.py

但是Nuitka的使用难度也较大,网络上的教程也很少,且存在无法运行PyQt5这个UI界面的缺陷,所以最终放弃使用Nuitka。


二、Cython将Python转为C

如上一节所述,上面的两种方法不能满足我对项目打包的要求,于是考虑其他方法,先通过Cython将Python转为.c文件,再通过C语言编译器,将C语言转为.exe文件,此时的文件相较于pyinstaller的生成的exe文件就具有了更强的反编译能力。

2.1 Cython的安装

搭建好Python环境后,在cmd输入一下命令并执行:
pip install Cython

2.2 Python到C的转换

安装完Cython后,命令行进入到目标Python文件xxx.py的目录下,执行命令:
cython xxx.py --embed

2.3 转换中的注意事项 :Error compiling Cython file

报错如下

Error compiling Cython file:
------------------------------------------------------------
...
import sys
^
------------------------------------------------------------

software_V1.5.py:1:0: 'software_V1.5' is not a valid module name

这个错误是因为文件software_V1.5.py命名中出现多余的'.',解决的方式是去除这个多余的'.',可将文件名改为software_V15.py即可解决错误。

PS C:\User> cython .\software_V15.py
c:Users\yww\AppData\Local\Programs\Python\python36\lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: C:\User\software_V15.py
  tree = Parsing.p_module(s, pxd, full_module_name)
PS C:\User>

运行成功,生成C文件,但是这个警告不知道是什么意思,但是不影响后面的工作。


三、将C文件编译为exe可执行文件

3.1 gcc编译的失败

参考【使用cython,gcc将python转换为.exe可执行文件】,进行完第二节的步骤,在刚刚转换得到的c文件的目录下,执行cmd命令:
gcc xxx.c -o xxx.exe

结果报错“fatal error: Python.h: No such file or directory”

PS C:\User> gcc .\software_V15.c -o .\software_V15.exe
.\software_V15.c:4:10: fatal error: Python.h: No such file or directory
 #include "Python.h"
          ^~~~~~~~~~
compilation terminated.

首先尝试将python路径下的'incloud'目录加入到环境变量的Path中,使得生成的C文件可以调用其中.h文件,还是报同样的错误。然后尝试网上的方法,安装python-dev。但是python-dev只有Linux系统可以使用:

1. sudo apt-get install aptitude
2. sudo aptitude install python-dev

进行安装,而Windows没有找到安装包。最终,在发现cl.exe编译器之后,选择放弃gcc编译。

3.2 cl.exe编译的安装

安装安装Microsoft Visual C++ Build Tools 2015,【Microsoft Visual C++ Build Tools 2015 下载地址】

滑动至页面下方进行下载:
【Python】将Python代码写的tensorflow项目转换成exe可执行文件,并放到其他电脑上成功运行的踩坑记录_第1张图片
安装Windows 10 SDK,【Windows 10 SDK 下载地址】
【Python】将Python代码写的tensorflow项目转换成exe可执行文件,并放到其他电脑上成功运行的踩坑记录_第2张图片
下载后直接点击,默认安装。

安装完毕后配置环境变量。在环境变量中寻找变量Path、include、lib,如果没有点击新建进行创建,配置时要注意区分Python是64位还是32位,我的Python是64位的。

(1) Path在64位Python下添加的路径:

C:\Users\yww\AppData\Local\Programs\Python\python36
C:\Users\yww\AppData\Local\Programs\Python\python36\include
C:\Users\yww\AppData\Local\Programs\Python\python36\Scripts
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE
C:\Program Files (x86)\Windows Kits\10\bin\x64

(2) include在64位Python下添加的路径:

C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt
C:\Program Files (x86)\Windows Kits\8.1\Include\um
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared
C:\Users\yww\AppData\Local\Programs\Python\python36\include

(3)lib在64位Python下添加的路径:

C:\Users\yww\AppData\Local\Programs\Python\python36\libs
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\x64
C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64

如果你使用的Python是32位,将上面的amd64或者x64,改为目录下x86系列目录即可,32位cl.exe的目录为:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin

注意,上面Python的路径是我的电脑上Python的路径,要根据你们Python的路径进行配置。安装完成后,转换得到的C文件目录下执行:
cl -GX xxx.c

得到:

PS C:\User> cl -GX .\software_V15.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9035 : option 'GX' has been deprecated and will be removed in a future release
cl : Command line warning D9036 : use 'EHsc' instead of 'GX'
software_V15.c
Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:software_V15.exe
software_V15.obj
   Creating library software_V15.lib and object software_V15.exp
PS C:\User>

成功生成exe文件!

3.3 可能的错误

(1) LINK : fatal error LNK1561: entry point must be defined

错误如下:

PS C:\User> cl -GX .\software_V15.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9035 : option 'GX' has been deprecated and will be removed in a future release
cl : Command line warning D9036 : use 'EHsc' instead of 'GX'
software_V15.c
Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:software_V15.exe
software_V15.obj
   Creating library software_V15.lib and object software_V15.exp
LINK : fatal error LNK1561: entry point must be defined
C:\User>

这个时候不能生成exe文件,这是由于在使用Cython将Python转为C时,将
cython xxx.py --embed

写成
cython xxx.py

这个错误的原因是在执行Cython时,未使用--embed关键字,导致生成的C文件中没有main函数。

(2) fatal error C1083: 无法打开包括文件: “io.h”: No such file or directory
除了io.h,还会出现找不到其他.h、.lib文件的情况,这是因为没有配置好环境变量,重新按照3.2部分配置环境变量。

(3) fatal error LNK1112: module machine type ‘x64’ conflicts with target machine type 'X86’

PS C:\User> cl -GX .\software_V15.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9035 : option 'GX' has been deprecated and will be removed in a future release
cl : Command line warning D9036 : use 'EHsc' instead of 'GX'
software_V15.c
Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:software_V15.exe
software_V15.obj
python36.lib(python36.dll) : fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
C:\User>

这个是由于cl.exe的位数与Python的位数不匹配,需要查看你所使用Python的位数(如64位Python),并以此根据3.2进行环境变量配置。


四、在其它电脑上运行的配置

要在其他电脑上运行,需要搭建环境。首先在需要运行的电脑上安装Python,这个教程很多,不再赘述,但是要注意Python的位数(64位还是32位)。【Python下载地址】

还有一个需要注意的是,目标电脑Python的安装路径需要和你的电脑中Python的安装路径一致,否则也会报错。

安装好Python后,从你的电脑Python路径下Lib目录中,打包site-packages,并将这个文件传输到目标电脑中同样的Python目录下,替换原来的文件。

将生成的.exe文件以及同级目录下的build文件夹打包(如果有权重文件,则对其进行加密后也要一起打包)。然后将这个包传输至目标电脑中进行解压。至此,就可以顺利在目标电脑上运行你的exe文件了。


五、总结

这种将Python文件先转换成.c文件在转换为.exe文件的方式,不能使用针对python的反编译软件进行反编译,例如之前介绍的pyinstxtractor.py,整体安全性要比使用Pyinstaller直接加密要高,具有一定的破解难度。且相比pyinstaller生成接近1G的包相比,使用这种方式生成的包只有50M。特别的轻量化。

第一次写的博客,感谢朋友对我的帮助,也特别希望各位大佬能对这种打包方式给出意见和建议,最重要的是想知道这种方式是否真的如我想象的这样安全。

如果觉得有用,也可以支持一下我这个快要秃头程序员
【Python】将Python代码写的tensorflow项目转换成exe可执行文件,并放到其他电脑上成功运行的踩坑记录_第3张图片

你可能感兴趣的:(【Python】将Python代码写的tensorflow项目转换成exe可执行文件,并放到其他电脑上成功运行的踩坑记录)