Packaging

Les propositions de correctifs ou d'exercices pour Pyromaths.

Modérateur : Développeurs

Avatar de l’utilisateur
Yves
Messages : 472
Inscription : 21 janv. 2009, 20:40
Contact :

Re: Packaging

Message par Yves » 21 avr. 2013, 19:05

Je vais mettre à jour mon environnement de développement. Pourrais-tu m'indiquer les versions de Qt, SIP et PyQt que tu as installé ?

Avatar de l’utilisateur
djinn
Messages : 183
Inscription : 03 mars 2013, 10:38

Re: Packaging

Message par djinn » 21 avr. 2013, 19:56

Sauf erreur de ma part: Qt-4.7.4, SIP-4.14.5, PyQt-4.10.
De nouvelles versions de SIP et PyQt viennent de sortir aujourd'hui. :-)

Avatar de l’utilisateur
Yves
Messages : 472
Inscription : 21 janv. 2009, 20:40
Contact :

Re: Packaging

Message par Yves » 21 avr. 2013, 22:05

Merci, avec les versions que tu indiques, ça fonctionne :)

Cependant, de nombreux frameworks superflus viennent alourdir l'application:
ls ~/Pyromaths.app/Contents/Frameworks

Python.framework	QtMultimedia.framework	QtTest.framework
QtCore.framework	QtNetwork.framework	QtWebKit.framework
QtDBus.framework	QtOpenGL.framework	QtXml.framework
QtDeclarative.framework	QtScript.framework	QtXmlPatterns.framework
QtDesigner.framework	QtScriptTools.framework	phonon.framework
QtGui.framework		QtSql.framework
QtHelp.framework	QtSvg.framework
Les frameworks Python, QtCore et QtGui sont suffisants.

Avatar de l’utilisateur
djinn
Messages : 183
Inscription : 03 mars 2013, 10:38

Re: Packaging

Message par djinn » 21 avr. 2013, 22:22

Oui. Du coup, en l'état le dmg fait dans les 40Mo! :P
Tu as une idée sur la façon de régler ça (autrement qu'en effaçant tout le superflu dans standalone.sh par exemple)?
Yves a écrit :Les frameworks Python, QtCore et QtGui sont suffisants.
Ça c'est l'info qui me manquait pour faire le ménage! J'attendais ton expertise… :)

Avatar de l’utilisateur
Yves
Messages : 472
Inscription : 21 janv. 2009, 20:40
Contact :

Re: Packaging

Message par Yves » 21 avr. 2013, 23:13

Quelques rm -rf dans standalone.sh règlent le problème mais une solution plus propre serait effectivement mieux. :)

Pyromaths a également enflé car on est passé d'une architecture i386 à une double architecture i386 (32-bit) / x86_64 (64-bit).

Avatar de l’utilisateur
djinn
Messages : 183
Inscription : 03 mars 2013, 10:38

Re: Packaging

Message par djinn » 21 avr. 2013, 23:20

Yves a écrit :Quelques rm -rf dans standalone.sh règlent le problème mais une solution plus propre serait effectivement mieux. :)
Essaie ça: :-)
from glob import glob
from setuptools import setup, find_packages

OPTIONS = dict(
        plist='Info.plist',
        argv_emulation=True,
        packages=['lxml'],
        dylib_excludes=['QtDBus', 'QtDeclarative', 'QtDesigner', 'QtHelp',
                        'QtMultimedia', 'QtNetwork', 'QtScript', 'QtScriptTools',
                        'QtSql', 'QtSvg', 'QtTest', 'QtWebKit', 'QtXml',
                        'QtXmlPatterns', 'phonon']
    )
