Android JNI學習筆記(三)-編譯檔案Android.mk、Application.mk 與camke

來源:互聯網
上載者:User

標籤:++   private   imu   addclass   archive   release   help   類型   down   

1. 前言

在android2.2中,加入了cmake編譯,而以前都是用Android.mk、Application.mk的,今天就來記錄下,他們的配置選項。

2. Android.mk

Android.mk在jni目錄下,用於描述構建系統的源檔案以及
shared libraries 。檔案格式如下:

  • 以LOCAL_PATH變數開始 LOCAL_PATH := $(call my-dir)
  • 緊接著是CLEAR_VARS變數 include $(CLEAR_VARS)
  • 接下來LOCAL_MODULE變數,定義來將要輸出的so檔案的名,預設情況下,輸出的so為 lib+LOCAL_MODULE變數值+.so,如果變數值前面有了lib,就不會加了,或者變數值後面有.xxx,也會去掉。
  • 接下來是LOCAL_SRC_FILES變數,聲明我們的原檔案路徑,如LOCAL_SRC_FILES := hello-jni.c
  • 最後一行是協助構建系統聯絡在一起的。include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jniLOCAL_SRC_FILES := hello.cppinclude $(BUILD_SHARED_LIBRARY)

當然,上面只是一個最簡單的,下面我們來介紹其他的一些變數和宏。

構建系統提供了許多變數和宏,當然 也允許我們自訂,內建的有以下三種:

  • 以LOCAL_開始,如LOCAL_MODULE
  • 以PRIVATE_, NDK_, or APP
  • 小寫字母,如 my-di

如果要自訂的話,建議MY_開頭。

2.1 NDK 預設的變數
  • CLEAR_VARS 用來在描述新model之前引入這個指令碼,會清除之前的值 include $(CLEAR_VARS)
  • BUILD_SHARED_LIBRARY,告訴構建系統去收集聲明的LOCAL_變數的值,然後輸出成so include $(BUILD_SHARED_LIBRARY)
  • BUILD_STATIC_LIBRARY,和BUILD_SHARED_LIBRARY類似,不過不會複製到project/packages,但是可以提供給shared libraries用,會輸出成.a include $(BUILD_STATIC_LIBRARY)
  • PREBUILT_SHARED_LIBRARY 用於指定預先編譯好的共用庫,但是LOCAL_SRC_FILES是so檔案 include $(PREBUILT_SHARED_LIBRARY)
  • PREBUILT_STATIC_LIBRARY 和PREBUILT_SHARED_LIBRARY 類似
  • TARGET_ARCH 略,重點看TARGET_ARCH_ABI
  • TARGET_PLATFORM 指定當前編譯的android api版本 TARGET_PLATFORM := android-22
  • TARGET_ARCH_ABI 指定cpu架構,TARGET_ARCH_ABI := arm64-v8a
  • TARGET_ABI,指定android api版本魚abi架構,TARGET_ABI := android-22-arm64-v8a
2.2 Module-Description Variables 描述model的變數
  • LOCAL_PATH 指定當前檔案的路徑,必須在檔案開始的時候指定 LOCAL_PATH := $(call my-dir),注意CLEAR_VARS,並不會清除這個的值
  • LOCAL_MODULE
  • LOCAL_MODULE_FILENAME 可以指定產生的so檔案的名字
  • LOCAL_SRC_FILES 指定這個model對應的原檔案
  • LOCAL_CPP_EXTENSION 配置c++ 檔案尾碼(副檔名),是c++、cc還是其他
  • LOCAL_CPP_FEATURES 指定特定的c++特性 如支援RTTI (RunTime Type Information),LOCAL_CPP_FEATURES := rtti
  • LOCAL_C_INCLUDES 指定路徑列表,相對於ndk的跟路徑
  • LOCAL_CFLAGS、LOCAL_CPPFLAGS 可以指定額外的宏定義和編譯選項
  • LOCAL_STATIC_LIBRARIES、LOCAL_SHARED_LIBRARIES 指定其他的static libraries、shared libraries
  • LOCAL_WHOLE_STATIC_LIBRARIES 整個。
  • LOCAL_LDLIBS 指定系統-l指定系統庫,如/system/lib/libz.so LOCAL_LDLIBS := -lz
  • LOCAL_LDFLAGS 略,沒看明白
  • LOCAL_ALLOW_UNDEFINED_SYMBOLS 預設情況下,當構建系統遇到遇到未定義的引用在試圖建立一個共用的,它會拋出未定義符號錯誤。這個錯誤可以協助debug。
  • 剩下的許多 並不常用,暫時到這裡,以後有機會用的話,查文檔吧。
3. Application.mk

用於描述app需要的native model。

