2009-06-26 5 views
4

Seit einigen Jahren verwenden Sie Lua 5.0 in einer Mac OS X Universal Binary App. Lua-Skripte werden mit luac kompiliert und die kompilierten Skripte werden mit der App gebündelt. Sie haben in Tiger und Leopard, Intel oder PPC richtig funktioniert.Lua kompilierte Skripte unter Mac OS X - Intel vs PPC

Um Bibliotheksprobleme zu der Zeit zu vermeiden, fügte ich einfach den Lua src-Baum zu meinem Xcode-Projekt hinzu und kompilierte wie es ist, ohne Probleme.

Es war Zeit, auf eine modernere Version von Lua zu aktualisieren, also ersetzte ich meinen Quellbaum durch den von 5.1.4. Ich baute Luac mit make macosx (Maschine läuft Leopard auf Intel) wieder auf.

Unkompilierte Skripts funktionieren wie immer in Tiger und Leopard, Intel und PPC.

Allerdings jetzt kompiliert Skripts nicht auf PPC-Maschinen laden.

Also habe ich Luac mit dem Flag 'ansi' neu aufgebaut und meine Skripte neu kompiliert. Derselbe Fehler. Ebenso erzeugte ein Build-Flag von 'generic' keine Freude.

Kann jemand bitte beraten, was ich als nächstes tun kann?

+0

Weitere Informationen benötigt: irgendwelche Fehlermeldungen bei diesem Fehler zu laden? –

Antwort

13

Lua's kompilierte Skripte sind so ziemlich der rohe Bytecode, der nach einem kurzen Header ausgegeben wurde. Der Header dokumentiert einige der Eigenschaften der Plattform, die zum Kompilieren des Bytecodes verwendet wurden, aber der Lader prüft nur, ob die aktuelle Plattform die gleichen Eigenschaften aufweist.

Leider verursacht dies Probleme beim Laden von Bytecode kompiliert auf einer anderen Plattform, auch wenn von der gleichen Version von Lua kompiliert. Natürlich können Skripts, die von verschiedenen Versionen von Lua kompiliert wurden, nicht funktionieren, und da die Versionsnummer von Lua im Bytecode-Header enthalten ist, wird der Versuch, sie zu laden, vom Kern erfasst.

Die einfache Antwort ist, Skripte nur nicht zu kompilieren. Wenn Lua das Skript selbst kompiliert, müssen Sie sich nur über mögliche Versionsunterschiede zwischen Lua-Kernen in Ihren verschiedenen Builds Ihrer Anwendung Gedanken machen, und das ist nicht schwer zu bewältigen.

Tatsächlich unterstützt eine vollständige Kreuzkompatibilität für kompilierten Bytecode not easy. In dieser E-Mail, identifiziert Mike Pall die folgenden Probleme:

  1. Endianess: swap auf Ausgabe nach Bedarf.

  2. sizeof(size_t), wirkt sich riesige String-Konstanten: für Überlauf überprüfen, wenn Herabstufung.

  3. sizeof(int), wirkt MAXARG_Bx und MAXARG_sBx: für Überlauf überprüfen, wenn Herabstufung.

  4. : einfach in C, aber nur wenn der Host und das Ziel demselben FP-Standard folgen; Präzision Verlust beim Upgrade (seltener Fall); warnen vor nicht ganzzahligen Zahlen, wenn zu int32 herabstufen.

Von all den Diskussionen, die ich zu diesem Thema auf der Mailing-Liste gesehen habe, sehe ich zwei wahrscheinlich tragfähige Ansätze, vorausgesetzt, dass Sie nicht bereit sind, nur zu prüfen, die nicht kompilieren Lua-Skripten Versand.

