ndkbuild 與 cmake
在 Android 項目中使用 jni 有兩種編譯方案,一種是傳統的ndkbuild,一種是當前推薦使用的 cmake;下面來分別介紹這兩種方式;我的AS版本 3.2:
1.ndk-build方式配置方式:
1.創建Android.mk文件,這裏我創建在cpp目錄中,這個目錄可以自己定,之後在build.grade中設置就行了
2.編寫Android.mk
#每個Android.mk文件必須以定義LOCAL_PATH爲開始。它用於在開發tree中查找源文件。宏my-dir 則由Build System提供。返回包#含Android.mk的目錄路徑。
LOCAL_PATH := $(call my-dir)
#CLEAR_VARS 變量由Build System提供。並指向一個指定的GNU Makefile,由它負責清理很多LOCAL_xxx.
#例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH.
#這個清理動作是必須的,因爲所有的編譯控制文件由同一個GNU Make解析和執行,其變量是全局的。所以清理後才能避免相互影響
include $(CLEAR_VARS)
#LOCAL_MODULE模塊必須定義,以表示Android.mk中的每一個模塊。名字必須唯一且不包含空格。Build System會自動添加適當的#前綴和後綴。例如,foo,要產生動態庫,則生成libfoo.so. 但請注意:如果模塊名被定爲:libfoo.則生成libfoo.so. 不再加前綴
#如果您將模塊命名爲'libfoo',構建系統將不會添加另一個'lib'前綴並生成libfoo。所以。
#這是爲了支持Android。來自安卓平臺的mk文件,需要用到這些
LOCAL_MODULE := native-lib
#用於指示C/ c++編譯器在其中查找頭文件的其他目錄。這些路徑是在最上層的下面。如果在include路徑中有自己的子目錄,則使用LOCAL_PATH。
#有些庫如果沒有引入成功,代碼中沒有提示,就是因爲這裏沒有配置對;
#下面的例子中 LOCAL_PATH 代表上面設置的目錄,即當前Android.mk文件所在目錄,NDK_ROOT 指的是ndk安裝所在的目錄
LOCAL_C_INCLUDES+= $(LOCAL_PATH)/includes \
$(NDK_ROOT)/sources/cxx-stl/llvm-libc++/include \
$(LOCAL_PATH) \
$(JNI_H_INCLUDE)
#LOCAL_SRC_FILES變量必須包含一個C和/或c++源文件列表,這些源文件將被構建和組裝到一個模塊中。注意,您應該
#這裏不列出頭文件和包含的文件,因爲構建系統將自動爲您計算依賴關係;只列出源文件
#它將直接傳遞給編譯器,您應該會做得很好。
#注意,c++源文件的默認擴展名是'.cpp'。但是,可以通過定義變量來指定一個不同的變量
#LOCAL_CPP_EXTENSION。不要忘記起始點。”。cxx'將工作,但不是'cxx')。
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_LDLIBS := -lm -llog
#BUILD_SHARED_LIBRARY是構建系統提供的一個變量,它指向一個GNU Makefile腳本,該腳本負責收集所有的
#自最新的“include $(CLEAR_VARS)”以來在LOCAL_XXX變量中定義的信息,並確定要構建什麼以及如何構建
#完全正確。還有BUILD_STATIC_LIBRARY來生成靜態庫
BUILD_SHARED_LIBRARY:是Build System提供的一個變量,指向一個GNU Makefile Script。
它負責收集自從上次調用 include $(CLEAR_VARS) 後的所有LOCAL_XXX信息。並決定編譯爲什麼。
NDK還定義了很多其他的BUILD_XXX_XXX變量,它們用來指定模塊的生成方式。
BUILD_STATIC_LIBRARY :編譯爲靜態庫。
BUILD_SHARED_LIBRARY :編譯爲動態庫
BUILD_EXECUTABLE :編譯爲Native C可執行程序
BUILD_PREBUILT :該模塊已經預先編譯
include $(BUILD_SHARED_LIBRARY)
3.配置app下面的build.grade:
在android節點下添加:(這一步也可以在項目文件app上右鍵--》Link C++ with gradle --》選擇ndk-build,選擇Android.mk路徑 來添加)
android{
externalNativeBuild {
ndkBuild {
path file('src/main/cpp/Android.mk')
}
}
在android defaultConfig節點下添加:
android{
defaultConfig{
//ndk-build配置
ndk {
abiFilters "x86","arm64-v8a","x86_64","armeabi-v7a" //表示.so生成的目錄
}
}
}
好,到此爲止,ndk-build編譯方式的簡單配置就可以了,native-lib.cpp中的代碼提示也有了,運行完美。查看生成的.so文件,如圖:
2.cmake方式配置:
cmake現在是谷歌默認的方式,比較推薦:
1.在項目app下創建 CmakeLists.txt文件:
2.編寫CmakeLists.txt:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
#用來設置在編譯本地庫時我們需要的最小的cmake版本
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
#創建並命名一個庫,將其設置爲靜態
#或共享,並提供到其源代碼的相對路徑。
#您可以定義多個庫,CMake爲您構建它們。
# Gradle自動將共享庫打包到APK中。
add_library(
# Sets the name of the library.
#生成.so文件的名字
native-lib
# Sets the library as a shared library.
# 設置生成的庫爲動態庫,也可以生成動態庫STATIC
SHARED
# Provides a relative path to your source file(s).
# 表示參與編譯的文件的路徑,這裏面可以寫多個文件的路徑。
src/main/cpp/native-lib.cpp )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
#搜索指定的預構建庫並將路徑存儲爲
#變量。因爲CMake在搜索路徑by中包含了系統庫
#默認情況下,您只需要指定公共NDK庫的名稱
#CMake驗證庫在完成構建之前會檢查庫是否存在
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
#指定庫CMake應該鏈接到目標庫。你
#可以鏈接多個庫,比如您在本文中定義的庫
#構建腳本、預構建的第三方庫或系統庫。
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
3.在app下build.grade中添加:
在android節點下添加:
android{
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
在android defaultConfig節點下添加:
android{
defaultConfig{
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
}
}
}
}
cmake的配置就結束了,運行完美,生成的.so文件如下: