Ironpython 2.6 .py - > 。可执行程序

时间:2009-10-16 13:21:54

标签: compilation ironpython

我已经尝试过使用py2exe(与ipy不兼容)和PYC(过时)。任何人都可以指向一个好的编译器的方向吗?

5 个答案:

答案 0 :(得分:29)

您可以使用pyc.py Python命令行编译器,它从2.6版本开始包含在IronPython中,以将Python脚本编译为可执行文件。您可以在硬盘上的%IRONPYTONINSTALLDIR%\Tools\Scripts\pyc.py找到它。

实施例

假设您有一个简单的脚本test.py,它只是打印出一些东西来控制台。您可以使用以下命令行将其转换为可执行文件(假设IronPython目录是当前目录,并且test.py也在其中):

ipy.exe Tools\Scripts\pyc.py /main:test.py /target:exe

注意:如果您使用表单而不想打开控制台窗口,则需要使用/target:winexe而不是/target:exe

结果将是两个文件test.dlltest.exetest.dll将包含您的实际脚本代码,而test.exe只是test.dll的启动器。如果包含文件

,则可以将此EXE和DLL分发给未安装IronPython的其他计算机
  • IronPython.dll
  • Microsoft.Dynamic.dll
  • Microsoft.Scripting.Core.dll
  • Microsoft.Scripting.Debugging.dll
  • Microsoft.Scripting.dll
  • Microsoft.Scripting.ExtensionAttribute.dll
  • IronPython.Modules.dll(有时需要)。

另请参阅博文IronPython - how to compile exe

答案 1 :(得分:6)

这是一个长期存在的问题,关于互联网上的信息很少。我能找到的唯一已知解决方案是使用SharpDevelop的http://community.sharpdevelop.net/blogs/mattward/archive/2010/03/16/CompilingPythonPackagesWithIronPython.aspx。但是,这个解决方案是不切实际的,因为任何半复杂的python项目都会进行大量的模块导入,SharpDevelop解决方案要求你创建一个项目 per import 。我开始尝试并放弃了大约30个新项目,更好地编写了一个自动化解决方案!

所以这是我的解决方案,我现在会警告你,它没有被充分理由作为一个合适的项目发布:

#!/usr/bin/env python
# CompileToStandalone, a Python to .NET ILR compiler which produces standalone binaries
# (C) 2012 Niall Douglas http://www.nedproductions.biz/
# Created: March 2012

import modulefinder, sys, os, subprocess, _winreg

if len(sys.argv)<2:
    print("Usage: CompileEverythingToILR.py <source py> [-outdir=<dest dir>]")
    sys.exit(0)

if sys.platform=="cli":
    print("ERROR: IronPython's ModuleFinder currently doesn't work, so run me under CPython please")
    sys.exit(1)

sourcepath=sys.argv[1]
destpath=sys.argv[2][8:] if len(sys.argv)==3 else os.path.dirname(sys.argv[0])
ironpythonpath=None
try:
    try:
        keyh=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\IronPython\\2.7\\InstallPath")
        ironpythonpath=_winreg.QueryValue(keyh, None)
    except Exception as e:
        try:
            keyh=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\IronPython\\2.7\\InstallPath")
            ironpythonpath=_winreg.QueryValue(keyh, "")
        except Exception as e:
            pass
finally:
    if ironpythonpath is not None:
        _winreg.CloseKey(keyh)
        print("IronPython found at "+ironpythonpath)
    else:
        raise Exception("Cannot find IronPython in the registry")

# What we do now is to load the python source but against the customised IronPython runtime
# library which has been hacked to work with IronPython. This spits out the right set of
# modules mostly, but we include the main python's site-packages in order to resolve any
# third party packages
print("Scanning '"+sourcepath+"' for dependencies and outputting into '"+destpath+"' ...")
searchpaths=[".", ironpythonpath+os.sep+"Lib"]
searchpaths+=[x for x in sys.path if 'site-packages' in x]
finder=modulefinder.ModuleFinder(searchpaths)
finder.run_script(sourcepath)
print(finder.report())
modules=[]
badmodules=finder.badmodules.keys()
for name, mod in finder.modules.iteritems():
    path=mod.__file__
    # Ignore internal modules
    if path is None: continue
    # Ignore DLL internal modules
    #if '\\DLLs\\' in path: continue
    # Watch out for C modules
    if os.path.splitext(path)[1]=='.pyd':
        print("WARNING: I don't support handling C modules at '"+path+"'")
        badmodules.append(name)
        continue
    modules.append((name, os.path.abspath(path)))
modules.sort()
print("Modules not imported due to not found, error or being a C module:")
print("\n".join(badmodules))
raw_input("\nPress Return if you are happy with these missing modules ...")

with open(destpath+os.sep+"files.txt", "w") as oh:
    oh.writelines([x[1]+'\n' for x in modules])
