2009-06-26 13 views
4

Nous avons utilisé Lua 5.0 dans une application binaire universelle Mac OS X depuis quelques années. Les scripts Lua sont compilés en utilisant luac et les scripts compilés sont regroupés avec l'application. Ils ont fonctionné correctement dans Tiger et Leopard, Intel ou PPC. Pour éviter les problèmes de bibliothèque à ce moment-là, j'ai simplement ajouté l'arborescence Lua src à mon projet Xcode et compilé tel quel, sans aucun problème.Lua scripts compilés sur Mac OS X - Intel vs PPC

Il était temps de mettre à jour vers une version plus moderne de Lua, j'ai donc remplacé mon arbre source par celui de 5.1.4. J'ai reconstruit luac en utilisant make macosx (la machine fonctionne sous Leopard sur Intel).

Les scripts non compilés fonctionnent correctement dans Tiger et Leopard, Intel et PPC, comme toujours.

Toutefois, maintenant compilés les scripts ne parviennent pas à charger sur les ordinateurs PPC. J'ai donc reconstruit luac avec le drapeau 'ansi' et j'ai recompilé mes scripts. Même erreur De même, un drapeau de construction de 'générique' n'a produit aucune joie.

Quelqu'un peut-il s'il vous plaît conseiller sur ce que je peux faire ensuite?

+0

Plus d'informations nécessaires: des messages d'erreur sur ce défaut de chargement? –

Répondre

13

Les scripts compilés de Lua sont à peu près le bytecode brut déposé après un court en-tête. L'en-tête documente certaines des propriétés de la plate-forme utilisée pour compiler le bytecode, mais le chargeur vérifie seulement que la plate-forme actuelle a les mêmes propriétés.

Malheureusement, cela crée des problèmes lors du chargement de bytecode compilé sur une autre plateforme, même si compilé par la même version de Lua. Bien sûr, on ne peut s'attendre à ce que les scripts compilés par différentes versions de Lua fonctionnent, et puisque le numéro de version de Lua est inclus dans l'en-tête bytecode, la tentative de chargement est interceptée par le noyau.

La réponse simple est simplement de ne pas compiler des scripts. Si Lua compile le script lui-même, vous n'avez qu'à vous préoccuper des éventuelles incompatibilités de version entre les cœurs Lua dans vos différentes versions de votre application, et ce n'est pas difficile à gérer.

Actuellement, la compatibilité croisée complète pour le bytecode compilé est not easy. Dans ce courriel, Mike Pall a identifié les questions suivantes:

  1. endianess: échange sur la production selon les besoins.

  2. sizeof(size_t), affecte d'énormes constantes de chaîne: vérifier le dépassement lorsque déclassement.

  3. sizeof(int), affecte MAXARG_Bx et MAXARG_sBx: vérifier débordement lors déclassement. : Facile en C, mais seulement lorsque l'hôte et la cible suivent la même norme FP; précision perte lors de la mise à niveau (cas rare); avertir des nombres non entiers lorsque rétrogradant à int32.

De toutes les discussions que je l'ai vu au sujet de cette question sur la liste de diffusion, je vois deux approches viables probablement, en supposant que vous n'êtes pas disposé à envisager l'expédition les anciens scripts Lua non compilés. Le premier serait de fixer l'ordre des octets lorsque les scripts compilés sont chargés. Cela s'avère plus facile à faire que prévu, car cela peut être fait en remplaçant la fonction de bas niveau qui lit le fichier de script sans recompiler le noyau lui-même. En fait, il peut même être fait en pur Lua, en fournissant votre propre fonction chunk reader à lua_load(). Cela devrait fonctionner tant que le seul problème de compatibilité sur vos plates-formes est l'ordre des octets.

La seconde consiste à patcher le noyau lui-même pour utiliser une représentation commune pour les scripts compilés sur toutes les plateformes. Cela a été décrit comme possible par Luiz Henrique de Figueiredo:

.... Je suis convaincu que la meilleure route à l'ordre octet ou la compilation croisée est benne tiers/paires undump. Les fichiers ldump.c et lundump.c sont complètement remplaçables; ils exportent un point d'entrée unique, bien défini, . Le format des morceaux précompilés n'est pas sacré du tout; vous pouvez utiliser n'importe quel format, tant que ldump.c et lundump.c sont d'accord à ce sujet. (Par exemple, le lac Rici est compte écrire un format de texte pour morceaux précompilés.) ....

Personnellement, je recommande d'envisager sérieusement de ne pas pré-compilation des scripts et éviter ainsi la les problèmes de portabilité de plate-forme entièrement.

Modifier: J'ai mis à jour ma description de l'en-tête bytecode grâce au commentaire de lhf. Je n'avais pas encore lu cette partie de la source de Lua, et j'aurais probablement dû la vérifier avant d'être si sûre de savoir quelles informations sont ou ne sont pas présentes dans l'en-tête.

Voici le fragment de lundump.c qui forme une copie de l'en-tête correspondant à la plate-forme en cours de réalisation pour comparaison avec le bytecode en cours de chargement. Il est simplement comparé avec memcmp() pour une correspondance exacte avec l'en-tête du fichier, de sorte que toute incompatibilité entraînera le rejet du fichier par le chargeur de stock (luaU_undump()).

