Android NDK系列一(ndk在android studio基本編譯配置 ndk-build 和 cmake)

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文件如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章