Sam & Max » compilation http://sametmax.com Du code, du cul Sat, 07 Nov 2015 10:56:13 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 Peut-on compiler un programme Python ? 28 http://sametmax.com/peut-on-compiler-un-programme-python/ http://sametmax.com/peut-on-compiler-un-programme-python/#comments Sun, 11 May 2014 16:58:00 +0000 http://sametmax.com/?p=10245 C complet.]]> Sans répit, des hordes d’OP ont demandé sur Stackoverflow comment compiler un programme Python. La plupart du temps, pour des raisons d’obfuscation ou pour faire un joli .exe. Et inlassablement, les devs bienveillants leur répondaient que Python était un langage interprété, et donc non compilable.

Commença alors la lente fuite des impatients vers Go qui permettait de le faire si facilement.

Et puis arriva Cython, qui promettait de permettre de transformer du Python en C, afin de l’embarquer dans un autre code C, ou permettre des appels de C vers Python et inversement plus facile.

Cela visait les perfs, l’intégration, faire des dll/so en Python, et du coup, dans l’excitation, tout le monde a loupé un petit détail minuscule.

Les mecs avaient implémenté un compilateur Python => C complet.

En fait, Cython permet – et c’est la que c’est fun car c’est un effet de bord presque involontaire – de créer un programme compilé autonome en Python. Et avec la toolchain classique en plus.

Ça peut gérer les dépendances, et ça marche même avec des trucs compilés balèzes du genre PyQT.

Je sens le chapiteau se dresser sous la braguette, alors voici la démo…

Pour montrer qu’on ne fait pas que du “Hello World”, je vais utiliser des dépendances assez complexes : lxml (qui contient une extension C compilée), path.py, requests et docopt :

"""
    Download a file and save it to a location.
 
    Usage:
        downloader.py <target> [<location>]
"""
 
import requests
import docopt
 
from lxml.html import parse
from path import path
 
args = docopt.docopt(__doc__)
 
p = path(args['<location>']).realpath()
 
if p.isdir():
    p = p / path(args['<target>']).namebase
 
p.write_bytes(requests.get(args['<target>']).content)
 
title = parse(p).getroot().find('head').find('title').text
print('Downloaded "%s"' % title)

Je ne m’encombre pas de gestion d’erreurs, juste suffisamment d’appels pour faire travailler les dépendances.

Qui dit compilation, dit environnement. Pour ma part, je suis sous Ubuntu 14.04 et je vais me compiler un petit programme en Python 3, avec lesquels il me faut installer Cython et pip pour Python 3, de quoi compiler du C, et les dépendances de notre script :

$ sudo apt-get install gcc cython3 python-pip3 python3-lxml
$ pip3 install requests docopt path.py

Je n’ai même pas eu besoin d’installer les headers de lxml. Vive le Dieu des geeks.

L’utilisation de Cython dans notre cas est assez simple : on lui dit de transformer notre module en module C. --embed lui dit d’inclure l’interpréteur Python dedans.

$ cython3 downloader.py -o downloader.c --embed

On obtient un fichier C bien copieux :

$ head downloader.c
/* Generated by Cython 0.20.1post0 (Debian 0.20.1+git90-g0e6e38e-1ubuntu2) on Sun May 11 22:53:18 2014 */
 
#define PY_SSIZE_T_CLEAN
#ifndef CYTHON_USE_PYLONG_INTERNALS
#ifdef PYLONG_BITS_IN_DIGIT
#define CYTHON_USE_PYLONG_INTERNALS 0
#else
#include "pyconfig.h"
#ifdef PYLONG_BITS_IN_DIGIT
#define CYTHON_USE_PYLONG_INTERNALS 1

Il ne reste plus qu’à compiler ce dernier :

$ gcc -Os -I /usr/include/python3.4m  downloader.c -o download -lpython3.4m -lpthread -lm -lutil -ldl

J’ai mis -I /usr/include/python3.4m et -lpython3.4m car les headers de Python sont là dedans sur ma machine. Le reste, ce sont des options que j’ai copier / coller sur le Web car GCC a plus de flags qu’une ambassade américaine et que j’ai des choses plus importantes à retenir, comme par exemple la recette du guacamole.

On obtient un exécutable tout à fait exécutablatoire :

$ chmod u+x downloader
$ ./downloader # docopt marche :)
Usage:
       downloader.py <target> [<location>]

Et ça télécharge comme prévu :

$ ./downloader http://sametmax.com index.html
Downloaded "Sam & Max: Python, Django, Git et du cul | Deux développeurs en vadrouille qui se sortent les doigts du code"

