IronPythonメモ

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で書けるならそのほうが書きやすいと思う。

コメントを残す

メールアドレスが公開されることはありません。