3.1 變數
  • APP_PROJECT_PATH 這個變數儲存應用程式的項目根目錄的絕對路徑。
  • APP_OPTIM 配置release和debug
  • APP_CFLAGS 這個變數儲存一組構建系統的C編譯器標誌傳遞給編譯器編譯任何C或c++原始碼的任何模組,可以修改應用需要的構建模組而不用修改Android.mk檔案
  • APP_CPPFLAGS 和 APP_CFLAGS類似
  • APP_LDFLAGS A set of linker flags that the build system passes when linking the application,只對 shared libraries 和 executables有效
  • APP_BUILD_SCRIPT 指定Android.mk檔案
  • APP_ABI 指定abi
  • APP_PLATFORM 指定android api版本
  • APP_STL 連結其他的c++支援
  • NDK_TOOLCHAIN_VERSION gcc編譯版本
  • APP_PIE
  • APP_THIN_ARCHIVE
4.在Android Studio中使用

要求 Android Studio 2.2 以上。

在gradle中,

android {  defaultConfig {      externalNativeBuild {      cmake {        // 設定cmake參數 "-DVAR_NAME=VALUE"        arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"      }    }    // 設定 abi    ndk {            abiFilters "armeabi","x86","armeabi-v7a"        }  }  buildTypes {...}  externalNativeBuild {    cmake {        // CMakeLists.txt 檔案路徑        path ‘src/main/jni/CMakeLists.txt‘     }  }}

我們需要編寫的就是上面三處有注釋的地方。

  • cmake參數 格式為 -D + Variable name = Arguments 的形勢
    • ANDROID_TOOLCHAIN cmake編譯鏈,gcc 和clang(預設)兩種
    • ANDROID_PLATFORM target Android platform
    • ANDROID_STL cmake編譯時間用哪個stl,有以下種類Helper Runtimes
    • ANDROID_PIE 指定是否使用位置獨立的可執行(餅)。Android的動態連結器支援派在Android 4.1(API級16)和更高。
    • ANDROID_CPP_FEATURES 指定特定的c++特性CMake編譯時間需要使用本地庫,比如c++ RTTI(運行時類型資訊)和異常,rtti,exceptions
    • ANDROID_ALLOW_UNDEFINED_SYMBOLS 指定是否拋出未定義符號錯誤如果CMake遇到一個未定義的引用而建立你的本地庫。禁用這些類型的錯誤,將這個變數設定為TRUE。
    • ANDROID_ARM_MODE 設定產生的二進位檔案arm 還是 thumb模式,thumb模式下,每個指令都是16bits,arm模式下為32位,預設是 thumb
    • NDROID_ARM_NEON build native lib 是否NONE支援
    • ANDROID_DISABLE_NO_EXECUTE 是否允許ne bit,或者執行、或者安全特訓過
    • ANDROID_DISABLE_RELRO 是否唯讀
    • ANDROID_DISABLE_FORMAT_STRING_CHECKS 指定與格式字串是否編譯原始碼的保護。當啟用時,編譯器將拋出一個錯誤如果不恒定格式字串中使用printf-style函數。
  • ndk abifilters
  • cmake path

關於cmake 參數,官方文檔

5. CMakeLists.txt 編寫
  • cmake_minimum_required(VERSION 3.4.1) cmake的最小版本
  • add_library(native lib name,SHARED(SHARED還是STATIC),c++或c檔案路徑)
  • include_directories(src/main/cpp/include/) 指定標頭檔路徑
添加native api
find_library( # Defines the name of the path variable that stores the              # location of the NDK library.              log-lib              # Specifies the name of the NDK library that              # CMake needs to locate.              log )

按照我個人的理解,

  • 第一個就是lib庫的別名,就是我們在這個檔案中其他地方要使用的。
  • 第二個參數是對應的native lib庫的名字,第二個參數在ndk-bundle/platforms/android版本/下面能找到。根據我們上面說到的產生so檔案規則,能夠很清楚的提出lib name

然後使用target_link_libraries(native-lib,${log-lib}) 去連結咱們的本地庫和ndk中帶的本地庫,

也可以將原始碼添加進來,

add_library( app-glue             STATIC             ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
  • lib name
  • 類型
  • 檔案路徑
添加其他預先構建的libraries

因為這些已經有的,需要用 IMPORTED 去告訴cmkae,只需要將這個lib匯入到咱們的project

add_library( imported-lib             SHARED             IMPORTED )

然後需要用set_target_properties去指定路徑。

set_target_properties( # Specifies the target library.                       imported-lib                       # Specifies the parameter you want to define.                       PROPERTIES IMPORTED_LOCATION                       # Provides the path to the library you want to import.                       imported-lib/src/${ANDROID_ABI}/libimported-lib.so )
  • lib name
  • 指定參數
  • 指定so的路徑

這時候需要include_directories來指定so對應的標頭檔路徑,上面也說到過了。

6. 總結

有理解的不對的,大家指出,共同學習共同進步。

參考資料:

  • Android.mk、文檔
  • Application.mk 文檔
  • Android 文檔cmake 文檔
  • Android studio 中介紹

Android JNI學習筆記(三)-編譯檔案Android.mk、Application.mk 與camke

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.