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 » 23 avr. 2013, 23:07

Pour compléter mon précédent post:
avec la commande suivante:
export DYLD_PRINT_LIBRARIES=1; /Users/administrateur/Desktop/Pyromaths.app/Contents/MacOS/pyromaths
voici la liste des librairies obtenues: http://pastebin.com/9EUKPTeJ

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

Re: Packaging

Message par djinn » 23 avr. 2013, 23:14

Yves a écrit :Non, les processeurs PowerPC (Motorola, certaines stations IBM et Mac) ne sont pas compatibles i386 (intel et AMD).
Tiens… Autant pout moi. :-)
Yves a écrit :Il y a également une option arch='i386' pour setup.py
Au final, à l'usage, ça donne bien ce que tu veux?
Yves a écrit :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:
Ce projet a de la chance d'avoir un packager OSX aussi méticuleux. :-)
Est-ce que ça te génerait qu'on inclue ce script (et ton modèle de dmg -- ou de quoi le reconstruire) dans les sources de pyromaths?
Yves a écrit :C'est vrai que ça commence à tourner au masochisme cette affaire de packaging :D
À mon sens, on est en train de manger notre pain noir. Beaucoup de travail pour pas grand chose en apparence: d'un point de vue pratique, on a une distro un peu plus lourde et qui ne semble pas encore fonctionner partout…
C'est au moment de la factorisation des setup.py qu'on va réaliser tout l'intérêt de ce travail. Sans compter que cette mise à jour de l'environnement de développement, une fois terminée, devrait nous assurer quelques années de tranquillité… :)
Yves a écrit :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
Est-ce que tu pourrais me poster une version en ligne, que je puisse regarder ça de plus près? Je n'ai pas OSX 10.8, et la màj vers 10.7.5 a planté, donc je vais m'en tenir à 10.7.3 pour l'instant… :P
Yves a écrit :Une idée ? :?
À part installer un système d'exploitation digne de ce nom, j'imagine? ;-)

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

Re: Packaging

Message par djinn » 23 avr. 2013, 23:24

Yves a écrit :avec la commande suivante:
export DYLD_PRINT_LIBRARIES=1; /Users/administrateur/Desktop/Pyromaths.app/Contents/MacOS/pyromaths
voici la liste des librairies obtenues: http://pastebin.com/9EUKPTeJ
En effet, ça ressemble au problème que tu mentionnais (on link la libxml2.2 système):

Code : Tout sélectionner

dyld: loaded: /Users/administrateur/Desktop/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.so
dyld: loaded: /usr/lib/libxslt.1.dylib
dyld: loaded: /usr/lib/libexslt.0.dylib
dyld: loaded: /usr/lib/libxml2.2.dylib
À part ça, je vois plein de frameworks qu'on est censé avoir exclus. C'est un pyromaths produit avec les dylib_excludes et juste gzip en includes?

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

Re: Packaging

Message par Yves » 23 avr. 2013, 23:56

djinn a écrit :
Yves a écrit :Il y a également une option arch='i386' pour setup.py
Au final, à l'usage, ça donne bien ce que tu veux?
Pour l'instant, je me suis surtout intéressé au problème avec libxml2.
djinn a écrit :Est-ce que ça te génerait qu'on inclue ce script (et ton modèle de dmg -- ou de quoi le reconstruire) dans les sources de pyromaths?
Pas de soucis pour inclure le script. Pour l'image disque modèle, elle a été obtenue de manière graphique ( comme expliqué ici par exemple ) et pour être tranquille, elle a une taille de 100 Mo…
djinn a écrit :Est-ce que tu pourrais me poster une version en ligne, que je puisse regarder ça de plus près?
http://gesnel.fr/Pyromaths.zip
djinn a écrit :À mon sens, on est en train de manger notre pain noir. Beaucoup de travail pour pas grand chose en apparence: d'un point de vue pratique, on a une distro un peu plus lourde et qui ne semble pas encore fonctionner partout…
C'est au moment de la factorisation des setup.py qu'on va réaliser tout l'intérêt de ce travail. Sans compter que cette mise à jour de l'environnement de développement, une fois terminée, devrait nous assurer quelques années de tranquillité… :)
J'admire ton optimisme :)
djinn a écrit :À part installer un système d'exploitation digne de ce nom, j'imagine? ;-)
Il est possible d'installer un package manager: http://www.macports.org et de l'utiliser pour installer un environnement de développement. Mais j'ai le sentiment de mieux contrôler le processus en compilant à la main… ;)
djinn a écrit :En effet, ça ressemble au problème que tu mentionnais (on link la libxml2.2 système):

