Ceci est une ancienne révision du document !
Faire un joli programme qui marche est une (bonne) chose, le diffuser en est une autre.
Il faut en effet que le PC du nouvel utilisateur dispose déjà des programmes nécessaires de Python, de PyQt4 (, etc…), avec les bonnes versions, sans lesquels votre programme ne fonctionnera pas (et vous porterez le chapeau…).
Alors, il est important de pouvoir diffuser votre programme, accompagné de toutes les bibliothèques qui lui permettront de fonctionner correctement, même si l'utilisateur n'a rien installé du tout! C'est l'objet du présent tuto.
On va utiliser le logiciel cx_freeze pour cela (http://cx-freeze.sourceforge.net/). Il a l'avantage d'être multiplateforme (Windows-Linux). Il faudra bien sûr l'utiliser sous Windows pour avoir la version Windows et sous Linux pour avoir la version Linux, car les bibliothèques ne sont pas les mêmes.
On va étudier ici l'utilisation de cx_freeze sur Windows XP, Vista ou 7.
Pour mettre au point ce tuto, j'ai utilisé deux Windows:
Mon but est de pouvoir transporter sur la version “brute d'install”, le programme traité par cx_freeze.
Pour qu'un programme PyQt4 fonctionne sous Windows, il faut peu de choses:
Ces 2 logiciels existent sous forme de binaire, et donc sont très faciles à installer.
Et c'est tout!
cx_freeze est aussi présenté sous forme de binaire facile à installer.
Choisir de préférence une verson >=4.2.1. (http://cx-freeze.sourceforge.net/)
Voilà, vous avez le cx_freeze le plus récent!
Il existe plusieurs façons d'utiliser cx_freeze, et j'ai choisi l'utilisation de setup.py (même méthode que pour py2exe sous Windows). L'avantage est que, si on débrouille bien, le même setup.py pourra être utilisé sous Windows et sous Linux.
J'utilise un “modèle” de setup.py que je fais évoluer au gré de mes programmes, et, il faut bien le dire, au gré de mes (nombreux et longs) tâtonnements.
Voilà les particularités des options de setup.py pour des programmes complexes PyQt4 avec QtSql (se reporter au code plus bas):
Et c'est tout: avec ça, vous récupérez un répertoire avec tout ce qu'il faut pour une exécution “standalone” sur un Windows dans lequel il n'y a ni Python, ni PyQt4!
Voilà un exemple de code du setup.py que j'ai utilisé pour un logiciel de concours photos pour un photo-club (environ 10000 lignes de code et utilisation de QtSql).
Pour que le setup.py puisse, sans modification, servir sous Windows et sous Linux, il faudra utiliser à plusieurs endroits les tests habituels de plateforme (if sys.platform == “win32” ou if sys.platform == “linux2”) puisque certaines adresses de bibliothèques seront différentes. Peut-être que des adaptations mineures permettraient l'utilisation sur Mac OSX et plus (Solaris, …) mais je n'ai aucune possibilité d'essayer.
#!/usr/bin/python # -*- coding: utf-8 -*- # Python 2.7 # 02/2011 import sys, os from cx_Freeze import setup, Executable ############################################################################# # preparation des options # chemins de recherche des modules path = sys.path + ["biblio", "consultations", "etatbase", "etiquettes", "jugement", "publications", "retourcolis", "saisiebord", "verifications", "vuetable"] # options d'inclusion/exclusion des modules includes = ["sip"] excludes = [] packages = [] # copier les fichiers et/ou répertoires et leur contenu: includefiles = [("aide", "aide")] if sys.platform == "linux2": includefiles += [(r"/usr/lib/qt4/plugins/sqldrivers","sqldrivers")] elif sys.platform == "win32": includefiles += [(r"C:\Python27\Lib\site-packages\PyQt4\plugins\sqldrivers","sqldrivers")] else: pass # inclusion éventuelles de bibliothèques supplémentaires binpathincludes = [] if sys.platform == "linux2": # pour que les bibliothèques de /usr/lib soient copiées aussi binpathincludes += ["/usr/lib"] # construction du dictionnaire des options options = {"path": path, "includes": includes, "excludes": excludes, "packages": packages, "include_files": includefiles, "bin_path_includes": binpathincludes } ############################################################################# # preparation des cibles base = None if sys.platform == "win32": base = "Win32GUI" cible_1 = Executable( script = "concoursphotos.pyw", base = base, compress = True, icon = None, ) ############################################################################# # creation du setup setup( name = "concoursphotos", version = "1", description = "Traitement de concours photos sous Windows et Linux", author = "Tyrtamos", options = {"build_exe": options}, executables = [cible_1] )
Une fois le setup.py écrit et mis dans la racine du répertoire du programme à traiter (\chemin par exemple):
python setup.py build
On peut aussi aller plus loin en encapsulant les fichiers obtenus dans un programme d'installation comme “innosetup” (http://www.jrsoftware.org/isinfo.php). Vous avez un bon tutoriel en français ici: ftp://ftp-developpez.com/jlelong/tutoriels/delphi/deployer-votre-application-innosetup/installation-innosetup.pdf. Vous obtiendrez alors un programme diffusé par un seul fichier qui s'installera et se désinstallera comme n'importe quel logiciel Windows: les utilisateurs se sauront même pas que c'est du Python…
Amusez-vous bien!