Содержание страницы
3. Сборка расширений на C и C++ с помощью distutils¶Building C and C++ Extensions with distutils
Начиная с Python 1.4, в Unix Python предоставлял специальный make-файл для создания make-файлов для сборки динамически загружаемых расширений и пользовательских интерпретаторов. Начиная с Python 2.0, этот механизм (известный как связанный с Makefile.pre.in и файлами Setup) больше не поддерживается. Сборка пользовательских интерпретаторов использовалась редко, а модули расширения можно собирать с помощью distutils.
Для сборки модуля расширения с помощью distutils требуется, чтобы distutils был установлен на сборочной машине; он входит в состав Python 2.x и доступен отдельно для Python 1.5. Поскольку distutils также поддерживает создание бинарных пакетов, пользователям не обязательно иметь компилятор и distutils для установки расширения.
Пакет distutils содержит управляющий скрипт setup.py. Это обычный
файл Python, который в простейшем случае может выглядеть так:
from distutils.core import setup, Extension
module1 = Extension('demo',
sources = ['demo.c'])
setup (name = 'PackageName',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module1])
Имея этот setup.py и файл demo.c, при выполнении
python setup.py build
скомпилирует demo.c и создаст модуль-расширение с именем demo в
каталоге build. В зависимости от системы файл модуля окажется
в подкаталоге build/lib.system и может иметь имя вроде
demo.so или demo.pyd.
В setup.py всё выполнение осуществляется вызовом setup
функции. Она принимает переменное количество именованных аргументов, из которых
в примере выше используется лишь часть. В частности, в примере задаётся
метаинформация для сборки пакетов, а также содержимое
пакета. Обычно пакет содержит дополнительные модули, такие как Python
модули исходного кода, документацию, вложенные пакеты и т.д. Обратитесь к документации distutils
в Распространение модулей Python (устаревшая версия), чтобы узнать больше о возможностях
distutils; в данном разделе описывается только сборка модулей-расширений.
Часто аргументы для setup() вычисляют заранее, чтобы лучше структурировать
скрипт-драйвер. В примере выше аргумент ext_modules для
setup() представляет собой список модулей-расширений, каждый из которых является экземпляром
Extension. В примере этот экземпляр
определяет расширение с именем demo, которое собирается компиляцией одного исходного
файла, demo.c.
Во многих случаях сборка расширения сложнее, поскольку могут потребоваться дополнительные определения препроцессора и библиотеки. Это показано в примере ниже.
from distutils.core import setup, Extension
module1 = Extension('demo',
define_macros = [('MAJOR_VERSION', '1'),
('MINOR_VERSION', '0')],
include_dirs = ['/usr/local/include'],
libraries = ['tcl83'],
library_dirs = ['/usr/local/lib'],
sources = ['demo.c'])
setup (name = 'PackageName',
version = '1.0',
description = 'This is a demo package',
author = 'Martin v. Loewis',
author_email = 'martin@v.loewis.de',
url = 'https://docs.python.org/extending/building',
long_description = '''
This is really just a demo package.
''',
ext_modules = [module1])
В этом примере setup() вызывается с дополнительной метаинформацией, что
рекомендуется, когда нужно собрать пакеты распространения. Для самого расширения
указываются макросы препроцессора, каталоги включаемых файлов, каталоги библиотек
и сами библиотеки. В зависимости от компилятора distutils передаёт эту
информацию компилятору разными способами. Например, в Unix это может
привести к командам компиляции
gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/local/include -I/usr/local/include/python2.2 -c demo.c -o build/temp.linux-i686-2.2/demo.o
gcc -shared build/temp.linux-i686-2.2/demo.o -L/usr/local/lib -ltcl83 -o build/lib.linux-i686-2.2/demo.so
Эти строки приведены только для демонстрации; пользователи distutils должны доверять, что distutils правильно формирует вызовы.
3.1. Распространение модулей-расширений¶Distributing your extension modules
Когда расширение успешно собрано, есть три способа его использовать.
Конечные пользователи обычно хотят установить модуль; они делают это, выполняя
python setup.py install
Сопровождающие модуля должны создавать исходные пакеты; для этого они выполняют
python setup.py sdist
В некоторых случаях в исходный дистрибутив необходимо включить дополнительные файлы;
это делается через файл MANIFEST.in; обратитесь к документации по distutils
за подробностями.
Если дистрибутив исходного кода был успешно собран, сопровождающие могут также создать бинарные дистрибутивы. В зависимости от платформы, для этого можно использовать одну из следующих команд.
python setup.py bdist_wininst
python setup.py bdist_rpm
python setup.py bdist_dumb