setup(
    app         = ['../../src/pyromaths.py'],
    packages    = find_packages('../../src'),
    package_dir = {'': '../../src'},
    data_files  = ['pyromaths.icns', 'qt.conf', ('data', glob('../../data/*'))],
    options={'py2app': OPTIONS},
    setup_requires=['py2app', 'lxml>=2.2.2'],
)
Note qu'il n'y a plus aucun include: modulegraph semble enfin faire son travail correctement et inclure les dépendances nécessaires de lui-même. En revanche, on doit exclure explicitement toutes les dépendances (secondaires) qu'on n'utilisera pas dans notre code.
Le gros des exclusions est constitué par des frameworks Qt inutiles dans notre cas. py2app offre une option (--qt-plugins) qui permettrait peut-être de faire le travail à l'envers, de façon "positive", en spécifiant seulement ceux que l'on désire inclure. Encore que je ne suis pas certain que "plugin" et "framework" soient synonymes dans ce contexte. À creuser…
Yves a écrit :Pyromaths a également enflé car on est passé d'une architecture i386 à une double architecture i386 (32-bit) / x86_64 (64-bit).
Et si on décidait juste d'appeler ça une feature? ;-)
À moins qu'il y ait un moyen de virer le code 64 bits? J'ai essayé l'option --prefer-ppc de py2app, sans succès apparent…
Enfin, à noter que, maintenant qu'on utilise py2app plus proprement, on peut aussi construire une application "semi-standalone" fonctionnelle (avec semi_standalone=True). C'est à dire une application qui n'inclut pas le framework python-2.7, mais utilise celui inclus par défaut dans OSX. Je ne sais pas si c'est franchement intéressant, sachant que ça ne fait pas économiser beaucoup: dans cette affaire, c'est surtout Qt le poids lourd; Et j'ignore l'impact que cela peut avoir en terme de compatibilité avec d'anciens Mac.

Avatar de l’utilisateur
Yves
Messages : 472
Inscription : 21 janv. 2009, 20:40
Contact :

Re: Packaging

Message par Yves » 22 avr. 2013, 10:28

Bien vu le dylib_excludes :) Sur ma configuration on peut également exclure QtOpenGL.

Pour conserver uniquement le code 32 bits et virer le code 64 bits:
ditto --rsrc --arch i386 ~/pyromaths/scripts/mac/dist/Pyromaths.app ~/Desktop/Pyromaths.app
Mais, sur ma config, Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so n'a pas d'architecture 32 bits, seulement 64 bits:
file Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so 
Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so: Mach-O 64-bit bundle x86_64
Du coup, une fois le code 64 bits éliminé, Pyromaths ne fonctionne plus.

Avatar de l’utilisateur
djinn
Messages : 183
Inscription : 03 mars 2013, 10:38

Re: Packaging

Message par djinn » 22 avr. 2013, 11:01

Yves a écrit :Bien vu le dylib_excludes :) Sur ma configuration on peut également exclure QtOpenGL.
Tiens? C'est vrai: sur ma plateforme je n'ai pas QtOpenGL. Marrant ça… Je l'ajoute aux autres dylib_excludes.
Dans cette affaire, ce qui m'étonne c'est que PyQt (et toute sa cour) sont inclus d'office, alors que je suis toujours obligé de spécifier lxml, autrement ça plante. On doit pouvoir encore améliorer ça…
Yves a écrit :Pour conserver uniquement le code 32 bits et virer le code 64 bits:
ditto --rsrc --arch i386 ~/pyromaths/scripts/mac/dist/Pyromaths.app ~/Desktop/Pyromaths.app
Mais, sur ma config, Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so n'a pas d'architecture 32 bits, seulement 64 bits:
file Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so 
Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so: Mach-O 64-bit bundle x86_64
Ah, c'est à ça qu'il sert ce ditto:-)
Marrant: chez moi c'est l'inverse:
$ file dist/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so 
dist/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so: Mach-O bundle i386

Avatar de l’utilisateur
Yves
Messages : 472
Inscription : 21 janv. 2009, 20:40
Contact :

Re: Packaging

Message par Yves » 22 avr. 2013, 11:51

djinn a écrit :J'ai essayé l'option --prefer-ppc de py2app
ppc c'est pour PowerPC, une architecture utilisée par les Mac jusqu'en 2006.
djinn a écrit :on peut aussi construire une application "semi-standalone"
À mon avis, ce n'est pas possible d'utiliser à la fois la version Python du système et PyQt embarqué dans l'application. Une application semi-standalone impliquerait que l'utilisateur final installe PyQt sur son système, et je pense que tu es d'accord sur le fait que ce n'est absolument pas envisageable ;)
djinn a écrit :Marrant: chez moi c'est l'inverse
Ta machine virtuelle doit émuler un processeur 32 bits alors que mon Mac tourne en 64 bits. C'est moins gênant dans ton cas. Tu peux appliquer la commande ditto sans problème.

