1. 手動製作python的exe可執行程式
轉載---------------
Python沒有內建一個編譯為exe的功能。給python程式的部署帶來不少的麻煩。
所以就會出現一些py2exe之類的很不錯的工具,用於自動把.py檔案編譯為.exe檔案。
最近抽空研究了一下手動實作類別似py2exe的功能,希望加強對python的瞭解。
結果還相當不錯。把結果記錄下來,與大家共用。
1.1. 原理
文中所描述的方法,基於python的以下幾個功能
1. python程式運行時,會在sys.path指定的路徑中尋找庫檔案。
2. python從2.3開始,支援從zip檔案中import庫(支援.py,.pyc和.pyo,但不支援.pyd)
3. python提供C API,讓c語言的程式,可以很方便的調用python的程式
1.2. 實際步驟
註:假設python安裝在c:/python25目錄中,最後的可執行檔放到d:/dist目錄中
1. 先去c:/python25/Lib目錄,把所有檔案都複製出來,比如複製到d:/pythonlib目錄中
2. 開一個cmd視窗,進入d:/pythonlib目錄中,運行 python -OO compileall.py -f . 把lib中的.py檔案都編譯成.pyo檔案
3. 刪除d:/pythonlib目錄中所有的.py和.pyc檔案,因為我們只要有.pyo檔案就可以讓這些庫運行了。
4. 刪除目錄中所有用不著的檔案,比如curses,test,idlelib,msilib等,以減少組建檔案的體積。
5. 把這些庫打包成一個zip檔案,比如stdlib.zip,放到d:/dist目錄中
6. 把c:/python25/dlls目錄中的.pyd和.dll檔案,複製到d:/dist/dlls目錄中,當然,刪除不可能用到的一些檔案_msi.pyd,_ssl.pyd等等,可以減少檔案的體積
7. 把自己寫的程式,也按步驟2至步驟5所說的方法,打成一個mysrc.zip包,放到d:/dist目錄中。 注意:自己寫的程式的入口應該是main.pyo檔案
8. 用以下C程式編譯出一個可執行檔,比方說叫runpy.exe,也放到d:/dist中。
#include <Python.h>#include <Windows.h>int main(){ // 得到當前可執行檔所在的目錄 char szPath[10240]; char szCmd[10240]; GetModuleFileName(NULL, szPath, sizeof(szPath)); char* p = strrchr(szPath, '//'); if (p == NULL) { printf("Get module file name error!/n"); return -1; } *p = 0; // 把sys.path設定為['.', '自己的原始碼zip檔案', '標準庫zip檔案', 'dll目錄'] // 然後調用main模組 sprintf(szCmd, "import sys/n" "sys.path=['.', r'%s//mysrc.zip', r'%s//stdlib.zip', r'%s//dlls']/n" "import main/n", szPath, szPath, szPath); Py_Initialize(); PyRun_SimpleString(szCmd); return 0;}
9. 把python25.dll放到d:/dist目錄中。
1.3. 結束語
這樣來,d:/dist目錄中,一共只有4個檔案加一個目錄:
dlls目錄:用於存放所有的dll檔案和pyd檔案
stdlib.zip檔案:用於存放所有的python的.pyo檔案格式的標準庫
mysrc.zip檔案:用於存放自己寫的程式。注意,自己寫的程式的入口在main.pyo中。
runpy.exe檔案:程式的開機檔案,啟動後會設定python的sys.path,然後調用main模組
python25.dll檔案:python的核心dll,runpy.exe依賴於這個dll
- 哈哈,相當的簡潔明了吧。一共才4個檔案一個目錄,5MB都不到哦。
註:當然,這種打包方式第一次做的時候比較麻煩,但之後就可以只要把自己的程式打包就好了,其它的不用變。
而且,如果自己的程式經常做改動的話,自己的程式也可以不打包,直接放到d:/dist中,反正runpy.exe啟動程式的時候,只要能正常運行import main就可以了。