如何建置給 iOS 使用的 LuaJIT 靜態函式庫

參考了網路上的一些文章和自己的嘗試,以及解決不同函式庫間的衝突,甚至還嘗試用最新的 Visual Studio 無功而返後,最後總算讓 LuaJIT bytecode 能順利在 arm64 及各種 iOS 裝置上運行無誤了。

為何使用 LuaJIT?

  1. LuaJIT 的效能比官方版 Lua 更好。
  2. 為了將遊戲程式碼編譯為 bytecode。

我原先嘗試使用 Lua 官方版 source code 建置出來的 luac,結果一試才發現在 Mac 上編譯後的 lua scripts,在 iOS 裝置中載入檔案時,會產生 incompatible bytecode error。雖然有其他的解決方法,但實行起來都有不少困難,所以我就想不如來使用 LuaJIT 試試看吧。

測試結果:藉由 luajit 可正確編譯 lua scripts 為二進位格式,並且在 iOS 專案連結 LuaJIT 靜態函式庫後,編譯後的 scripts 也可以成功地被載入執行了。

建置 LuaJIT for iOS 的步驟

  1. 產出可和專案連結的 .a 檔。
  2. 產出可以在電腦上使用的 luajit 檔。
  3. 用 luajit 來編譯 Lua 檔並可於實機上執行無誤。

詳細步驟如下:

第一步:建置靜態函式庫時需要產生出 armv7、armv7s、x86_64、i386、arm64 五個 slice,才可讓所有 iOS 裝置以及 iOS 模擬器都能連結 LuaJIT 建置。

第二步:用 i386 版本的 luajit 產生 arm 32-bits bytecode。用 x86_64 版本的 luajit 產生 arm64 bytecode。

為何「x86_64 luajit 可以產出 arm64 bytecode」依然是個謎,然後我也沒有設定 LUAJIT_ENABLE_GC64 竟然就可以用了。如果有人了解運作原理的話,還請不吝指教。

第三步:把兩種版本的 bytecode 包進 app 中,執行時偵測裝置是否為 arm64,去決定載入 Lua bytecode 的路徑。對,app bundle 中需要將 32/64 bits 兩份 bytecode 一起打包進去。

雖然在 iOS 上不能真的 JIT,但是可以用 LuaJIT 還是有不少幫助,至少幫我解決了原先頭痛的跨平台編譯 Lua source 的問題。

# 建置 i386 版本
make CC="gcc -m32 -arch i386" clean all

# 建置 x86_64 版本
make CC="gcc -m64 -arch x86_64" clean all

# 建置 armv7 版本
ISDKF="-arch armv7 -isysroot $ISDK/SDKs/$ISDKVER"
make HOST_CC="gcc -m32 -arch i386" TARGET_FLAGS="$ISDKF" TARGET=arm TARGET_SYS=iOS

# 建置 armv7s 版本
ISDKF="-arch armv7s -isysroot $ISDK/SDKs/$ISDKVER"
make HOST_CC="gcc -m32 -arch i386" TARGET_FLAGS="$ISDKF" TARGET=arm TARGET_SYS=iOS

# 建置 arm64 版本
ISDKF="-arch arm64 -isysroot $ISDK/SDKs/$ISDKVER"
make HOST_CC="gcc" TARGET_FLAGS="$ISDKF" TARGET=arm64 TARGET_SYS=iOS

建置完成後看到以下訊息表示正確無誤:

Architectures in the fat file: libLuajit.a are: armv7 armv7s i386 x86_64 arm64

完整程式碼請見:https://github.com/HalfLucifer/BuildLuaJIT_iOS

參考資料:

One Reply to “如何建置給 iOS 使用的 LuaJIT 靜態函式庫”

Leave a Reply