Скомпілювати основну програму Python за допомогою Cython


81

У мене є програма Python2.6, яка може завантажувати модулі Python, скомпільовані у файли .so, використовуючи Cython. Я використовував Cython для компіляції модулів .py у файли .so, і все працює нормально.

Це файл setup.py, який я використовую з Cython:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension("ldap", ["ldap.pyx"]),
    Extension("checker", ["checker.pyx"]),
    Extension("finder", ["finder.pyx"]),
    Extension("utils", ["utils.pyx"]),
]

setup(
  name = 'bchecker',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

Отже, я знаю, що можу компілювати модулі Python за допомогою Cython (мабуть, Cython створює файли „C“ з моїх файлів Python, а потім компілює їх), але чи можу я скомпілювати свою основну програму Python до чогось, що я можу виконати на платформі Linux? Якщо так, то вдячний приклад командного рядка Cython. Дякую.


4
Чи була якась із цих відповідей корисною? Ви це спрацювали? Якщо так, прийміть відповідь
Майк Пеннінгтон,

3
Я сумніваюся, що це коли-небудь буде позначено - користувача востаннє бачили через день після дати редагування питання.
Broken Man

Відповіді:


152

На відміну від тверджень Адама Матана та інших, ви насправді можете створити єдиний виконуваний двійковий файл, використовуючи Cython, із чистого файлу Python (.py).

Так, Cython призначений для використання як зазначено - як спосіб спрощення написання модулів розширення C / C ++ для середовища виконання CPython python.

Але, як натякає нудзо в цьому коментарі , ви можете використовувати --embedперемикач у командному рядку.

Ось надзвичайно простий приклад. Я виконую це на робочій станції Debian Sid, використовуючи python3 та cython3 ..

Переконайтеся, що заздалегідь встановлені пакети python-dev або python3-dev .

1) Створіть дуже просту програму Python під назвою hello.py

$ cat hello.py

print ("Привіт Світ!")

2) Використовуйте Cython для компіляції вашої програми python в C ...

cython3 --embed -o hello.c hello.py

3) Використовуйте GCC для компіляції hello.c у виконуваний файл, який називається hello ...

gcc -Os -I /usr/include/python3.3m -o hello hello.c -lpython3.3m -lpthread -lm -lutil -ldl

4) Ви отримаєте файл із назвою hello ...

$ файл привіт

привіт: ELF 64-розрядна версія LSB, x86-64, версія 1 (SYSV), динамічно пов’язана (використовує спільні бібліотеки), для GNU / Linux 2.6.32, BuildID [sha1] = 006f45195a26f1949c6ed051df9cbd4433e1ac23, не зачищена

$ ldd hello
linux-vdso.so.1 (0x00007fff273fe000)
libpython3.3m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.3m.so.1.0 (0x00007fc61dc2c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc61da0f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc61d70b000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fc61d508000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc61d304000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc61cf5a000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fc61cd52000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fc61cb28000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc61c90f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc61e280000)

У цьому випадку виконуваний файл динамічно пов'язаний з Python 3.3 у моїй системі Debian.

5) біжи привіт ...

$ ./ привіт

Привіт Світ!

Як бачите, використовуючи цей метод, ви можете в основному використовувати Cython для перетворення ваших чистих програм Python у виконуваний компільований об'єктний код.

Я використовую цей метод для значно складніших програм - наприклад, повнофункціональної програми Python / PySide / Qt.

Для різних версій Python ви пристосовуєте gcc -Iта -lперемикаєтеся відповідно до вимог .

Потім ви можете упакувати виконуваний файл як файл розподілу (.deb тощо) без необхідності пакувати файли Python / PySide / Qt - перевага полягає в тому, що ваша програма все одно зможе працювати навіть після оновлення дистрибутиву до того самого версії Python тощо для цього дистрибутиву.


чи можна цей метод вбудовування використовувати для створення динамічної бібліотеки замість виконуваного файлу?
denfromufa

5
Він не компілює модулі (модулі) у виконуваний файл. Чи можна мати портативний виконуваний файл, тобто кожен модуль, який був імпортований у вихідному коді, буде скомпільований у цей виконуваний файл. @BrokenMan
Devesh Saini

1
@DeveshSaini Я не витрачав час, намагаючись зрозуміти це. Єдиним способом, яким мені вдалося отримати повномасштабну програму python + Pyside для компіляції, як зазначено вище, було розробити програму звичайним способом - багато включають оператори <mymodule> + тестування з інтерпретатором. Потім, коли все готово, я вручну вставляю весь включений код і коментую відповідні оператори include, які вони замінили. Так, це небажано, але, як я вже говорив спочатку, я не витратив час, щоб побачити, як я можу скомпілювати лише основну процедуру та зв’язати включені модулі між собою.
Broken Man

3
А як щодо статичного зв’язування libpython?
Джеймс Міллс,

4
Для python 2.7 cython --embed -o /tmp/a.c a.pyтаgcc -Os -I /usr/include/python2.7 -o /tmp/a/tmp/a.c -lpython2.7 -lpthread -lm -lutil -ldl
dsaydon

17

Погляньте на відповіді на питання Чи може Cython скомпілювати в EXE? які, на відміну від усіх інших відповідей тут, говорять, що так, можна скомпілювати у виконуваний файл.

Посилання на Embedding Cython, здається, гарне місце для початку, але це не головне призначення Cython, тому я не знаю, наскільки це було б просто.


1
Дякую за посилання. Я також підозрюю, що це можливо, оскільки я використовую Python для створення файлів .so, що містять виконуваний код.
mozza

4

Не знаю, допоможе це чи ні, але Нудзо правильний. Ви можете отримати це за допомогою, cython --embed -o main.o main.pyа потім я намагаюся скласти результат за допомогою cl / EHsc


-21

Ви не можете, Cython не створений для компіляції Python і не перетворює його на виконуваний файл.

Щоб створити файл .exe, використовуйте py2exe .

Щоб створити пакет для Mac або Linux, використовуйте процес упаковки regulard, оскільки в програмі на мові сценарію в Unix env немає нічого конкретного.


2
Ну, це дозволяє мені перетворити свої .py-файли на .so-файли. Дивіться наведений вище сценарій, який я використовую Чи не містять файли .so виконуваний код?
mozza

Це не мета. Cython призначений для компіляції розширень Python на C / C ++, а не для перетворення скриптів Python на виконувані файли.
e-satisfa

10
Дезінформація. Є те, cython --embedщо може створювати виконувані файли за допомогою вбудованого Python.
нудзо

Отриманий виконуваний файл все ще залежить від libpython, якщо ви не зв’яжете його статично. Крім того, він не створить один виконуваний файл із усіх ваших файлів, а один виконуваний файл із вашої точки входу.
e-satisfa

2
@ e-satisfa Так, виконуваний файл буде динамічно пов'язаний з версією libpython, з якою він був складений на той час. У чому проблема? Якщо це для Linux, і якщо ви плануєте розповсюджувати свою програму, ви просто упаковуєте її в будь-який формат дистрибутива Linux, на який ви націлюєтесь, як і в будь-який інший двійковий пакет. наприклад, myapp_1_wheezy_amd64.deb - це ваш скомпільований додаток python, зв’язаний проти цього python2 або python3 для цього дистрибутива. Для Windows просто поставте необхідний python. Знову ж таки, я не бачу тут проблеми чи заперечення.
Broken Man
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.