/* 
* make header 
*/ 
void luaU_header (char* h) 
{ 
int x=1; 
memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); 
h+=sizeof(LUA_SIGNATURE)-1; 
*h++=(char)LUAC_VERSION; 
*h++=(char)LUAC_FORMAT; 
*h++=(char)*(char*)&x;       /* endianness */ 
*h++=(char)sizeof(int); 
*h++=(char)sizeof(size_t); 
*h++=(char)sizeof(Instruction); 
*h++=(char)sizeof(lua_Number); 
*h++=(char)(((lua_Number)0.5)==0);    /* is lua_Number integral? */ 
} 

Comme on peut le voir, l'en-tête est de 12 octets et contient une signature (4 octets, "<esc>Lua"), les codes de version et le format, un octet de drapeau pour boutisme, les tailles des types int, size_t, Instruction et lua_Number, et un drapeau indiquant si lua_Number est un type intégral.

Ceci permet à la plupart des distinctions de plate-forme d'être prises, mais n'essaie pas de saisir toutes les façons dont les plates-formes peuvent différer.

Je suis toujours d'accord avec les recommandations ci-dessus: d'abord, expédier des sources compilables; ou en second lieu, personnalisez ldump.c et lundump.c pour stocker et charger un format commun, avec la note supplémentaire que tout format personnalisé doit redéfinir l'octet LUAC_FORMAT de l'en-tête afin de ne pas être confondu avec le format bytecode stock.

+1

L'en-tête bytecode contient des informations sur la plate-forme, telles que la taille et le type de lua_Number et l'endianness. – lhf

+0

@lhf, merci. J'ai mis à jour ma réponse pour mieux décrire ce que contient l'en-tête. – RBerteig

+0

Tout d'abord, merci à tous ceux qui ont participé à cette Question. Gros câlins! Je m'excuse de ne pas avoir répondu plus tôt. Je suis revenu au vers 5 qui, pour une raison quelconque, exécute avec succès des scripts compilés sur PPC et Intel, pour l'instant.À plus long terme, je me méfie des versions futures de Lua pour les questions endianiques. Je vais donc probablement envoyer les scripts non compilés avec mon application et les compiler sur la machine hôte si nécessaire. La sécurité occasionnelle est un problème, donc je devrai obnubiler par lots - crypter les scripts (100s) et les décrypter juste avant la compilation. – SirRatty

1

Lua bytecode n'est pas portable. Vous devriez expédier des scripts source avec votre application.

Si la taille de téléchargement est une préoccupation, ils sont généralement plus courtes que la forme de bytecode.

Si la propriété intellectuelle est une préoccupation, vous pouvez utiliser un obfuscateur code, et garder à l'esprit que désassembler Lua bytecode est tout sauf difficile.

Si le temps de chargement est un problème, vous pouvez précompilez les sources locales dans votre script d'installation.

3

Vous pouvez utiliser un chargeur de patché bytecode qui prend en charge différents boutisme. Voir this.

0

Je conjecture que vous avez compilé les scripts sur une boîte Intel.

Les scripts compilés sont extrêmement non-portables. Si vous voulez vraiment précompiler des scripts, vous devez inclure deux versions de chaque script compilé: une pour Intel et une pour PPC. Votre application devra interroger le programme sur lequel elle s'exécute et utiliser le bon script compilé.

3

J'ai commenté le poste de RBerteig, mais je semble ne pas avoir encore assez réputation d'être en mesure de le faire. En travaillant sur la mise à jour de LuaRPC avec Lua 5.1.x ET en le faisant fonctionner avec des cibles intégrées, j'ai modifié les sources ldump.c et lundump.c pour les rendre un peu plus flexibles. Le projet Lua embarqué (eLua) avait déjà quelques-uns des correctifs que vous pouvez trouver sur la liste Lua, mais j'ai ajouté un peu plus pour rendre lundump un peu plus convivial pour les scripts compilés sur différentes architectures. La prise en charge de la compilation croisée est également disponible afin que vous puissiez créer des cibles différentes du système hôte (voir luac.c dans le même répertoire que les liens ci-dessous).

Si vous êtes intéressé à vérifier les modifications, vous pouvez les trouver dans le référentiel source elua: http://svn.berlios.de/wsvn/elua/trunk/src/lua/lundump.c http://svn.berlios.de/wsvn/elua/trunk/src/lua/lundump.h http://svn.berlios.de/wsvn/elua/trunk/src/lua/ldump.c

Responsabilité Standard: Je ne prétends pas que les modifications sont parfaits ou au travail dans toutes les situations. Si vous l'utilisez et que vous trouvez quelque chose de cassé, je serais heureux d'en entendre parler pour que cela puisse être corrigé.

+0

+1 pour eLua. Et pour vous obtenir suffisamment de commentaires pour commenter ;-) – RBerteig

+0

FYI: Notre site Web de projet peut être trouvé ici, http://www.eluaproject.net/ et docs qui devraient accompagner la version 0.6 (bientôt, j'espère) ici: http: //elua.berlios.de/beta/ qui contient des notes sur l'utilisation du compilateur croisé: http://elua.berlios.de/beta/fr/using.html#cross –

0

Je n'ai pas assez réputation de commentaires, donc je dois fournir cela comme une réponse au lieu même si ce n'est pas une réponse appropriée à la question posée. Pardon.

Il y a un Lua Obfuscator ici:

http://www.capprime.com/CapprimeLuaObfuscator/CapprimeLuaObfuscator.aspx

divulgation complète: Je suis l'auteur du obfuscateur et je suis conscient qu'il est pas parfait. Les commentaires sont les bienvenus et encouragés (il y a une page de commentaires disponible sur la page ci-dessus).