web-dev-qa-db-fra.com

Faire un exécutable en Cython

Joue avec cython. Programme normalement en Python, mais utilisé C dans une vie antérieure. Je ne sais pas comment créer un exécutable autonome.

J'ai téléchargé cython et je peux créer un fichier .pyx (c'est juste un fichier Python avec une extension .pyx) normal, qui s'exécute dans le Python = Shell, en utilisant: import pyximport; pyximport.install ()

Je peux générer un fichier .c sur la ligne de commande avec: cython file.pyx Je peux générer un fichier .so en construisant un setup.py standard et en exécutant:

setup.py build_ext --inplace

J'ai essayé de créer un exécutable à partir du fichier .so en utilisant gcc avec diverses options, mais j'ai toujours des tonnes de fichiers manquants, des en-têtes, etc. J'ai essayé de pointer vers des en-têtes de pratiquement partout, mais sans succès, et je ne suis pas vraiment familier avec ce que font toutes les options de gcc, ou même si je devrais utiliser gcc.

J'ai ici une déconnexion avec le fait que je peux exécuter mon programme dans le shell Python, mais pas sur la ligne de commande, (je ne veux pas que les utilisateurs aient à entrer dans le Shell, modules d'importation, etc.).

Qu'est-ce que j'oublie ici?

31
Paul Nelson

Ce que vous voulez, c'est le drapeau --embed Pour le compilateur Cython. Il n'y a pas une tonne de documentation dessus, mais this est ce que j'ai pu trouver. Il est lié à un simple exemple de travail.

Pour compiler le code source Cython dans un fichier C qui peut ensuite être compilé en un exécutable, vous utilisez une commande comme cython myfile.pyx --embed, Puis compilez avec le compilateur C que vous utilisez.

Lorsque vous compilez le code source C, vous devrez toujours inclure le répertoire avec les en-têtes Python et le lien vers la bibliothèque partagée Python partagée Python $ sur votre système ( un fichier nommé quelque chose comme libpython27.so ou libpython27.a si vous utilisez Python 2.7).

Edit: Voici quelques instructions supplémentaires sur la façon d'obtenir les commandes pour inclure les en-têtes appropriés et les lier aux bibliothèques appropriées.

Comme je l'ai dit plus tôt, vous devez exécuter le compilateur Cython comme ceci:

cython <cython_file> --embed

Pour compiler en utilisant gcc, vous devrez trouver où se trouvent les en-têtes python sur votre système (vous pouvez obtenir cet emplacement en exécutant distutils.sysconfig.get_python_inc() (vous devrez l'importer) Il s'agit probablement juste du sous-répertoire /include de votre répertoire d'installation Python.

Vous devrez également trouver la bibliothèque partagée python. Pour Python 2.7, ce serait libpython27.a Sous Windows ou libpython2.7.so sous Linux.

Votre commande gcc sera alors

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>

Il peut être judicieux d'inclure le drapeau -fPIC. Sur les machines Windows 64 bits, vous devrez également inclure les indicateurs -D MS_WIN64 Qui indiquent à mingw de compiler pour les fenêtres 64 bits.

Si vous compilez quelque chose qui dépend de NumPy, vous devrez également inclure le répertoire contenant les en-têtes NumPy. Vous pouvez trouver ce dossier en exécutant numpy.get_include() (à nouveau, après l'importation de numpy). Votre commande gcc devient alors

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>

Cette option de commande gcc guide peut être utile.

En outre, je vous recommande d'utiliser des vues de mémoire Cython si possible. Cela vous permettra de ne pas avoir à inclure les en-têtes NumPy et à inclure le fichier pxP NumPy dans votre fichier Cython. Il rend également les opérations de découpage plus faciles à optimiser pour le compilateur C.

32
IanH

Testé sur Ubuntu:

Installez Cython en utilisant ce qui suit (Python 2):

Sudo apt-get install cython

Pour Python 3:

Sudo apt-get install cython3

Pour compiler le code Python en une exécution de code C (changez cython en cython3 pour Python 3):

cython --embed -o example.c example.py

Cela générera le example.c fichier.

Compilez maintenant le example.c fichier:

gcc -Os -I /usr/include/python2.7 example.c -lpython2.7 -o example

Exécutez le fichier:

./example

Maintenant pour Python 3, quelque chose comme ça fonctionnera (non testé):

gcc -Os -I /usr/include/python3.6 example.c -lpython3.6 -o example

python3.x est la version de Python installée sur votre machine.

6
Rafael