cmd='ipy64 '+destpath+os.sep+'pyc.py /main:"'+os.path.abspath(sourcepath)+'" /out:'+os.path.splitext(os.path.basename(sourcepath))[0]+' /target:exe /standalone /platform:x86 /files:'+destpath+os.sep+'files.txt'
print(cmd)
cwd=os.getcwd()
try:
    os.chdir(destpath)
    retcode=subprocess.call(cmd, shell=True)
finally:
    os.chdir(cwd)
sys.exit(retcode)

这是使用其新的独立二进制功能针对IronPython v2.7.2 RC1编写的,实际上它确实有效。你得到一个完全独立的独立.exe文件 - 它不需要安装任何其他东西。该脚本的工作原理是解析所提供脚本的导入并将整个批次发送到pyc.py.这是个好消息。

坏消息如下:

  1. IronPython v2.7.2 RC1的ModuleFinder似乎不起作用,因此需要使用CPython运行上述脚本。然后使用CPython的ModuleFinder,但使用IronPython的自定义运行时库。是的,我很惊讶它也有效......
  2. 二进制文件输出开始于大约8Mb。一个简单的单元测试在16Mb时称重。有很多东西不需要在那里,例如它引发了Wpf支持和更多,但它们仍然不小。
  3. 加载时间比非独立加载时间慢得多。想想在快速英特尔酷睿2上进行独立单元测试需要40秒,而对于非独立版本需要大约3秒。如果仅为x86编译,那将下降到十秒。
  4. 运行时性能比非独立运行时慢约40%。如果仅为x86编译,性能大约翻倍。这就是我离开/ platform:x86以上的原因。
  5. CPython的编码和编解码器支持中存在一个众所周知的错误,除非您手动指定,否则ModuleFinder根本不包含任何编解码器支持。因此,例如,如果您使用UTF-8和codecs.open(),那么您需要“从编码导入utf_8作为some_unique_identifier”来强制依赖。
  6. 以上假设修改了pyc.py,它可以采用/ files参数,因为命令行长度限制很容易被超出。您可以轻松地修改自己的pyc.py,如果没有,我已经提交了包含在下一个IronPython中的增强功能。
  7. 所以你去吧。它可行,但解决方案仍需要更多成熟。祝你好运!

答案 2 :(得分:4)

查看IronPython Samples Page

大约一半的页面:

Pyc - Python命令行编译器 此示例向开发人员展示了如何直接从IronPython脚本创建.NET可执行文件。下载中的readme.htm将帮助您入门。

IronPython的托管API可用于将Python脚本编译为DLL,控制台可执行文件或Windows可执行文件。本教程中包含的pyc.py脚本利用这些托管API,可用于编译其他Python脚本。它提供了各种标志,例如指定.NET程序集的目标平台的能力(例如,x64)。

虽然IronPython Hosting API生成的程序集是真正的.NET程序集,但Python语言的动态特性使得很难从其他.NET语言中使用它们。简而言之,这意味着不建议尝试将Python类型导入其他.NET语言(如C#)。

编辑:刚刚注意到你提到PYC已经过时了。是什么原因造成的? IronPython的工作人员似乎仍在推广它,所以我想它并没有那么遥远。

答案 3 :(得分:2)

我在尝试实施此解决方案时遇到了一些麻烦。 这就是我所做的:

  1. here下载pyc。 这花了我更多的搜索,因为它似乎很难找到pyc(我认为,有点过时)
  2. 我从zip文件中提取了pyc文件夹,并将其添加到C:\Program Files
  3. 中的IronPython文件夹中
  4. 现在我尝试在Windows控制台上运行此命令,如pyc下载中的自述文件所示: ipy.exe pyc.py other_hw.py /main:console_hw.py
  5. 它给了我这个错误:

    Traceback (most recent call last):
      File "pyc\pyc.py", line 35, in pyc\pyc.py
    AttributeError: attribute 'CompilerSink' of 'namespace#' object is read-only
    

    我对第35行进行了以下更改:

    之前:class PycSink(Hosting.CompilerSink):

    之后:class PycSink():

    由于权限,保存文件被证明是一个问题,因此我将pyc.py的内容复制到新的IDLE窗口(创建副本),删除了pyc.py的现有副本并保存了副本在pyc.py位于同一位置。这会处理权限问题并允许更改。

    进行此更改后,我再次尝试运行此命令:

    ipy.exe pyc.py other_hw.py /main:console_hw.py

    但是,这一次,我收到了以下错误:

    Traceback (most recent call last):
      File "pyc\pyc.py", line 170, in pyc\pyc.py
      File "pyc\pyc.py", line 56, in Main
    AttributeError: attribute 'ResourceFile' of 'namespace#' object is read-only
    

    在这一点上,我总结了现在凌晨1点,我明天有中期的事实,所以我解除了改变并关闭了它。

    如果您有解决方案或我的任何进步,请告诉我。

答案 4 :(得分:1)

是的,我发现编译exe太难了,所以我又回到了使用标准的Python。他们应该在IronPython网站上提供一个很好的教程