Outils pour utilisateurs

Outils du site


cx_freeze

Distribuer une application avec cx-freeze (multiplateforme)

[modif 24/12/2014]

Objectif

Python est de plus en plus utilisé sur nos machines (et c'est très bien!), mais en contrepartie, quand on diffuse un logiciel en Python, on ne devrait pas être soumis à l'existence d'un python installé, ou à sa version: il faut donc que le logiciel diffusé intègre son propre interpréteur Python ainsi que les modules et bibliothèques utilisés.

C'est l'objet de la présente page: on va utiliser cx_Freeze pour cela, qui a l'avantage d'être multiplateforme.

Site de référence: http://cx-freeze.sourceforge.net/

Installation de cx_Freeze

Comme on voit sur la page des téléchargements, cx_Freeze existe pour la partie binaire pour chaque version de Python. A ce jour (12/2014), il existe pour Python 2.7, 3.3 et 3.4.

Sous Windows, c'est facile: on télécharge sur le site de cx_Freeze et on installe la bonne version (celle qui correspond à la version du Python qu'on a!) comme n'importe quel logiciel Windows.

Sous Linux, c'est un peu plus complexe. Il y a un paquet rpm pour centos, et les sources (.tar.gz) pour les autres. Cependant, il est très probable que cx_Freeze fasse déjà partie des logiciels disponibles pour votre distribution: prenez celle-là!

Sous Mac Os X, je ne sais pas, mais on en parle dans la mailing-list: http://sourceforge.net/mailarchive/forum.php?forum_name=cx-freeze-users

Code proposé

J'utilise depuis pas mal de temps déjà la méthode avec setup.py. En fait, j'utilise toujours le même setup.py que j'améliore petit à petit au fur et à mesure de mes expériences.

Voilà mon setup.py vide:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Python 3
 
"""
Icone sous Windows: il faut:
=> un xxx.ico pour integration dans le exe, avec "icon=xxx.ico"
=> un xxx.png pour integration avec PyQt4 + demander la recopie avec includefiles.
"""
 
import sys, os
from cx_Freeze import setup, Executable
 
#############################################################################
# preparation des options
 
# chemins de recherche des modules
# ajouter d'autres chemins (absolus) si necessaire: sys.path + ["chemin1", "chemin2"]
path = sys.path
 
# options d'inclusion/exclusion des modules
includes = []  # nommer les modules non trouves par cx_freeze
excludes = []
packages = []  # nommer les packages utilises
 
# copier les fichiers non-Python et/ou repertoires et leur contenu:
includefiles = []
 
if sys.platform == "win32":
    pass
    # includefiles += [...] : ajouter les recopies specifiques à Windows
elif sys.platform == "linux2":
    pass
    # includefiles += [...] : ajouter les recopies specifiques à Linux
else:
    pass
    # includefiles += [...] : cas du Mac OSX non traite ici
 
# pour que les bibliotheques binaires de /usr/lib soient recopiees aussi sous Linux
binpathincludes = []
if sys.platform == "linux2":
    binpathincludes += ["/usr/lib"]
 
# niveau d'optimisation pour la compilation en bytecodes
optimize = 0
 
# si True, n'affiche que les warning et les erreurs pendant le traitement cx_freeze
silent = True
 
# construction du dictionnaire des options
options = {"path": path,
           "includes": includes,
           "excludes": excludes,
           "packages": packages,
           "include_files": includefiles,
           "bin_path_includes": binpathincludes,
           "create_shared_zip": False,  # <= ne pas generer de fichier zip
           "include_in_shared_zip": False,  # <= ne pas generer de fichier zip
           "compressed": False,  # <= ne pas generer de fichier zip
           "optimize": optimize,
           "silent": silent
           }
 
# pour inclure sous Windows les dll system de Windows necessaires
if sys.platform == "win32":
    options["include_msvcr"] = True
 
#############################################################################
# preparation des cibles
base = None
if sys.platform == "win32":
    base = "Win32GUI"  # pour application graphique sous Windows
    # base = "Console" # pour application en console sous Windows
 
icone = None
if sys.platform == "win32":
    icone = "icone.ico"
 
cible_1 = Executable(
    script="monprogramme1.pyw",
    base=base,
    compress=False,  # <= ne pas generer de fichier zip
    copyDependentFiles=True,
    appendScriptToExe=True,
    appendScriptToLibrary=False,  # <= ne pas generer de fichier zip
    icon=icone
    )
 
cible_2 = Executable(
    script="monprogramme2.pyw",
    base=base,
    compress=False,
    copyDependentFiles=True,
    appendScriptToExe=True,
    appendScriptToLibrary=False,
    icon=icone
    )
 
#############################################################################
# creation du setup
setup(
    name="monprogramme",
    version="1.00",
    description="monprogramme",
    author="auteurduprogramme",
    options={"build_exe": options},
    executables=[cible_1, cible_2]
    )

Utilisation:

A titre d'exemple: dans un répertoire, j'ai un développement comportant 2 programmes .py à lancer en exe: monprogramme1.py et monprogramme2.py. Il peut y avoir dans ce répertoire des modules personnels utilisés par ces 2 fichiers .py.

On place le setup.py dans ce répertoire, et on le configure en fonction du programme.

On prend alors la console (cmd pour Windows), on se loge dans le répertoire en question (avec “cd chemin”), et on fait:

python setup.py build

Il vient alors des lignes qui indiquent le déroulement du traitement par cx_freeze. On lit soigneusement pour voir s'il y a des erreurs. En cas d'erreur, il faut corriger le setup.py et/ou corriger directement les programmes.

Sous Windows, le résultat se trouve dans le sous-répertoire build/exe.win32-3.4 (exemple pour Python 3.4), qui contient les 2 exécutables voulus “monprogramme1.exe” et “monprogramme2.exe” accompagnés de toutes les bibliothèques nécessaires, y compris bien entendu de l'interpréteur Python.

Le répertoire à diffuser est donc dans cet exemple: 'exe.win32-3.4'. On peut le renommer en “monprogramme” ou en n'importe quoi d'autre. On peut aussi le diffuser sous forme d'archive zip.

Il est bien sûr possible d'utiliser en plus un “installeur” qui permettra à un utilisateur d'installer ce programme comme n'importe quel autre. Il y a des possibilités sous cx_freeze de faire cela, mais en ce qui me concerne, j'utilise plutôt “inno Setup” sous Windows (http://www.jrsoftware.org/isinfo.php). Sous Linux, on peut créer des paquets (rpm, …) mais je n'ai jamais essayé.

On peut, bien entendu traiter des cas plus complexes en utilisant toutes les nombreuses options possibles: voir http://cx-freeze.readthedocs.org/en/latest/index.html.

J'essaie de ne gérer qu'un seul setup.py pour Windows et Linux, quitte à mettre les particularités sous les tests “if sys.platform==…” Mais l'exécutable Windows doit être construit sous Windows, et l'exécutable Linux sous Linux, à cause des bibliothèques à intégrer qui sont différentes.


Amusez-vous bien!

cx_freeze.txt · Dernière modification: 2014/12/24 12:21 de tyrtamos

Outils de la page