3. Construire les extensions C et C++ avec *distutils*
******************************************************

Starting in Python 1.4, Python provides, on Unix, a special make file
for building make files for building dynamically-linked extensions and
custom interpreters.  Starting with Python 2.0, this mechanism (known
as related to Makefile.pre.in, and Setup files) is no longer
supported. Building custom interpreters was rarely used, and extension
modules can be built using distutils.

Building an extension module using distutils requires that distutils
is installed on the build machine, which is included in Python 2.x and
available separately for Python 1.5. Since distutils also supports
creation of binary packages, users don’t necessarily need a compiler
and distutils to install the extension.

Un paquet *distutils* contient un script "setup.py". C’est un simple
fichier Python, ressemblant dans la plupart des cas à :

   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])

Avec ce "setup.py" et un fichier "demo.c", lancer :

   python setup.py build

compilera "demo.c", et produira un module d’extension nommé "demo"
dans le dossier "build". En fonction du système, le fichier du module
peut se retrouver dans "build/lib.system", et son nom peut être
"demo.py" ou "demo.pyd".

Dans le fichier "setup.py", tout est exécuté en appelant la fonction
"setup". Elle prend une quantité variable d’arguments nommés,
l’exemple précédent n’en utilisant qu’une partie. L’exemple précise
des méta-informations pour construire les paquets, et définir le
contenu du paquet. Normalement un paquet contient des modules
additionnels, comme des modules sources, documentation, sous paquets,
etc. Referez-vous à la documentation de distutils dans Distribuer des
modules Python (Version historique) pour en apprendre plus sur les
fonctionnalités de distutils. Cette section n’explique que la
construction de modules d’extension.

Il est classique de pré-construire les arguments de "setup()", pour
mieux structurer le script pilote. Dans l’exemple précédent,
l’argument "ext_modules" donné à "setup()" est une liste de modules
d’extension, dont chacun est une instance de "Extension". Dans
l’exemple, l’instance défini une extension nommée "demo" qui est
construite en compilant un seul fichier source, "demo.c".

Dans la plupart des cas, construire une extension est plus complexe à
cause des bibliothèques et définitions de préprocesseurs dont la
compilation pourrait dépendre. C’est ce qu’on remarque dans l’exemple
plus bas.

   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])

Dans cet exemple, "setup()" est appelée avec des méta-informations
supplémentaires, ce qui est recommandé lorsque le paquet est amené à
être distribué. Pour l’extension elle même, elle donne des variables
de préprocesseur (*defines*), dossiers de bibliothèques, et
bibliothèques. En fonction du compilateur distutils peut lui donner
ces informations de différentes manières, par exemple, sur Linux, on
pourrait obtenir cette ligne :

   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

Ces lignes ne sont qu’à titre d’exemple, les utilisateurs de
*distutils* doivent avoir confiance en *distutils* qui fera les appels
correctement.


3.1. Distribuer vos modules d’extension
=======================================

Lorsqu’une extension a été construite avec succès, il existe trois
moyens de l’utiliser.

Typiquement, les utilisateurs vont vouloir installer le module, ils le
font en exécutant :

   python setup.py install

Les mainteneurs de modules voudront produire des paquets source, pour
ce faire ils exécuteront :

   python setup.py sdist

Dans certains cas, des fichiers supplémentaires doivent être joints à
la distribution source, c’est possible grâce à un fichier
"MANIFEST.in". Voir la documentation de distutils pour plus de
détails.

Si la distribution source a été construite avec succès, les
mainteneurs peuvent créer une distribution binaire. En fonction de la
plateforme, une des commandes suivantes peut être utilisée.

   python setup.py bdist_wininst
   python setup.py bdist_rpm
   python setup.py bdist_dumb