Code : Tout sélectionner

dyld: loaded: /Users/administrateur/Desktop/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.so
dyld: loaded: /usr/lib/libxslt.1.dylib
dyld: loaded: /usr/lib/libexslt.0.dylib
dyld: loaded: /usr/lib/libxml2.2.dylib
Exactement.
djinn a écrit :je vois plein de frameworks qu'on est censé avoir exclus. C'est un pyromaths produit avec les dylib_excludes et juste gzip en includes?
oui :(

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

Re: Packaging

Message par djinn » 24 avr. 2013, 03:10

J'ai beau essayer de toutes les manières auxquelles je peux penser, je n'arrive pas à inclure proprement la librairie libxml2 système dans notre app'. Même ce qui paraît la bonne méthode et semble fonctionner avec une libxml2 dans /usr/local échoue lamentablement avec celle dans /usr/lib:|
En résumé: je t'avoue que ça pique ma curiosité, mais pour l'instant je cale au même niveau que toi.

Du coup, en attendant, je me dis qu'on pourrait peut-être contourner le problème: après tout, jusqu'ici, la situation était la même (sans qu'on en soit conscient), la seule différence étant qu'on utilisait une version antérieure de lxml, compatible avec la libxml2 système. Or, vu ce qu'on fait de lxml (lire/écrire le fichier de config), on a pas vraiment besoin d'une version "cutting edge".
Du coup, j'ai réinstallé une ancienne version: lxml-2.2.7. Je t'ai même mis en ligne un pyromaths l'utilisant.

Et puis d'un coup je me dis: «Mais, moi aussi je suis sur OSX 10.7, moi aussi j'utilise lxml-3.1.2 et je link /usr/lib/libxml2.2, et pourtant chez moi ça tourne!». En revanche, quand je teste le pyromaths que tu viens de mettre en ligne, ça plante (même symbole non-défini).
J'avais mal compris le problème. En fait, lxml se comporte poliment: quand il est compilé sur une machine (OSX 10.8) où libxml2 présente ce symbole (___xmlStructuredErrorContext), il l'utilise; dans le cas contraire (OSX 10.7), il ne l'utilise pas. C'est quand il est compilé pour l'utiliser et qu'on le link ensuite avec une libxml où le symbole est absent qu'il tousse.
Ma version de pyromaths avec lxml-2.2.7 compilé sur OSX 10.7 ne sert donc à rien. À la rigueur, tu pourrais essayer un trick similaire sur 10.8 (setup_requires=['lxml==2.2.6'], vu que tu utilisais cette version sans problèmes semble-t-il). Alternative: utiliser le dernier lxml mais compiler sur la plateforme la plus ancienne possible.

Bien entendu, le mieux serait d'arriver à embarquer proprement la libxml2 qui a servi à compiler lxml.
Ça sent le bug py2app, non?

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

Re: Packaging

Message par djinn » 24 avr. 2013, 12:32

Yves a écrit :
djinn a écrit :je vois plein de frameworks qu'on est censé avoir exclus. C'est un pyromaths produit avec les dylib_excludes et juste gzip en includes?
oui :(
On dirait que py2app ne fait pas vraiment mieux qu'un rm des frameworks inutiles dans standalone.sh:
$ ls -l dist/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/
total 28302
-rwxr--r--  1 olivier  staff    12736 24 avr 10:58 Qt.so
-rwxr--r--  1 olivier  staff  2364576 24 avr 10:58 QtCore.so
-rwxr--r--  1 olivier  staff   223576 24 avr 10:58 QtDBus.so
-rwxr--r--  1 olivier  staff   299044 24 avr 10:58 QtDeclarative.so
-rwxr--r--  1 olivier  staff   402812 24 avr 10:58 QtDesigner.so
-rwxr--r--  1 olivier  staff  8068548 24 avr 10:58 QtGui.so
-rwxr--r--  1 olivier  staff   130164 24 avr 10:58 QtHelp.so
-rwxr--r--  1 olivier  staff   150636 24 avr 10:58 QtMultimedia.so
-rwxr--r--  1 olivier  staff   695168 24 avr 10:58 QtNetwork.so
-rwxr--r--  1 olivier  staff   207556 24 avr 10:58 QtScript.so
-rwxr--r--  1 olivier  staff    31220 24 avr 10:58 QtScriptTools.so
-rwxr--r--  1 olivier  staff   324356 24 avr 10:58 QtSql.so
-rwxr--r--  1 olivier  staff   117480 24 avr 10:58 QtSvg.so
-rwxr--r--  1 olivier  staff    37948 24 avr 10:58 QtTest.so
-rwxr--r--  1 olivier  staff   447628 24 avr 10:58 QtWebKit.so
-rwxr--r--  1 olivier  staff   336648 24 avr 10:58 QtXml.so
-rwxr--r--  1 olivier  staff   185276 24 avr 10:58 QtXmlPatterns.so
-rwxr--r--  1 olivier  staff   445336 24 avr 10:58 phonon.so
J'ai fait l'essai: a priori, on peut effacer tous les so superflus sans altérer le fonctionnement de l'application. Toujours ça de gagné…

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

Re: Packaging

Message par djinn » 24 avr. 2013, 17:07

djinn a écrit :Bien entendu, le mieux serait d'arriver à embarquer proprement la libxml2 qui a servi à compiler lxml.
Ça sent le bug py2app, non?
Bon, je crois que j'ai trouvé: c'est une erreur de conception de py2app, qui se repose abusivement sur macholib pour copier les librairies/frameworks spécifiées explicitement via l'option frameworks.
Or, la méthode en question (MachOStandalone.locate()) est designée pour le cas général: recherche automatique des dépendances et copie des librairies nécessaires pour qu'un code python puisse tourner dans un contexte d'application "standalone". Du coup, elle écarte notamment les librairies systèmes, jugées redondantes [macholib.MachOStandalone:49]:
def locate(self, filename):
    if in_system_path(filename):
        return filename
(...)
    info = framework_info(filename)
    if info is None:
        res = self.copy_dylib(filename)
        self.changemap[filename] = res
        return res
    else:
        res = self.copy_framework(info)
        self.changemap[filename] = res
        return res
Dans notre cas, c'est à dire quand on veut forcer l'inclusion de /usr/lib/libxml2.2.dylib, on se fait éjecter au premier if, et on arrive jamais jusqu'au test (framework_info() is None) qui permet ultimement de copier la librairie inconnue dans dist/.../Frameworks.
Il suffit de modifier ce détail et ça fonctionne:
$ otool -L dist/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.sodist/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.so:
	/usr/lib/libxslt.1.dylib (compatibility version 3.0.0, current version 3.24.0)
	/usr/lib/libexslt.0.dylib (compatibility version 9.0.0, current version 9.13.0)
	@executable_path/../Frameworks/libxml2.2.dylib (compatibility version 10.0.0, current version 10.3.0)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
Une façon simple de contourner ce bug: copier libxml2.2 n'importe où ailleurs (ou au pire dans /usr/local/lib/) et l'option frameworks=['/ailleurs/libmxl2.2.dylib'] devrait fonctionner impec'. 8-)

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

Re: Packaging

Message par djinn » 24 avr. 2013, 18:46

djinn a écrit :Une façon simple de contourner ce bug: copier libxml2.2 n'importe où ailleurs (ou au pire dans /usr/local/lib/) et l'option frameworks=['/ailleurs/libmxl2.2.dylib'] devrait fonctionner impec'. 8-)
Argh, j'ai parlé trop vite: :(
$ dist/Pyromaths.app/Contents/MacOS/pyromaths 2>&1 | grep libxml
dyld: loaded: /Volumes/pyromaths/scripts/mac/dist/Pyromaths.app/Contents/MacOS/../Frameworks/libxml2.2.dylib
dyld: loaded: /usr/lib/libxml2.2.dylib
Il charge la bonne libxml, et ensuite il charge quand même celle de /usr/lib, cet… acharné. :evil:
Est-ce que ça pourrait être dû à ça:
(...)
/usr/bin/strip: changes being made to the file will invalidate the code signature in: /Volumes/pyromaths/scripts/mac/dist/Pyromaths.app/Contents/Frameworks/libxml2.2.dylib (for architecture x86_64)
/usr/bin/strip: changes being made to the file will invalidate the code signature in: /Volumes/pyromaths/scripts/mac/dist/Pyromaths.app/Contents/Frameworks/libxml2.2.dylib (for architecture i386)
stripping saved 3930104 bytes (60325704 / 64255808)

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

Re: Packaging

Message par djinn » 24 avr. 2013, 20:40

djinn a écrit :Est-ce que ça pourrait être dû à ça:(...)
Non, strip=False n'y change rien. Grrr…

Pour une fois, je ne taperai pas sur cette magnifique plateforme de développement qu'est OSX (ça fera de vraies vacances à Yves ;)) pour m'en prendre à XML (merveilleuse technologie M$ de plus): un format verbeux et inefficace, qui se parse en O(n²). Franchement, est-ce qu'on a besoin d'une librairie de plusieurs mégas pour parser un fichier de config qui fait quelques centaines d'octets?
Et si l'on doit s'en tenir à XML, pour des raison de backward compatibility par exemple, pourquoi ne pas utiliser tout simplement le package xml de python?

Avatar de l’utilisateur
Jérôme
Administrateur - Site Admin
Messages : 1130
Inscription : 26 août 2006, 13:10
Localisation : Nantes
Contact :

Re: Packaging

Message par Jérôme » 24 avr. 2013, 22:07

Si tu as une modification viable, pas de soucis. Je n'ai malheureusement pas le temps de m'en occuper maintenant, même si je suis avec beaucoup d'intérêt tous vos échanges et que j'aimerais pouvoir être actif. Merci pour votre investissement à Yves et toi. :)
Pyromaths génère des fiches d'exercices et leur corrigé en toute simplicité.
Un programme multi-plateformes libre et gratuit sous licence GPL

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

Re: Packaging

Message par Yves » 24 avr. 2013, 22:13

djinn a écrit :Du coup, j'ai réinstallé une ancienne version: lxml-2.2.7
J'ai installé lxml-2.2.7 (sans static-deps) et Pyromaths.app tourne sur OS X 10.8, 10.7 et 10.6.
djinn a écrit :tu pourrais essayer un trick similaire sur 10.8 (setup_requires=['lxml==2.2.6'], vu que tu utilisais cette version sans problèmes semble-t-il).
J'ai installé lxml-2.2.6 (sans static-deps) et Pyromaths.app tourne également sur OS X 10.8, 10.7 et 10.6.
djinn a écrit :Alternative: utiliser le dernier lxml mais compiler sur la plateforme la plus ancienne possible.
Je ne souhaite pas devoir compiler dans une machine virtuelle ou dans une partition dédiée. Je veux pouvoir utiliser mon environnement habituel de travail.

Que ce soit avec lxml-2.2.6 ou lxml-2.2.7, Pyromaths.app ne fonctionne pas sur OS X 10.4 et 10.5
ImportError: dlopen(/Users/administrateur/Desktop/Pyromaths.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.so, 2): Symbol not found: _xmlDictExists
djinn a écrit :J'ai fait l'essai: a priori, on peut effacer tous les so superflus sans altérer le fonctionnement de l'application. Toujours ça de gagné…
Bien joué ! En tout cas, py2app est loin d'être aussi abouti qu'on pourrait l'espérer.

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

Re: Packaging

Message par djinn » 25 avr. 2013, 04:20

djinn a écrit :
$ dist/Pyromaths.app/Contents/MacOS/pyromaths 2>&1 | grep libxml
dyld: loaded: /Volumes/pyromaths/scripts/mac/dist/Pyromaths.app/Contents/MacOS/../Frameworks/libxml2.2.dylib
dyld: loaded: /usr/lib/libxml2.2.dylib
Il charge la bonne libxml, et ensuite il charge quand même celle de /usr/lib, cet… acharné. :evil:
Bein en fait je pense que je me suis affolé pour rien: je crois que le second dyld libxml2 est secondaire (c'est une librairie système qui le génère et pas directement notre app', donc pas de risque de conflit)…
Si c'est bien le cas, la technique de copier libxml2 hors du path système et spécifier son chemin complet via frameworks devrait fonctionner. :P

En passant, j'ai aussi patché py2app afin qu'il accepte l'inclusion de librairies systèmes, comme on essayait naturellement de le faire via l'option frameworks=['/usr/lib/libxml2.2.dylib'].
En gros, il suffit d'overrider la méthode locate(), en ajoutant le code suivant dans PythonStandalone [build_app.py:80]:
class PythonStandalone(macholib.MachOStandalone.MachOStandalone):
    def __init__(self, appbuilder, *args, **kwargs):
        super(PythonStandalone, self).__init__(*args, **kwargs)
        self.appbuilder = appbuilder

+   def locate(self, filename):
+       if filename.startswith(self.base):
+           return filename
+       if filename in self.changemap:
+           return self.changemap[filename]
+       if filename not in self.appbuilder.frameworks:
+           if in_system_path(filename):
+               return filename
+           for base in self.excludes:
+               if filename.startswith(base):
+                   return filename
+       info = macholib.dyld.framework_info(filename)
+       if info is None:
+           res = self.copy_dylib(filename)
+           self.changemap[filename] = res
+           return res
+       else:
+           res = self.copy_framework(info)
+           self.changemap[filename] = res
+           return res

    def copy_dylib(self, src):
Si je ne m'abuse ces deux méthodes devraient permettre d'embarquer libxml2.2.dylib et de résoudre ce problème de symbole manquant. Tu devrais donc pouvoir compiler pyromaths sur OSX 10.8 avec les dernières versions de lmxl (3.1.2 par exemple), et avoir néanmoins une app' qui fonctionne sur toutes les versions précédentes d'OSX (10.4 et 10.5 comprises). :)

Aurais-tu l'extrême gentillesse de tester chacune de ces deux méthodes, ce que je ne peux malheureusement pas faire tout seul (étant limité à OSX 10.7)? :oops:
Peut-être auras-tu besoin d'inclure également libxslt.1.dylib et libexslt.0.dylib (i.e. les autres dépendances d'etree.so): une fois ce problème de symbole libxml2 résolu, d'autres symboles non-définis suivront peut-être…
Yves a écrit :
djinn a écrit :J'ai fait l'essai: a priori, on peut effacer tous les so superflus sans altérer le fonctionnement de l'application. Toujours ça de gagné…
Bien joué ! En tout cas, py2app est loin d'être aussi abouti qu'on pourrait l'espérer.
Si le patch ci-dessus fonctionne, je verrai si je peux patcher py2app pour éviter qu'il nous copie des .so de frameworks qu'on a explicitement exclus. Maintenant que j'ai les mains dans le cambouis… :P

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

