android中编译和使用luajit开发应用,Android 嵌入 LuaJIT 的曲折道路
相關鏈接: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.
wget https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
解壓放在 /opt/android/ndk.
然后配置環境變量。這里直接配置全局的環境變量。修改 /etc/proile 在最后加上
export PATH=/opt/android/ndk:$PATH
注銷重新登錄一下使之生效。測試下命令 ndk-build,能運行則是配置完畢。
編譯
首先去 LuaJIT 官網下載源碼并解壓。
wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
tar -zxvf LuaJIT-2.0.5.tar.gz
按照官方指南,新建一個 build.sh 放在解壓目錄下,根據實際需求輸入指令:
注意根據實際環境配置,有幾個地方需要修改一下。
NDK=/opt/android/ndk #注意匹配實際ndk目錄
NDKABI=14
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9 #注意匹配實際版本號
NDKP=$NDKVER/prebuilt/linux-x86_64/bin/arm-linux-androideabi- #注意匹配實際路徑
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
NDKARCH="-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8"
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF $NDKARCH"
然后執行 sh build.sh 就應該可以編譯了。
但是實際情況總是沒有那么順利。
折騰了3天,最后發現原來是變量引用問題。我不是很熟悉 shell,所以也就不再深究了,直接把 make 的所有參數寫在一行里,就這么神奇地成功了。
make HOST_CC="gcc -m32" CROSS=/opt/android/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi- TARGET_FLAGS="--sysroot=/opt/android/ndk/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8"
如果之前編譯(失敗)過,記得先 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,輸入:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := luajit # 預編譯模塊名稱,任意。
# 指定靜態庫的位置。$(TARGET_ARCH_ABI)表示當前編譯的ABI名稱。
LOCAL_SRC_FILES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/libluajit.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := luajava
LOCAL_SRC_FILES := luajava.c
LOCAL_STATIC_LIBRARIES := luajit # 指定依賴的預編譯模塊名稱。
include $(BUILD_SHARED_LIBRARY)
將需要的頭文件復制到 jni/luajava/ 目錄。
包括:lauxlib.h lua.h lua.hpp luaconf.h luajava.h luajit.h lualib.h
這些文件可以在 LuaJIT 的源碼目錄找到。
最后在模塊的 build.gradle 文件的 android->defaultConfig 節點內添加下面代碼:
ndk {
abiFilters 'armeabi-v7a', 'x86' # 根據實際情況選擇ABI(靜態庫對應文件夾必須存在)
}
編譯完成后就可以愉快地使用 LuaJIT 了。
源碼與懶人必備
源碼已經在 github 了。
并且傳到了 JCenter,無需自己編譯,直接添加依賴就可以使用:
compile 'cc.chenhe:android-luajit:1.0.0' //注意自行替換最新版本
總結
以上是生活随笔為你收集整理的android中编译和使用luajit开发应用,Android 嵌入 LuaJIT 的曲折道路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 弹窗时间,Android
- 下一篇: 华为harmonyos公测,华为鸿蒙 H