Il y a également une option arch='i386' pour setup.py :
from glob import glob
from setuptools import setup, find_packages
 
OPTIONS = dict(
        plist='Info.plist',
        argv_emulation=True, 
        arch='i386',
        packages=['lxml'],
        dylib_excludes=['QtDBus', 'QtDeclarative', 'QtDesigner', 'QtHelp',
                        'QtMultimedia', 'QtNetwork', 'QtOpenGL','QtScript', 'QtScriptTools',
                        'QtSql', 'QtSvg', 'QtTest', 'QtWebKit', 'QtXml',
                        'QtXmlPatterns', 'phonon',]
    )
setup(
    app         = ['../../src/pyromaths.py'],
    packages    = find_packages('../../src'),
    package_dir = {'': '../../src'},
    data_files  = ['pyromaths.icns', 'qt.conf', ('data', glob('../../data/*'))],
    options={'py2app': OPTIONS},
    setup_requires=['py2app', 'lxml>=2.2.2'],
)
Je dois d'abord m'occuper d'avoir une version de QtGui.so en 32 bits. Je vais voir ce que ça donne en installant Python 2.7.4 pour i386/PPC plutôt que la version 64-bit/32-bit.

Il est également possible d'intégrer la commande ditto directement dans setup.py (et peut-être se débarrasser de mon script shell standalone.sh):
https://github.com/minrk/DinosaurComics ... r/setup.py

Avatar de l’utilisateur
djinn
Messages : 183
Inscription : 03 mars 2013, 10:38

Re: Packaging

Message par djinn » 22 avr. 2013, 15:31

Yves a écrit :ppc c'est pour PowerPC, une architecture utilisée par les Mac jusqu'en 2006.
Oui, une architecture 32bits compatible i386, si je ne m'abuse? :)
Yves a écrit :À mon avis, ce n'est pas possible d'utiliser à la fois la version Python du système et PyQt embarqué dans l'application.
Je comprends ton inquiétude, mais ça marche chez moi en tous cas. Je t'ai mis une version semi-standalone en ligne. Est-ce que tu pourrais la tester sur ta machine?
Pour info, je ne suggère pas de se passer complètement de la version standalone, mais plutôt de proposer une alternative (avancée) supplémentaire. Dans ce registre une version "noob-friendly", tout compris (i.e. incluant BasicTex), serait pas mal non plus, non?
Enfin, comme j'aimerais aussi pouvoir distribuer pyromaths sous forme d'egg, il y aussi l'option de l'egg exécutable (que je classerais: très avancé).
Yves a écrit :Ta machine virtuelle doit émuler un processeur 32 bits alors que mon Mac tourne en 64 bits.
Écoute, on dirait pas pourtant:
$ sysctl -a
kern.ostype: Darwin
kern.osrelease: 11.0.0
kern.osrevision: 199506
kern.version: Darwin Kernel Version 11.0.0: Fri Apr  8 20:29:42 PDT 2011; root:xnu-1699.22.36~1/RELEASE_X86_64
hw.machine = x86_64
hw.model = MacPro3,1
Yves a écrit :Il y a également une option arch='i386' pour setup.py
Ah bon? Mais c'est une option distutils, setuptools ou py2app? Dans ton code, on dirait une option py2app, mais je ne trouve pas de doc dessus… Tu aurais un lien?
Yves a écrit :Il est également possible d'intégrer la commande ditto directement dans setup.py (et peut-être se débarrasser de mon script shell standalone.sh)
Pour se passer entièrement de standalone.sh il faut aussi coder le hack du setenv.sh.
En effet, quand on lance pyromaths en tant qu'application graphique, le PATH ressemble à quelque chose comme /bin:/usr/bin:/usr/sbin. J'ai bien essayé un putenv('PATH', path_complet), sans succès -- un bug connu de la plateforme OSX, qui peut aller jusqu'au memory leak. J'aimerais vraiment trouver une solution plus propre, mais je cale pour l'instant. :P