Re: Packaging

Message par Yves » 25 avr. 2013, 08:52

Les deux méthodes permettent bien l'inclusion de libxml2.2.dylib, libxslt.1.dylib et libexslt.0.dylib dans Pyromaths.app/Contents/Frameworks mais l'erreur dans OS X 10.4 et 10.5 reste la même.

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

Re: Packaging

Message par Yves » 25 avr. 2013, 10:12

djinn a écrit :
Yves a écrit :Il y a également une option arch='i386' pour setup.py
Au final, à l'usage, ça donne bien ce que tu veux?
Avec l'option arch='i386', Pyromaths.app/Contents/MacOS/pyromaths dispose bien d'une architecture unique i386, mais pas Pyromaths.app/Contents/MacOS/python qui a toujours d'une double architecture i386 et x86_64. La commande ditto est donc quand même nécessaire pour alléger l'application en se débarrassant du code 64 bits.

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

Re: Packaging

Message par djinn » 25 avr. 2013, 10:39

Merci! :D
Yves a écrit :Les deux méthodes permettent bien l'inclusion de libxml2.2.dylib, libxslt.1.dylib et libexslt.0.dylib dans Pyromaths.app/Contents/Frameworks
:)
Est-ce que libxslt.1.dylib et libexslt.0.dylib sont vraiment nécessaires, ou tu as juste été prudent/pressé?
Sinon, tu préfères laquelle des deux méthode?
Yves a écrit :…mais l'erreur dans OS X 10.4 et 10.5 reste la même.
:(
Avec python-2.7 et lmxl-3.1.2?
Tu te souviens de la combinaison que tu utilisais pour construire pyromaths quand il fonctionnait encore sur 10.4/10.5?
Yves a écrit :Avec l'option arch='i386', Pyromaths.app/Contents/MacOS/pyromaths dispose bien d'une architecture unique i386, mais pas Pyromaths.app/Contents/MacOS/python qui a toujours d'une double architecture i386 et x86_64. La commande ditto est donc quand même nécessaire pour alléger l'application en se débarrassant du code 64 bits.
Bien joué! :)

Répondre