ndkbuild 与 cmake
在 Android 项目中使用 jni 有两种编译方案,一种是传统的ndkbuild,一种是当前推荐使用的 cmake;下面来分别介绍这两种方式;我的AS版本 3.2:
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文件,如图:
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文件如下: