Создание исполняемого файла в Cython

Играли с cython. Обычно программа на Python, но используется C в предыдущей жизни. Я не могу понять, как сделать автономный исполняемый файл.

Я загрузил cython, и я могу создать файл .pyx(это обычный файл Python с расширением .pyx), который выполняется в оболочке Python, используя: import pyximport; pyximport.install()

Я могу создать .c файл в командной строке с помощью: cython file.pyx Я могу сгенерировать файл .so, создав стандартный файл setup.py и выполнив:

setup.py build_ext --inplace

Я попытался сделать исполняемый файл из .so файла, используя gcc с различными параметрами, но всегда имел массу недостающих файлов, заголовков и т.д. Попробовал называть заголовки практически повсеместно, но без успеха, и я не совсем знакомы с тем, что делают все параметры gcc, или даже если я должен использовать gcc.

У меня есть разрыв здесь с тем фактом, что я могу запускать свою программу в оболочке Python, но не в командной строке (я не хочу, чтобы пользователи приходили в оболочку, импортировали модули и т.д.).

Что мне здесь не хватает?

Ответ 1

То, что вы хотите, это флаг --embed для компилятора Cython. На нем нет тонны документации, но this - это то, что я смог найти. Он ссылается на простой рабочий пример.

Чтобы скомпилировать исходный код Cython в файл C, который затем можно скомпилировать в исполняемый файл, вы используете команду типа cython myfile.pyx --embed, а затем скомпилируете с использованием любого компилятора C.

Когда вы скомпилируете исходный код C, вам все равно нужно будет включить каталог с заголовками Python и ссылку на соответствующую общую библиотеку Python в вашей системе (файл с именем вроде libpython27.so или libpython27.a, если вы используя Python 2.7).

Изменить: Вот еще несколько инструкций о том, как получить команды для включения правильных заголовков и ссылки на соответствующие библиотеки.

Как я уже говорил, вам нужно запустить компилятор Cython следующим образом:

cython <cython_file> --embed

Чтобы скомпилировать gcc, вам нужно найти, где находятся заголовки python в вашей системе (вы можете получить это местоположение, запустив distutils.sysconfig.get_python_inc() (сначала вам нужно будет импортировать его). Вероятно, это только подкаталог /include в каталоге установки Python.

Вам также потребуется найти общую библиотеку python. Для Python 2.7 это было бы libpython27.a в Windows или libpython2.7.so в Linux.

Ваша команда gcc будет

gcc <C_file_from_cython> -I<include_directory> -L<directory_containing_libpython> -l<name_of_libpython_without_lib_on_the_front> -o <output_file_name>

Может быть разумным включить флаг -fPIC. На 64-битных машинах Windows вам также придется включать флаги -D MS_WIN64, которые сообщают mingw компилировать для 64-битных окон.

Если вы компилируете что-то, что зависит от NumPy, вам также нужно будет включить каталог, содержащий заголовки NumPy. Вы можете найти эту папку, запустив numpy.get_include() (опять же после импорта numpy). Затем ваша команда gcc станет

gcc <C_file_from_cython> -I<include_directory> -I<numpy_include_directory> -L<directory_containing_libpython> -l<name_of_libpython_without_lib_on_the_front> -o <output_file_name>

Эта опция команды gcc guide может быть полезна.

Кроме того, я бы рекомендовал, если возможно, использовать виды памяти Cython. Это сделает так, что вам не придется включать заголовки NumPy и включать файл NumPy pxd в ваш файл Cython. Он также упрощает операции разрезания для компилятора C.