【最新】LuaJIT 32/64 位字節碼,從編譯到使用全紀錄

網上關於 LuaJIT 的討論,已經顯得有些陳舊。若是你對 LuaJIT 編譯 Lua 源文件爲具體的 32位或64位字節碼,極其具體使用感興趣的話,不妨快速讀一下這篇文章。此文章針對嘗試在 iOS 或 Android 上使用 LuaJIT 的小夥伴。限於篇幅,此處假定,你能夠成功在 iOS/Android App 中集成了 LuaJIT,而且已經能夠執行源碼形式的 Lua 文件。html

我忍不住在開頭插一句: LuaJIT 編譯後,只有約 600k,可能也就是一張圖片的空間,但卻可讓你的你App能夠擁有一門完整的腳本語言的能力 -- 真的很酷!爲許多問題,提供了許多新的思路,特別是 App 地動態性和可配置型方面。ios

環境

  • 操做系統: macOS 10.13.4 【Linux 系統上,應該使用;Windows 系統上,僅供參考】swift

  • LuaJIT 版本: LuaJIT-2.1.0-beta3【官網最新版】xcode

目錄結構預約義

爲了便於下文指令的說明,此處簡單約定下目錄結構。實際使用時,按需設置和整理便可。緩存

  • tools:存放各類編譯腳本和工具。
  • source:存放編譯前的 Lua 源碼。之後全部的 Lua 源碼,都須要放在且只能放在此文件夾下。
  • output: 用於存放編譯後的 Lua 字節碼文件。

編譯加密工具

Lua 的加密工具,本質上就是 Lua 的解釋器。此處使用的解釋器源碼是 LuaJIT。LuaJIT 執行效率最高,且編譯出來的字節碼沒法逆向爲 Lua 源碼,更能保證源碼安全性。LuaJIT 支持交叉編譯,便可以在電腦上編譯出 iOS 或 Android 手機上系統須要的字節碼。如此,咱們只須要編譯一次 32 和 64 位的 LuaJIT 解釋器各一個,備份存檔,後續可直接使用。安全

編譯 LuaJIT 解釋器,直接用官方的推薦指令便可。比較特殊的一點時,若是是想編譯出 64 位 LuaJIT,須要加上參數 CFLAGS=-DLUAJIT_ENABLE_GC6工具

# cd 到 LuaJIT 源碼目錄
cd tools/LuaJIT-2.1.0-beta3

# 編譯 32 位 LuaJIT 解釋器
make clean && make && cp src/luajit ../luajit-32 && make clean

# 編譯 64 位 LuaJIT 解釋器
make clean && make CFLAGS=-DLUAJIT_ENABLE_GC64 && cp src/luajit ../luajit-64 && make clean

注意:從新解壓源碼後,可能須要從新啓動命令行/終端,來清除可能的系統緩存,才能正確 build 出想要的東西。ui

加密 Lua 源文件

所謂的加密 Lua 源文件,其實就是把 Lua 源文件,編譯爲 LuaJIT 字節碼。相對於 Luac ,LuaJIT 字節碼執行效率更高,並且沒法被直接逆向爲對應的 Lua 源碼。加密

編譯字節碼,用的是 -b 命令,須要注意的是,必定要使用對應字節的 LuaJIT 解釋器來編譯,不然 iOS/Android App 中,可能沒法加載。lua

編譯後的字節碼文件的後綴,能夠根據本身須要自定義。此處我使用的是 「.yan」 和 「.yan64」。

# 編譯32位字節碼 ,適用於Android所有手機,部分 iOS 手機。
./tools/luajit-32 -b ./source/main.lua ./output/main.yan

# 編譯64位字節碼,僅用於部分 iOS 手機。
./tools/luajit-64 -b ./source/main.lua ./output/main.yan64

注意: 敏感信息,不要直接以常量字符串的形式使用。

在 iOS 中,根據不一樣的 CPU, 加載不一樣的字節碼。

在 Android 手機上,通常只須要使用 32 位的 LuaJIT 字節碼文件便可。iOS 上,狀況比較複雜,從 iOS11 以後,iOS 要求相對的庫必須有64位版本。也就意味着,若是 App 想兼容 iPhone5s 之前的 32位CPU的設備的話,就必須在項目中同時放置32位和64位的LuaJIT靜態庫。關於適用於手機端的 LuaJIT 靜態庫的編譯問題,暫不進一步展開。此處只討論,如何在 iOS 中,動態根據須要準確加載對應的 32 或 64 位的 LuaJIT 字節碼文件。

基於上文的討論,此處給出一個簡單的策略:

  • Lua 源文件,同時編譯生成32位和64位字節碼的文件。
  • 編譯後的字節碼文件,僅文件後綴不一樣,文件路徑的其餘部分保證是徹底一致的。如 main.yanmain.yan64 是由 main.lua編譯獲得。
  • 在 iOS App 運行時,動態根據當前真正運行的是 32 仍是 64 位的 LuaJIT 解釋器,來選擇對應的字節碼文件後綴便可。

分享一個 swift 版的實現:

private func luaFileSuffix() -> String{
        #if (arch(i386) || arch(arm))
        return ".yan"
        #else
        return ".yan64"
        #endif

    }

參考文章

相關文章
相關標籤/搜索