Avatar de l’utilisateur
djinn
Messages : 183
Inscription : 03 mars 2013, 10:38

Re: Packaging

Message par djinn » 22 avr. 2013, 16:21

Voilà où j'en suis de la standardisation du setup.py mac:
from glob import glob
from setuptools import setup, find_packages

OPTIONS = dict(
        plist='Info.plist',
        iconfile='pyromaths.icns',
        argv_emulation=True,
#        semi_standalone=True,
        includes=['gzip'],
        dylib_excludes=['QtDBus', 'QtDeclarative', 'QtDesigner', 'QtHelp',
                        'QtMultimedia', 'QtNetwork', 'QtOpenGL', 'QtScript',
                        'QtScriptTools', 'QtSql', 'QtSvg', 'QtTest',
                        'QtWebKit', 'QtXml', 'QtXmlPatterns', 'phonon']
    )
setup(
    app=['../../src/pyromaths.py'],
    packages=find_packages('../../src'),
    package_dir={'': '../../src'},
    data_files=[('data', glob('../../data/*'))],
    options={'py2app': OPTIONS},
    install_requires=['lxml>=2.2.2'],
    setup_requires=['py2app', 'lxml>=2.2.2'],
)
  • data_files a été vidé de tout fichier propre au mac:
    • qt.conf semble inutile: il ne contient qu'un path pour les plugins Qt-- qu'on utilise pas à ce jour,
    • le fichier icône est passé via l'option iconfile de py2app.
  • La dépendance explicite sur lmxl est réduite à son minimum: le module gzip, le reste semble inclus d'office. Reste à voir si ça fonctionnera sur une machine vierge de tous nos environnements de développement.
  • Reste à inclure:
    • l'appel à ditto,
    • le hack setenv.sh.
Ton lien semble commencer un hack similaire, mais je ne vois pas le remplacement du champ concerné dans l'Info.plist
print "replacing executable and _imaging.so"
…
shutil.copyfile("load", pjoin(Contents, "MacOS/"))
À ce stade il faudrait que je monte une nouvelle machine virtuelle vierge pour tester nos dmg. Sauf si tu as déjà quelque chose qui permet de faire les mêmes tests?
D'ailleurs, en parlant dmg, comment fabriques-tu celui de pyromaths? :)

fabienm
Messages : 28
Inscription : 06 nov. 2012, 00:20

Re: Packaging

Message par fabienm » 22 avr. 2013, 18:15

Je vous lis, je vous suis de loin, mais ça m'intéresse aussi :) J'ai jamais eut le courage de me plonger la dedans, je suis de tout coeur avec toi !

Bon courage !

Si quand t'as fini t'as le courage de pondre un post avec à quoi sert py2exe, distutils, setup.ui, et tous les trucs qui tournent autour de ça c'est cool :), j'ai compilé ma version windows et je me souviens avoir passé un certain temps avant de comprendre qui faisait quoi, qui était indispensable et qui ne l'était pas...

Avatar de l’utilisateur
djinn
Messages : 183
Inscription : 03 mars 2013, 10:38

Re: Packaging

Message par djinn » 22 avr. 2013, 20:09

Ah, bein c'est sympa de voir qu'on est pas les seuls masochistes à s'intéresser au problème! :D
En effet je pense que, quand on aura fini ce boulot, on sera suffisamment calé sur le packaging python pour répondre à quelques questions… :P

À part ça, je viens de créer une nouvelle machine virtuelle vierge pour pouvoir tester nos dmg.
  • Pour raccourcir le job (et alléger mon petit disque dur), j'ai voulu utiliser BasicTex à la place de MacTex. Mauvaise nouvelle: pyromaths ne fonctionne pas avec BasicTex. Il y a une première erreur avec dvips (que je n'ai pas creusée), mais surtout ps2pdf est absent de cette distribution. En l'état, on dépend donc d'une "librairie" de 4Go (installée). Tout n'est pas noir, car pdflatex est là, donc on pourrait peut-être contourner l'absence de ps2pdf… À creuser dans une thread consacrée.
  • J'en ai profité pour tester la version semi-standalone et, sure enough, j'obtiens une erreur: "A Python runtime not could be located (sic). You may need to install a framework build of Python, or edit the PyRuntimeLocations array in this application's Info.plist file". On est pas encore face à un mur cela dit: il faut encore tester avec PyRuntimeLocations modifié.
