Python.NETことIronPythonでプログラムをMSIL(アセンブリ)にコンパイルするときに、普通にやるとモジュールを使えない。Tools/Scripts/pyc.pyでコンパイルできて.exeと.dllを生成できるのだが、実行すると例外が発生して落ちてしまう。sysは組み込みらしく使えるものの、sys以外のモジュールはひどい状況だ。
最初はprintくらいしか使ってない非現実的な例しか見つからなくて困った。
例外の文字列を見ながら、モジュールも込みでコンパイルする(pyc.pyにモジュールのファイルをいちいち追加していく)と、何とか実行できるファイルを生成できるが、非常に長大なコンパイルオプションになり、面倒なことに。とてもやってられない。
import文を追跡してpyc.pyに渡すスクリプトを書けばいいのかなぁと思いながらググッていると、良い情報があった。
次のようなスクリプトを実行して、一度stdlib.dllを作っておく。
basedir=r"C:\Program Files\IronPython 2.7.1" import System import sys sys.path.append(basedir+r"\Tools\Scripts") import pyc files=System.IO.Directory.GetFiles(basedir+r"\Lib") files=filter(lambda f: f.endswith(".py"), files) pyc.Main(files+["/target:dll", "/out:stdlib"])
MLのメールのように/out:stdlib.dllとすると、stdlib.dll.dllというファイルになってしまいますね。
そして、コンパイルするスクリプトの中で、
import clr
clr.AddReference("stdlib")
と書いておけば、普通のPythonのスクリプトの多くが動く。例えば、以下のような。
import clr clr.AddReference("stdlib") import os print os.path.join("os", "path", "join")
↓
> \path\to\ipy \path\to\pyc.py /target:exe /main:hello.py
> hello.exe
os\path\join
全部のモジュールを1つのDLLに入れていて富豪的な解決策だが、まあ動けばいいんじゃないかな。
C#で何か書こうと思っていろいろ調べたりもしてみたが、配布可能な.exeをPythonで書けるならそのほうが書きやすいと思う。