Pyinstaller打包詳解---生成windows、linux下的整包可執行文件


1、原理及作用:

pyinstaller自身打包的流程:讀取編寫好的python腳本,分析其中調用的模塊和庫,然后收集這些文件的副本(包括Python的解釋器)。最后把副本與腳本,可執行文件等放在一個文件夾中,或者可選的封裝在一個可執行文件中。我們可以將自己的python代碼打包成一個可執行文件。起到代碼保護和封裝的作用。

2、打包流程:

 

簡略描述Pyinstall的打包流程:
①下載好Pyinstaller之后,
②拷貝上述spec文件並增刪自己的工程代碼路徑(或使用pyi-makespec main.py命令生成.spec文件)

 

③執行 pyinstaller main.spec

 

④在dist中,檢驗生成的  main可執行文件

 

2-1、安裝pyinstaller
pip install pyinstaller
2-2、拷貝main.spec文件

我們用main.spec文件記錄打包需要的文件依賴等,pyinstaller參數的本質可認為是 .spec文件中的配置屬性。main.spec文件可按照類型直接在internet中拷貝模板即可,之后進行修改。(下文有模板示例)

camera_stress_test_tool_main工具為例:

將下面模板的camera_stress_test_tool_main.spec文件拷貝至和 main.py同目錄下

亦可用pyi-makespec  main.py生成 .spec文件,需注意按需使用參數

-F, –onefile 打包一個單個文件
-D, –onedir 打包多個文件,在dist中生成很多依賴文件,適合以框架形式編寫工具代碼,我個人比較推薦這樣,代碼易於維護
-K, –tk 在部署時包含 TCL/TK
-a, –ascii 不包含編碼.在支持Unicode的python版本上默認包含所有的編碼.
-d, –debug 產生debug版本的可執行文件
-w,–windowed,–noconsole 使用Windows子系統執行.當程序啟動的時候不會打開命令行(只對Windows有效)
-c,–nowindowed,–console 使用控制台子系統執行(默認)(只對Windows有效)pyinstaller -c xxxx.pypyinstaller xxxx.py –console
-s,–strip 可執行文件和共享庫將run through strip.注意Cygwin的strip往往使普通的win32 Dll無法使用.
-X, –upx 如果有UPX安裝(執行Configure.py時檢測),會壓縮執行文件(Windows系統中的DLL也會)(參見note)
-o DIR, –out=DIR 指定spec文件的生成目錄,如果沒有指定,而且當前目錄是PyInstaller的根目錄,會自動創建一個用於輸出(spec和生成的可執行文件)的目錄.如果沒有指定,而當前目錄不是PyInstaller的根目錄,則會輸出到當前的目錄下.
-p DIR, –path=DIR 設置導入路徑(和使用PYTHONPATH效果相似).可以用路徑分割符(Windows使用分號,Linux使用冒號)分割,指定多個目錄.也可以使用多個-p參數來設置多個導入路徑,讓pyinstaller自己去找程序需要的資源
–icon=<FILE.ICO> 將file.ico添加為可執行文件的資源(只對Windows系統有效),改變程序的圖標 pyinstaller -i ico路徑 xxxxx.py
–icon=<FILE.EXE,N> 將file.exe的第n個圖標添加為可執行文件的資源(只對Windows系統有效)
-v FILE, –version=FILE 將verfile作為可執行文件的版本資源(只對Windows系統有效)
-n NAME, –name=NAME 可選的項目(產生的spec的)名字.如果省略,第一個腳本的主文件名將作為spec的名字

 

camera_stress_test_tool_main.spec文件模板示例:(模板為單文件示范)

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['main.py',
            './cfg/__init__.py',
            './cfg/setting.py',
            './comm/__init__.py',
            './comm/logger.py',
            './comm/utils.py',
            './handler/__init__.py',
            './handler/invite_handler.py',
            './handler/sip_parse_handler.py',
            './handler/subscribe_handler.py',
            './my_thread/__init__.py',
            './my_thread/alarm.py',
            './my_thread/audio_media.py',
            './my_thread/audio_media_rtp.py',
            './my_thread/broadcast.py',
            './my_thread/my_sip_epoll.py',
            './my_thread/timer.py',
            './my_thread/video_media.py',
            './redis_utils/__init__.py',
            './redis_utils/redis_keys.py',
            './redis_utils/redis_work.py',
            './__init__.py',
            './device.py',
            './std/ietf/__init__.py',
            './std/ietf/rfc1035.py',
            './std/ietf/rfc2198.py',
            './std/ietf/rfc2396.py',
            './std/ietf/rfc2617.py',
            './std/ietf/rfc2833.py',
            './std/ietf/rfc3261.py',
            './std/ietf/rfc3489.py',
            './std/ietf/rfc5658.py',
            './std/ietf/rfc6455.py',
            './std/ietf/rfc7064.py',
            './std/ietf/rfc7065.py',
            './std/itu_t/__init__.py',
            './std/w3c/__init__.py',
            './std/w3c/simplexml.py',
            './std/__init__.py'],
             pathex=['./'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='main',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True )
2-3、修改main.spec文件

一般來說,我們需要在“Analysis”這個item中,加入打包的代碼的路徑,(此處需注意路徑相關依賴,與創建spec的路徑相對應,一般在main.py文件基礎上找,可寫絕對及相對路徑)。另外:是否加入圖標路徑icon,是否需要console等可按需配置。

為了便於理解掌握命令配置參數

下面附上main.spec文件的配置詳情:

 

 

2-4、執行打包命令
pyinstaller  main.spec
 
2-5、刪除源代碼和中間產物

打包完成后可刪除生成的build文件夾,.spec文件等,亦可將代碼刪除,之后我們可直接運行打包成品的可執行文件。

 
2-6、運行檢查打包后的可執行文件

修改配置文件相關配置后

(注意是配置文件不是代碼,修改代碼則需要重新打包)

可直接進入dist文件夾中,找到可執行文件,linux下直接使用下述命令執行。如:

  ./main

若有路徑報錯,根據運行情況自行解決相關依賴等。

常見問題有路徑依賴包依賴,一般需解決代碼內部引用路徑(目前可執行文件的執行路徑,與代碼入口路徑不同)來更改代碼,缺省的依賴需加入到.spec文件中等。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM