Single Binary StacklessPython 3.6.4 L8 リリース
業務の効率化や Python インタプリタの勉強も兼ねて、 StacklessPython を 1 バイナリ化していましたが、バージョン L8 まできました。
GitHub のリリースページからダウンロードできます。
今回は、主に以下の変更をしました。
- tkinter のサポート
- EXE 化の実験的サポート
- Windows Subsystem 版のサポート
tkinter のサポート
これまでに Python の標準ライブラリは、ほぼすべてサポートしていましたが、 tkinter はいくつかの理由でサポートしていませんでした。
tkinter をサポートし、1 バイナリで実行するには、 tcl/tk のライブラリを静的にリンクする必要があります。
また、 tcl/tk は、いくつかの *.tcl ファイルを必要とするので、こちらについても対応する必要があります。
静的リンクについては、 nmake -f makefile.vc core OPTS=static
のように OPTS
として static
を指定すれば、静的リンク版をビルドできるので、こちらを使うことになります。
一方で、*.tcl ファイルの抱き込みについては、やや面倒です。
*.tcl ファイルの抱き込み
tcl では、Tcl_Filesystem
という構造体で、複数のファイルシステムを持つことができます。
これは一言で言うと Python の path_hooks
に相当するものです。
今回は embeddedFilesystem
というファイルシステムを作成し、 embeddedfs:/tcl8.6/init.tcl
のように embeddedfs:/
で始まる仮想的なパスが指定された場合に、バイナリの中に保持しているファイルの中身を返すようにしています。
詳しくは tclEmbeddedFilesystem.c
を参照してください。
EXE 化の実験的サポート
せっかくなので、おまけの機能として EXE 化の機能を付けてみました。
なお、元々、標準ライブラリ外の機能は考慮していないので、py2exe や PyInstaller の代わりには使えません。あくまで、標準ライブラリだけを使って書けるスクリプトの EXE 化ができます。
例えば下記のように、 tk でウィンドウを作成し、クリックでカウントアップするだけのプログラムを EXE 化してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # coding: utf-8 # counter.py import tkinter as tk import tkinter.ttk as ttk class Counter(ttk.Frame): def __init__( self , parent): super ().__init__(parent) var = tk.StringVar() var. set ( "0" ) label = ttk.Label( self , textvariable = var, anchor = tk.CENTER, font = ("", 30 )) label.pack(expand = True , fill = tk.BOTH) label.bind( "<Button-1>" , self .increment) label.bind( "<Button-3>" , self .decrement) self .var = var self .count = 0 def increment( self , event): self .count + = 1 self .var. set ( "%d" % self .count) def decrement( self , event): self .count - = 1 self .var. set ( "%d" % self .count) root = tk.Tk() a = Counter(root) a.pack(expand = True , fill = tk.BOTH) root.mainloop() |
今回の Single Binary StacklessPython では、上記のように tkinter を使うような場合も、実行することができます。
これを、単一の EXE にするには、下記のようにします。
ただし、これはまだ実験的な機能なので、将来は仕様を変更するかもしれません。
1 | python.exe -m exepy sample.exe counter.py |
上記を実行すると sample.exe
が生成されます。
サイズは 14MB ぐらいになりますが、テンポラリディレクトリにファイルを展開したりはしないので、かなり高速に実行されます。
Windows Subsystem 版のサポート
今回から pythonw.exe
のように、コンソール画面が表示されないバイナリを作っておきました。
こちらは、主に GUI を使うスクリプトを EXE 化する際に使うと便利です。
Python, tcl/tk の実装の勉強にもなり、 AppVeyor の利用の勉強にもなりましたが、すべての標準ライブラリを 1 バイナリに収めたので、そろそろ終了にする予定です。