Документация Python неофициальный перевод
Содержание страницы

3. Сборка расширений на C и C++ с помощью distutilsBuilding 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; в данном разделе рассматривается только сборка модулей-расширений.

Часто аргументы для 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 = 'http://docs.python.org/extending/building',
       long_description = '''
This is really just a demo package.
''',
       ext_modules = [module1])

В этом примере setup() вызывается с дополнительной метаинформацией, что рекомендуется при необходимости сборки дистрибутивных пакетов. Для самого расширения задаются определения препроцессора, каталоги include, каталоги библиотек и библиотеки. В зависимости от компилятора 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