xmake從入門到精通5:Android平臺編譯詳解

xmake是一個基於Lua的輕量級現代化c/c++的項目構建工具,主要特色是:語法簡單易上手,提供更加可讀的項目維護,實現跨平臺行爲一致的構建體驗。android

本文主要詳細講解如何經過xmake編譯可在android下運行的庫和可執行程序。c++

準備工做

首先,咱們須要先準備好編譯android native庫必須的ndk工具鏈,若是尚未能夠從官網下載解壓便可:Android NDKgit

若是是爲了獲取更好的向下兼容性,能夠選擇r16版本,由於這個是最後一個支持armeabi的版本,若是沒什麼特別需求,能夠直接下載最新版。github

NDK集成和編譯

手動配置NDK

咱們只須要將解壓後ndk目錄路徑傳遞給xmake完成配置,能夠直接編譯了,例如:macos

$ xmake f -p android --ndk=~/downloads/android-ndk-r19c
$ xmake
複製代碼

其中,-p android用於切換到android平臺,由於若是不指定平臺,默認會編譯當前主機平臺的target程序。api

一般,若是沒特殊需求,上面的配置就能夠完成android native程序的編譯,目前xmake內置支持:binary, static, shared這三種基礎target類型文件的生成,分別對應可執行程序,.a靜態庫,.so動態庫。bash

NDK路徑的全局配置

xmake f/config命令僅僅是針對當前項目的配置,若是常常跨平臺編譯和配置切換都要從新設置一遍ndk路徑,那麼仍是稍顯繁瑣。架構

咱們能夠經過xmake g/global全局配置命令來設置它,確保永久生效。函數

$ xmake g --ndk=~/xxx/android-ndk-r19c
複製代碼

咱們也能夠經過設置ANDROID_NDK_HOME全局環境變量來確保永久生效,這跟上述命令配置的效果是差很少的。工具

NDK路徑的自動探測

一般狀況下即便沒有配置ndk路徑,xmake仍是會嘗試默認檢測一些經常使用路徑,好比在macos下會自動探測是否存在如下路徑:

~/Library/Android/sdk/ndk-bundle
複製代碼

這是mac下裝完android studio自動建立的sdk目錄,以及ndk的經常使用放置路徑。

或者嘗試從ANDROID_NDK_HOME這種環境變量中探測,若是存在的話。

若是能探測到,也就不必再額外手動配置了。

C++ STL庫配置切換

首先,咱們先來介紹下,ndk提供的三種stl庫版本

  • stlport:早期ndk內置的stl庫,如今基本已廢棄
  • gnustl:ndk r16b以前主要使用的stl庫,可是自從r16b以後,也已經被google去掉了
  • llvm-c++:r16b以後較新的ndk內置的stl庫

所以,咱們在編譯android庫的時候,須要根據本身的需求,選用stl,以及選用合適的ndk版本,而xmake一般會盡量默認使用llvm-c++庫,若是發現當前ndk版本比較老,會嘗試退化到gnustl上去。

用戶也能夠手動修改stl庫的版本,例如:

$ xmake f -p android --ndk=xxxx --ndk_cxxstl=gnustl_shared
複製代碼

具體,關於ndk_cxxstl選項的配置值,能夠敲help查看,xmake f --help,主要就是:

  • llvmstl_static
  • llvmstl_shared
  • gnustl_static
  • gnustl_shared
  • stlport_static
  • stlport_shared

API版本設置

若是在編譯過程當中,報出一些libc庫符號找不到,一般有多是api版本沒設置對,由於有些libc函數,只有在高版本api下才存在。

這個時候,咱們能夠經過嘗試手動修改api版原本解決:

$ xmake f -p android --ndk=xxx --ndk_sdkver=16
複製代碼

arch的編譯切換

目前xmake提供 armv7-a, arm64-v8a, armv5te, mips, mips64, i386,x86_64這些架構的配置編譯,若是沒有指定arch,那麼默認會使用armv7架構。

手動修改arch方式以下:

$ xmake f -p android --ndk=xxx -a arm64-v8a
複製代碼

Android相關配置設置

若是項目中須要配置一些只有android平臺纔有的編譯設置,好比添加特定宏開關,連接庫等,能夠在xmake.lua中,經過is_plat("android")來判斷處理。

target("test")
    set_kind("shared")
    add_files("src/*.c")
    if is_plat("android") then
        add_defines("ANDROID")
        add_syslinks("log")
    end
複製代碼

FAQ

遇到一些libc/stl庫頭文件找不到怎麼辦?

能夠嘗試修改stl庫版本,和api版原本解決,好比ndk r16b 推薦使用gnustl庫,由於這個版本的llvmc++庫剛集成進去不久,問題比較多,使用過程當中容易遇到各類編譯問題。

$ xmake f -p android --ndk=xxxx --ndk_cxxstl=gnustl_shared --ndk_sdkver=16
複製代碼

編譯生成的可執行程序在設備上運行不起來?

一般是api版本設置過高,致使的不兼容問題,能夠嘗試調低api版本。

原文:tboox.org/cn/2019/11/…

相關文章
相關標籤/搜索