Die erste wäre, die Byte-Reihenfolge zu beheben, wenn die kompilierten Skripte geladen werden. Dies stellt sich als einfacher heraus, als Sie es erwarten würden, da dies durch Ersetzen der Low-Level-Funktion, die die Skriptdatei liest, ohne erneute Kompilierung des Kerns erfolgen kann. In der Tat kann es sogar in reinem Lua getan werden, indem Sie Ihre eigene chunk reader Funktion zu lua_load() zur Verfügung stellen. Dies sollte funktionieren, solange das einzige Kompatibilitätsproblem auf Ihren Plattformen die Bytereihenfolge ist.

Die zweite besteht darin, den Kern selbst zu patchen, um eine gemeinsame Darstellung für kompilierte Skripte auf allen Plattformen zu verwenden. Dies wurde als möglich durch Luiz Henrique de Figueiredo beschrieben:

.... Ich bin überzeugt, dass der beste Weg zur Byte-Reihenfolge oder Cross-Compilierung Dritter dump/undump Paare ist. Die Dateien ldump.c und lundump.c sind vollständig austauschbar; Sie exportieren einen einzelnen, wohldefinierten Einstiegspunkt . Das Format von vorkompilierten Brocken ist nicht heilig, überhaupt heilig; Sie können jedes Format verwenden, solange ldump.c und lundump.c darüber einig sind . (Zum Beispiel Rici Lake ist erwägen ein Textformat für vorkompilierte Stücke zu schreiben.) ....

Persönlich würde ich ernsthaft in Erwägung empfehlen, nicht zu geben, um die Skripte vorzunehmen Kompilieren und somit vermeiden die Plattform Portabilitätsprobleme vollständig.

Bearbeiten: Ich habe meine Beschreibung des Bytecode-Headers dank LHF Kommentar aktualisiert. Ich hatte diesen Teil der Lua-Quelle noch nicht gelesen, und ich hätte es wahrscheinlich überprüfen sollen, bevor ich ziemlich durchsetzungsfähig darüber bin, welche Informationen in der Kopfzeile vorhanden sind oder nicht.

Hier ist das Fragment von lundump.c, das eine Kopie der Kopfzeile bildet, die mit der laufenden Plattform für den Vergleich mit dem Bytecode übereinstimmt, der geladen wird. Es wird einfach mit memcmp() für eine genaue Übereinstimmung mit dem Header aus der Datei verglichen, so dass jede Nichtübereinstimmung dazu führt, dass der Bestandslader (luaU_undump()) die Datei zurückweist.

/* 
* 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? */ 
} 

Wie zu sehen ist, wird der Header 12 Byte lang und enthält eine Signatur (4 Byte, "<esc>Lua"), Version und Format-Codes, ein Flag-Byte für Byte-Reihenfolge, Größen der Typen int, size_t, Instruction und lua_Number, und ein Flag, das anzeigt, ob lua_Number ein integraler Typ ist.

Dadurch können die meisten Plattformunterscheidungen abgefangen werden, es wird jedoch nicht versucht, auf jede Art und Weise zu unterscheiden, in der sich Plattformen unterscheiden können.

Ich stehe immer noch zu den oben gemachten Empfehlungen: Erstens, kompilierbare Quellen; Oder passen Sie ldump.c und lundump.c an, um ein allgemeines Format zu speichern und zu laden, mit der zusätzlichen Anmerkung, dass jedes benutzerdefinierte Format das LUAC_FORMAT-Byte des Headers neu definieren sollte, um nicht mit dem Bytecode-Format zu verwechseln.

+1

Der Bytecode-Header enthält einige Informationen über die Plattform, z. B. die Größe und den Typ von lua_Number und die Endianess. – lhf

+0

@lhf, danke. Ich habe meine Antwort aktualisiert, um besser zu beschreiben, was der Header enthält. – RBerteig

+0

