Python沒有內建一個編譯爲exe的功能。給python程序的部署帶來很多的麻煩。 python
因此就會出現一些py2exe之類的很不錯的工具,用於自動把.py文件編譯爲.exe文件。 c++
最近抽空研究了一下手動實現相似py2exe的功能,但願增強對python的瞭解。 redis
結果還至關不錯。把結果記錄下來,與你們共享。 工具
文中所描述的方法,基於python的如下幾個功能 code
1. python程序運行時,會在sys.path指定的路徑中查找庫文件。 ip
2. python從2.3開始,支持從zip文件中import庫(支持.py,.pyc和.pyo,但不支持.pyd) ssl
3. python提供C API,讓c語言的程序,能夠很方便的調用python的程序 部署
注:假設python安裝在c:\python25目錄中,最後的可執行文件放到d:\dist目錄中 get
1. 先去c:\python25\Lib目錄,把全部文件都複製出來,好比複製到d:\pythonlib目錄中 cmd
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> #include <stdlib.h> #include <stdio.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; // 設定運行時的PATH sprintf(szCmd, "PATH=%s\\dlls;%%PATH%%", szPath); _putenv(szCmd); // 把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_OptimizeFlag = 2; Py_NoSiteFlag = 1; Py_Initialize(); PyRun_SimpleString(szCmd); return 0; }
9. 把python25.dll放到d:\dist目錄中。
這樣來,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
注:固然,這種打包方式第一次作的時候比較麻煩,但以後就能夠只要把本身的程序打包就行了,其它的不用變。
並且,若是本身的程序常常作改動的話,本身的程序也能夠不打包,直接放到d:\dist中,反正runpy.exe啓動程序的時候,只要能正常運行import main就能夠了。
有很多人寫email給我,問我要我作的包。你們能夠在這裏下載基於2.5.2版本的包: python_dist.7z 以及基於3.1.2版本的包: python31-dist.7z
注:3.1.2依賴於visual c++ 2008 redistributable package. 若是在目標機器上沒有安裝,則程序運行不起來。
解開包後,只要用本身的程序替換mysrc.zip就可使用了。
包裏有runpy.exe和runpyw.exe兩個文件。其中,runpy.exe是控制檯程序,runpyw.exe是非控制檯程序。這兩個程序分別相似於python.exe和pythonw.exe。想讓程序運行時出現一個控制檯,就運行runpy.exe,若是不想出現黑黑的控制檯,就運行runpyw.exe。