Le script Python original fait 472 octets, le binaire obtenu 28,7 ko. Mais ce n’est pas standalone, puisque je n’ai pas demandé la compilation des dépendances (je viens de le tester sur une autre Ubuntu, il pleure que requests n’est pas installé). Je vous laisse vous faire chier à trouver comment faire pour répondre à votre cas de figure exact, mais ça implique d’utiliser cython_freeze.

Après tout, cet article est intitulé “Peut on compiler un programme Python ?” et non “Tuto pour rendre un script Python stand alone”. Je ne suis pas fou.

Apparemment ça marche sous Windows et Mac, même si je n’ai pas de quoi tester sous la main (bon, si j’ai une partition Windows, mais faut rebooter, tout réinstaller, merde quoi…).

Donc si vous voulez faire une application en Python et la rendre stand alone, l’obfusquer, pondre un exe pour rendre le téléchargement facile, rassurer les gens ou simplement ignorer les mises à jours des libs de l’OS, Cython est une bonne piste.

Petit bonus, votre programme sera plus rapide, car il saute l’étape d’interprétation. Bien entendu, vous récoltez les galères qui viennent avec la compilation, à savoir les différentes architectures, le linking vers les libs qui peuvent changer de place ou de versions, etc.

]]>
http://sametmax.com/peut-on-compiler-un-programme-python/feed/ 28
installer ffmpeg avec x264 et support mp3 8 http://sametmax.com/installer-ffmpeg-avec-x264-et-support-mp3/ http://sametmax.com/installer-ffmpeg-avec-x264-et-support-mp3/#comments Thu, 17 May 2012 15:11:32 +0000 http://sametmax.com/?p=383 ffmpeg n’est plus à présenter, c’est génial, ça fait tout et même le café. On peut trouver des versions executables ou choisir de compiler la sienne (souvent parceque les version exe sont sans support mp3 ou/et x264 pour des raisons de droits). Compiler ffmpeg avec les libs dont on a besoin relève du défi de Spartiate, je le HAIS du plus profond de mon âme juste pour ça.

Voici une manière de s’installer un petit ffmpeg sympatoche (si vous y arrivez) avec un max d’options, toutes ne vous seront pas utiles mais même si y en a trop je vous la met quand même comme j’ai coutume de dire à ces dames…

D’abord le truc chiant, trouver les libs, je mets les liens que j’ai à l’heure actuelle mais ça change souvent.
Attention il faut être root pour pouvoir installer les libs.

JE TIENS A PRECISER QUE JE HAIS FFMPEG POUR LA COMPILATION ! CA VA PLANTER !

support mp3 : libmp3lame

wget http://cdnetworks-kr-2.dl.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
tar xvf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --enable-shared
make & make install

JE HAIS FFMPEG (rappel)

support h264 : libx264

wget ftp://ftp.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xvf last_x264.tar.bz2
cd x264-snapshot-20120516-2245
./configure --enable-shared
make & make install

JE HAIS FFMPEG (je vous l’ai déjà dit ?)

support Theora : libtheora

wget http://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2
tar xvf libtheora-1.1.1.tar.bz2
cd  libtheora-1.1.1
./configure --enable-shared
make & make install

JE HAIS FFMPEG (jamais 2 sans 3)

support Vorbis : libvorbis

wget http://downloads.xiph.org/releases/vorbis/libvorbis-1.2.3.tar.gz
tar xvf libvorbis-1.2.3.tar.gz
cd  libvorbis-1.2.3
./configure --enable-shared
make & make install

JE HAIS FFMPEG (un dernier pour la route)

Enfin FFMPEG (on prend la derniere version sur Git): ffmpeg

git clone git://source.ffmpeg.org/ffmpeg.git 
./configure --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib --mandir=/usr/share/man  --enable-bzlib --disable-libdirac --enable-libfaac --enable-nonfree --enable-libmp3lame  --enable-libschroedinger --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid --enable-x11grab --enable-avfilter --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib --enable-runtime-cpudetect 
make & make install

Les problèmes à la compilation:
ça ne marche JAMAIS du premier coup ! Celui qui vous dit que ça s’est passé sans problème vous ment, vous méprise, vous pouvez l’égorger.
Quelques trucs pour essayer de debuger:
– si à la compilation de ffmpeg il vous dit qu’il ne trouve pas la librairie vérifier que le chemin vers celle-ci est présent dans le PATH de votre système, vous pouvez savoir où se trouve la lib en tapant locate (ou whereis) le_nom_de_la_lib
– si vous changez un paramètre dans configure pensez à faire un ‘make clear’
– éteindre l’ordi et aller vous coucher
– vérifier que le paramètre ‘enable-shared’ est bien dans le configure à la compilation des libs, par défaut il est activé mais on sait jamais

]]>
http://sametmax.com/installer-ffmpeg-avec-x264-et-support-mp3/feed/ 8