Erstens, danke an alle, die an dieser Frage teilgenommen haben. Große Umarmungen! Ich entschuldige mich dafür, dass ich nicht früher geantwortet habe. Ich bin zu Vers 5 zurückgekehrt, das, aus welchem ​​Grund auch immer, kompilierte Skripte für PPC und Intel erfolgreich ausführt. Längerfristig scheue ich mich, die Zukunft zu hinterfragen. Lua baut mit Endian-Problemen auf, daher werde ich die nicht kompilierten Skripte wahrscheinlich mit meiner App versenden und sie nach Bedarf auf dem Host-Rechner kompilieren. Zufällige Sicherheit ist ein Problem, daher muss ich die (100s) Skripte im Batch-Verfahren verschleiern und sie dann vor der Kompilierung entschlüsseln. – SirRatty

1

Lua Bytecode ist nicht tragbar. Sie sollten Quelltexte mit Ihrer Anwendung versenden.

Wenn Download-Größe ein Problem ist, sind sie in der Regel kürzer als die Bytecode-Form.

Wenn geistiges Eigentum ein Problem ist, können Sie einen Code-Obfuscator verwenden, und bedenken Sie, dass das Zerlegen von Lua Bytecode alles andere als schwierig ist.

Wenn die Ladezeit ein Problem darstellt, können Sie die Quellen lokal in Ihrem Installationsskript vorkompilieren.

3

Möglicherweise möchten Sie einen gepatchten Bytecode Loader verwenden, der unterschiedliche Endiannität unterstützt. Siehe this.

0

Ich vermute, dass Sie die Skripte auf einer Intel-Box kompiliert haben.

Kompilierte Skripte sind nicht portierbar. Wenn Sie Skripts wirklich vorkompilieren möchten, müssen Sie zwei Versionen jedes kompilierten Skripts einbinden: eines für Intel und eines für PPC. Ihre App muss abfragen, auf welchem ​​Programm sie läuft und das korrekte kompilierte Skript verwenden.

3

Ich hätte zu RBerteigs Beitrag kommentiert, aber ich habe anscheinend noch nicht genug Ruf, um das zu können. Als ich daran arbeitete, LuaRPC mit Lua 5.1.x auf den neuesten Stand zu bringen und es mit eingebetteten Zielen zu arbeiten, habe ich die Quellen ldump.c und lundump.c modifiziert, um sie ein wenig flexibler zu machen. Das eingebettete Lua-Projekt (eLua) hatte bereits einige der Patches, die Sie auf der Lua-Liste finden können, aber ich habe etwas mehr hinzugefügt, um lundump etwas freundlicher für Skripte zu machen, die auf verschiedenen Architekturen kompiliert wurden. Es gibt auch Unterstützung für Cross-Compilation, sodass Sie für Ziele erstellen können, die sich vom Host-System unterscheiden (siehe luac.c im selben Verzeichnis wie die unten stehenden Links).

Wenn Sie bei der Prüfung der Änderungen interessiert sind, können Sie sie in der elua Quellrepository finden: 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

Standard Disclaimer: ich keinen Anspruch machen, dass die Änderungen sind perfekt oder Arbeit in jeder Situation. Wenn Sie es verwenden und etwas kaputt finden, würde ich mich freuen, davon zu hören, damit es repariert werden kann.

+0

+1 für eLua. Und um Sie genügend Rep zu kommentieren ;-) – RBerteig

+0

FYI: Unsere Projekt-Website finden Sie hier, http://www.eluaproject.net/ und Dokumente, die die Version 0.6 (bald, hoffe ich) hier begleiten sollten: http: //elua.berlios.de/beta/, das Hinweise zur Verwendung des Cross Compilers enthält: http://elua.berlios.de/beta/de/using.html#cross –

0

Ich habe nicht genug Reputation, um zu kommentieren, also muss ich dies als Antwort anbieten, obwohl es keine passende Antwort auf die gestellte Frage ist. Es tut uns leid.

Es ist ein Lua Obfuscator finden Sie hier:

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

Vollständige Offenlegung: Ich bin der Autor des obfuscator und ich bin mir bewusst, es ist nicht perfekt. Feedback ist erwünscht und erwünscht (auf der obigen Seite gibt es eine Feedback-Seite).