AndroidStudio3.0环境,NDK使用CMake编So

谷歌从AndroidStudio2.2以上就添加了Cmake方式来编译So库,
这种方式比起原来命令行式的ndk-build方便了不少,
也不需要Android.mk,Application.mk和JNI文件夹了。

在下方的谷歌Android官方链接可以看到一个中文NDK的教程。
https://developer.android.com/studio/projects/add-native-code.html
而这个链接是谷歌Android官方英文Cmake指南
https://developer.android.com/ndk/guides/cmake.html
这俩都要认真上网才能看。

Using Android Studio 2.2 and higher, you can use the NDK and CMake to compile C and C++ code into a native library. Android Studio then packages your library into your APK using Gradle, the IDE's integrated build system.

先说一下具体环境,使用的是,Windows10 + AndroidStudio3.0

新建一个NDK工程

首先创建一个新项目,选中Include C++ support,因为是NDK项目嘛(见图1)
然后一路点Next,可以选Empty Activity,Layout文件也不需要,
因为是为了编So库嘛,不是为了做apk。(见图2,图3)
最后则要选定C++标准,(比如C++11),异常,RTTI,(见图4)
就完成了,非常简单。

图片1.png

图片2.png
图片3.png
图片4.png

CMake构建

图片5.png

工程完成后,先关注下新建好的工程的目录结构,(见图5)
最主要看两个文件,app目录内的build.gradle和CMakeList.txt
build.gradle是gradle构建的配置定义文件,这里就不展开讲了,只关注和CMake相关的。

externalNativeBuild {
    cmake {
        cppFlags "-std=c++11 -frtti -fexceptions"
    }
}

externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}

cppFlags是刚才选择的C++11,rtti和异常
CMakeList.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_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.
set(libs "${CMAKE_SOURCE_DIR}/libs")
add_library( # Sets the name of the library.
             native-lib
             # Sets the library as a shared library.
             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.

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.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

cmake_minimum_required(VERSION 3.4.1)用来设置在编译本地库时我们需要的最小的cmake版本,AndroidStudio自动生成,我们几乎不需要自己管。
以下是几个常用命令:
set,CMake设置变量,变量在下面就可以使用
add_library用来设置编译生成的本地库的名字为native-lib,SHARED表示编译生成的是动态链接库(这个概念前面已经提到过了),src/main/cpp/native-lib.cpp表示参与编译的文件的路径,这里面可以写多个文件的路径。
find_library 是用来添加一些我们在编译我们的本地库的时候需要依赖的一些库,由于cmake已经知道系统库的路径,所以我们这里只是指定使用log库,然后给log库起别名为log-lib便于我们后面引用,此处的log库是我们后面调试时需要用来打log日志的库,是NDK为我们提供的。
target_link_libraries 是为了关联我们自己的库和一些第三方库或者系统库,这里把我们把自己的库native-lib库和log库关联起来。
set_target_properties 命令的意思是设置目标的一些属性来改变它们构建的方式。

常见用法:
1)设置输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI})
修改So的生成路径至main/libs,与main/cpp同级。

2)引用第三方库,通过set_target_properties,
设置IMPORTED_LOCATION,就是被引入So库所在路径。

 add_library(usb-1.0.9
             SHARED
             IMPORTED
 )
 set_target_properties(usb-1.0.9
                       PROPERTIES IMPORTED_LOCATION
                      "${libs}/${ANDROID_ABI}/libusb-1.0.9.so")

3)为子目录编译So库文件,
有的时候,我们并不想把所有代码文件打包成单一个So,那么可以为子目录写一个CMakeList.txt,
在这个子CMakeList.txt内,add_library,target_link_libraries,
然后在主CMakeList.txt里加一句add_subdirectory(src/main/cpp/子目录路径),
这样就会为子目录也生成一个So库文件,
我们在主CMakeList.txt里可以像引用第三方库一样引用这个子目录了。
更多:
对多个So编译,这两篇文章写的很好的。
分别是子目录多Module编译多个So库文件。我就不赘述了。
子目录方式:http://blog.csdn.net/b2259909/article/details/58591898
多Module方式:https://www.jianshu.com/p/4e3c0c20c244

4)编译Debug版和Release版
target_link_libraries可以附带debug,optimized的参数
用法如下:

target_link_libraries( # Specifies the target library.
                       native-lib
                       debug/optimized
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

target_link_libraries(< target> [item1 [item2 […]]] [[debug|optimized|general] < item>] …)
这个更多的具体的用法,可以看后面附的CMake命令链接。

5)CMake引入CpuFeatures库
在CMakeList.txt里加这两句,然后就可以在target_link_libraries调用cpufeatures了

include(AndroidNdkModules)
android_ndk_import_module_cpufeatures()

target_link_libraries( # Specifies the target library.
                       native-lib
                       cpufeatures
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

更进一步学习CMake
https://www.zybuluo.com/khan-lau/note/254724
这篇文章很好,翻译了https://cmake.org/cmake-tutorial/,和CMake的80个命令
CMake的全部命令,官网链接:
https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html
CMake的帮助文档,官网链接:
https://cmake.org/cmake/help/latest/index.html

最后,编译So库


点击Make Project,各个ABI的So,就生成在相应的目录内了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容