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

Сборка расширений на 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 правильно формирует вызовы.

Распространение модулей расширения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