2018年11月19日 星期一

ndk-build的使用心得

ndk-build的使用心得

前言

  最近將繪圖引擎跨到Android,在繪圖API的部分會面臨到選擇GLES的版本的問題,還有像是GLES3只有64位元支援,如果只靠修改Android.mk與Application.mk的話會沒辦法做出像是組態(Configuration)的效果,所以對ndk-build做了研究,在此做個紀錄。

內容

  ndk-build本身不提供組態(Configuration)的功能,但可以透過參數指定Android.mk與Application.mk,這做法可以做出組態(Configuration)的效果,但只要想想組態越多,Android.mk與Application.mk的數量也會隨著組態而增多,GLES的版本目前有GLES2、GLES3、GLES3.1與GLES3.2,如果用這個方法就會有8個檔案要維護,加上共用的部分還要隔開的成本,做了一下我就放棄這個做法,因為成本有點高。

  在google一陣子後發現ndk-build可以直接從命令列新增或修改在Android.mk與Application.mk的參數,比方說"APP_ABI"這個參數,在入門教學中會把該參數寫在Application.mk,用來決定要建置的ABI,但事實上是可以用ndk-build的命令列來修改,命令如下
ndk-build APP_ABI=arm64-v8a

當用這個命令後,請移除Application.mk裡的"APP_ABI"的設定,不然ndk-build社的數值會被覆蓋,如果要設定多個參數就用空白隔開即可。只靠這個方法來實現組態會不太夠,必須再搭配makefile的if語法,語法的範例如下
ifeq ($(GLES_VERSION),GLES2)
GLES_LIBS := -lGLESv2
endif
ifeq ($(GLES_VERSION),GLES3)
GLES_LIBS := -lGLESv3
endif
ifeq ($(GLES_VERSION),GLES3_1)
GLES_LIBS := -lGLESv3
endif
ifeq ($(GLES_VERSION),GLES3_2)
GLES_LIBS := -lGLESv3
endif

範例中使用"GLES_VERSION"這個變數來決定最後的要載入的LIB,"GLES_VERSION"是自訂的,搭配之前的方法可以在ndk-build的命令列隨喜好來修改,這樣不論是選GLES版本或者是只能建64位元版本都可以解決了!

  ndk-build在指定ABI的版本來建置後,會把非建置版本的ABI移除,例如APP_ABI=arm64-v8a時,x86_64、armeabi-v7a與x86都會被移除,這個問題目前解決的方案不是很好,就是每個ABI都分不同資料夾來建置,可以在ndk-build的命令列修改"NDK_OUT"與"NDK_LIBS_OUT"來完成,這個方法可行,但就是覺得不太優雅,有機會再找找有沒有優雅的解決方案。

  ndk-build的clean有點討厭,它只為清除LIB,但不會清除OBJ,如果需要完整重建的話,就手動清空或是寫個命令來清除。

  最後來說一下命令的部分,我個人是使用Python來執行ndk-build並選擇組態(Configuration),不選擇Shell與bash只是單純地不熟,但Python雖然跨平台,但有新舊版本的問題(Python2.7與Python3),這部分的實現目前就這樣解決,如果有更好的方法以後再來說明。

參考資料

Application.mk
ndk-build

沒有留言:

張貼留言