手動製做python的exe可執行程序 -- by Leo Jay

轉載來自: http://wiki.woodpecker.org.cn/moin/LeoJay/PyPackage

手動製做python的exe可執行程序 -- by Leo Jay

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

  • 哈哈,至關的簡潔明瞭吧。一共才4個文件一個目錄,5MB都不到哦。

注:固然,這種打包方式第一次作的時候比較麻煩,但以後就能夠只要把本身的程序打包就行了,其它的不用變。

並且,若是本身的程序常常作改動的話,本身的程序也能夠不打包,直接放到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。

相關文章
相關標籤/搜索