Dernière modification par djinn le 23 avr. 2013, 00:43, modifié 2 fois.

Avatar de l’utilisateur
Yves
Messages : 472
Inscription : 21 janv. 2009, 20:40
Contact :

Re: Packaging

Message par Yves » 22 avr. 2013, 23:31

djinn a écrit :
Yves a écrit :ppc c'est pour PowerPC, une architecture utilisée par les Mac jusqu'en 2006.
Oui, une architecture 32bits compatible i386, si je ne m'abuse? :)
Non, les processeurs PowerPC (Motorola, certaines stations IBM et Mac) ne sont pas compatibles i386 (intel et AMD).
djinn a écrit :Je t'ai mis une version semi-standalone en ligne. Est-ce que tu pourrais la tester sur ta machine?
Ta version semi-standalone fonctionne sur mon Mac car PyQt est installé sur mon système. J'ai également fait l'essai avant de lire ton dernier post, dans un environnement vierge, dans une machine virtuelle pour arriver au même message d'erreur que toi.
djinn a écrit :
Yves a écrit :Il y a également une option arch='i386' pour setup.py
Ah bon? Mais c'est une option distutils, setuptools ou py2app? Dans ton code, on dirait une option py2app, mais je ne trouve pas de doc dessus… Tu aurais un lien?
Tu peux l'obtenir en générant setup.py ainsi:
py2applet --arch=i386 --make-setup pyromaths.py
djinn a écrit :À ce stade il faudrait que je monte une nouvelle machine virtuelle vierge pour tester nos dmg. Sauf si tu as déjà quelque chose qui permet de faire les mêmes tests?
D'ailleurs, en parlant dmg, comment fabriques-tu celui de pyromaths? :)
Habituellement, je fais mes tests dans différentes machines virtuelles avec OS X 10.5 à 10.8.
Pour créer mon image disque, je pars d'une image disque modèle en lecture/écriture et j'applique le script suivant:
# Monter l'image disque modèle
hdiutil attach -owners on ~/Documents/modele.dmg -shadow

# Déplacer Pyromaths.app du Bureau vers l'image disque
ditto ~/Desktop/Pyromaths.app /Volumes/Pyromaths/Pyromaths.app

# Démontage et compression de l'image disque: UDIF bzip2-compressed image (OS X 10.4+ only)
hdiutil detach /Volumes/Pyromaths
hdiutil convert ~/Documents/modele.dmg -format UDBZ -imagekey zlib-level=9  -o ~/Desktop/pyromaths.dmg -shadow
djinn a écrit :Ah, bein c'est sympa de voir qu'on est pas les seuls masochistes à s'intéresser au problème! :D
C'est vrai que ça commence à tourner au masochisme cette affaire de packaging :D

Avatar de l’utilisateur
Yves
Messages : 472
Inscription : 21 janv. 2009, 20:40
Contact :

Re: Packaging

Message par Yves » 23 avr. 2013, 18:59

Pyromaths.app, créée avec mon nouvel environnement de développement sur OS X 10.8, fonctionne correctement. Par contre, testée sur OS X 10.7, Pyromaths.app génère cette erreur:
ImportError: dlopen(/Users/administrateur/Desktop/Pyromaths.app/Contents/Resources/lib/python2.7/lxml/etree.so, 2): Symbol not found: ___xmlStructuredErrorContext
Une solution serait d'utiliser une librairie statique pour libxml2.

Cependant, l'installation de lxml avec l'option -static-deps génère des librairies statiques libxml2 uniquement en 64 bits, inutilisables dans un processus 32 bits.

Je pensais avoir trouvé solution en rajoutant frameworks=['/usr/lib/libxml2.2.dylib'] dans setup.py ou bien includes=['gzip','libxml2'], mais j'ai toujours la même erreur sur Mac OS X 10.7.

Une idée ? :?

Répondre