相關鏈接:Windows 下編譯 LuaJIT
懶人與伸手黨可以直接看最底部。
為什么使用 LuaJIT
Lua 官方版的編譯嵌入相對簡單,但是為什么要用 LuaJIT 呢?我所了解到的優勢有:
更高的運行效率。
支持運行 Lua 編譯后的機器碼。
雖然 Lua 也支持編譯腳本,但是編譯出來的機器碼文件并不是跨平臺的,也就是說在
PC 上編譯的腳本在 Android 中無法使用。至于如何編譯 Android 上使用的腳本,至今沒有找到方案。
腳本的編譯不僅可以提高載入速度,更可以一定程度上保護源碼,避免被篡改。這也是我使用 LuaJIT 的主要原因。
LuaJIT NDK 編譯
系統環境:Ubuntu 17 x64
Windows 下使用 Cygwin 應該也是可以的。
由于我們系統是64位,編譯的目標很可能是32位的,所以先確認安裝了32位所需的編譯環境:
sudo apt-get install libc6-dev-i386
NDK 配置
已經配置好 NDK 的可以略過本章節。
去 NDK 官網下載適合自己的版本并解壓。這里使用的是 android-ndk-r14b-linux-x86_64.
解壓放在 /opt/android/ndk.
然后配置環境變量。這里直接配置全局的環境變量。修改 /etc/proile 在最后加上
export PATH=/opt/android/ndk:$PATH
注銷重新登錄一下使之生效。測試下命令 ndk-build,能運行則是配置完畢。
編譯
首先去 LuaJIT 官網下載源碼并解壓。
按照官方指南,新建一個 build.sh 放在解壓目錄下,根據實際需求輸入指令:
注意根據實際環境配置,有幾個地方需要修改一下。
然后執行 sh build.sh 就應該可以編譯了。
但是實際情況總是沒有那么順利。
折騰了3天,最后發現原來是變量引用問題。我不是很熟悉 shell,所以也就不再深究了,直接把 make 的所有參數寫在一行里,就這么神奇地成功了。
如果之前編譯(失敗)過,記得先 make clean 清理下文件。編譯成功后可看到如下提示:
之后可以在 src 目錄里找到編譯出的 .a 靜態庫文件。通過改變編譯腳本,可以編譯出 armeabi-v7a x86 等不同 ABI 下的文件。
整合 Android
得到了靜態庫,下面就要整合進 Android 工程。由于 Lua 只提供的 C API,所以在 Android 中需要通過 JNI 來實現調用。還好有個 luajava 的開源庫幫我們實現了這個繁瑣的過程。而 androlua 又把 luajava 整合進了 Android. 我們這里是借用這個庫來整合 LuaJIT.
導入 luajava 源碼
創建 jni/luajava/ 目錄,將 luajava.c 復制到創建的目錄。
在 jni/ 下創建 Android.mk,輸入 include $(call all-subdir-makefiles).
導入 LuaJIT 靜態庫
在 jni/luajava/ 下根據 ABI 創建子目錄,例如 armeabi-v7a x86,將之前編譯出的 .a 文件放進對應的目錄中。
在 jni/luajava/ 下創建 Android.mk,輸入:
將需要的頭文件復制到 jni/luajava/ 目錄。
包括:lauxlib.h lua.h lua.hpp luaconf.h luajava.h luajit.h lualib.h
這些文件可以在 LuaJIT 的源碼目錄找到。
最后在模塊的 build.gradle 文件的 android->defaultConfig 節點內添加下面代碼:
編譯完成后就可以愉快地使用 LuaJIT 了。
源碼與懶人必備
源碼已經在 github 了。
并且傳到了 JCenter,無需自己編譯,直接添加依賴就可以使用: