Ironpython 2.6 .py -> .exe

Я уже пытался использовать py2exe (не совместимый с ipy) и PYC (устарел). Кто-нибудь может указать мне в направлении хорошего компилятора?

5 ответов

Ты можешь использовать pyc.py компилятор командной строки Python, который включен в IronPython начиная с версии 2.6 для компиляции скрипта 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.dll а также test.exe, test.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 - как скомпилировать exe.

Это давний вопрос, о котором в Интернете очень мало информации. Единственное известное решение, которое я могу найти, находится по адресу http://community.sharpdevelop.net/blogs/mattward/archive/2010/03/16/CompilingPythonPackagesWithIronPython.aspx котором используется SharpDevelop. Однако это решение нецелесообразно, поскольку любой полусложный проект на Python будет выполнять МНОЖЕЕ импорта модулей, а решение SharpDevelop требует создания проекта для каждого импорта. Я начал с этого и сдался после тридцати новых проектов, лучше написать автоматизированное решение!

Итак, вот мое решение, и я предупрежу вас прямо сейчас, что оно не выпущено как правильный проект по уважительной причине:

#!/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. ModuleFinder в IronPython v2.7.2 RC1 не работает, поэтому приведенный выше сценарий необходимо запустить с использованием CPython. Затем он использует CPython ModuleFinder, но против настроенной библиотеки времени выполнения IronPython. Да, я поражен, что это работает так же хорошо...
  2. Выходные данные бинарных файлов начинаются с 8 МБ. Простой модульный тест весил 16 Мб. Есть много вещей, которые не должны быть там, например, он добавляет поддержку Wpf и немного больше, но все же они не малы.
  3. Время загрузки намного медленнее, чем в автономном режиме. Подумайте о сорока секундах для автономного модульного теста на быстром Intel Core 2 и о трех секундах для автономного. Если скомпилировано только для 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.

Итак, поехали. Это работает, но решение все еще нуждается в более зрелом подходе. Удачи!

Проверьте страницу образцов IronPython

Примерно на полпути вниз по странице:

Pyc - компилятор командной строки Python В этом примере показано, как создавать исполняемые файлы.NET непосредственно из сценариев IronPython. Readme.htm в загрузке поможет вам начать.

Хостинговые API IronPython могут использоваться для компиляции скриптов Python в библиотеки DLL, исполняемые файлы консоли или исполняемые файлы Windows. Сценарий pyc.py, включенный в это руководство, использует эти API-интерфейсы хостинга и может использоваться для компиляции других скриптов Python. Он предоставляет различные флаги, такие как возможность указать целевую платформу сборки.NET (например, x64).

Хотя сборки, создаваемые API-интерфейсами IronPython Hosting, являются настоящими.NET-сборками, динамическая природа языка Python затрудняет использование их из других языков.NET. Короче говоря, это означает, что не рекомендуется пытаться импортировать типы Python в другие языки.NET, такие как C#.

Изменить: Только что заметил, что вы упомянули PYC устарел. Что делает это так? Команда IronPython, похоже, все еще продвигает его, поэтому я думаю, что это не так уж далеко.

У меня была небольшая проблема, пытаясь реализовать это решение. Вот что я сделал:

  1. Загрузите pyc отсюда. Это заняло у меня больше поисков, чем следовало бы, потому что кажется, что Pyc трудно найти (и я думаю, немного устарели)
  2. Я извлек папку pyc из zip-файла и добавил ее в свою папку IronPython в C:\Program Files
  3. Теперь я попытался запустить эту команду на консоли Windows, как указано в readme в загрузке pyc:ipy.exe pyc.py other_hw.py /main:console_hw.py

Это дало мне эту ошибку:

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 час ночи, и у меня завтра среднесрочный период, поэтому я отменил изменения и закрыл их.

Пожалуйста, дайте мне знать, если у вас есть решение или какие-либо улучшения по моему.

Да, мне было слишком сложно скомпилировать исполняемый файл, поэтому я вернулся к использованию стандартного Python. Они должны дать хороший учебник по этому на сайте IronPython

Другие вопросы по тегам