NDK(23) 使用CMake 构建 c/c++代码库
1.官网
https://developer.android.com/studio/projects/add-native-code.html
2.android studio 安装相关工具
- 在打开的项目中,从菜单栏选择 Tools > Android > SDK Manager。
- 点击 SDK Tools 标签。
- 选中 LLDB、CMake 和 NDK 旁的复选框,如图所示.
3.新建支持c/c++的项目
- 在android studio 3.4.1 新建向导里选 Native C++ 模板.
2.选择想要使用的c++标准,如C++14.
3.最后 生成的项目如下:
其中:
- CMakeLists.txt 是cmake构建工程要用的项目配置文件,类似android.mk.
- native-lib.cpp是源文件
4.编辑代码,使用本地程序....
4.在现有项目中添加 c/c++库
4.1 创建 jni目录
项目名(或者File) ---> 右键 ---> New ---> Folder ---> JNI Folder
4.2 创建 CMakeLists.txt文件
在上一步上创建的jni目录(当前版本目录名是cpp) 右键 ---> New ---> File 输入CMakeLists.txt
4.3 配置CMakeLists.txt 文件
# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build. cmake_minimum_required(VERSION 3.4.1) # Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK. add_library( # Specifies the name of the library.
# 本地库名
student-lib # Sets the library as a shared library.
# 本地库的类型
SHARED # Provides a relative path to your source file(s).
# 要编译的源文件 ,多个之间用空格.
student.cpp school.cpp) # Specifies a path to native header files.
include_directories(inc) #添加本地代码依赖的其它系统库.
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 ) # Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.
student-lib # Links the log library to the target library.
${log-lib} )
- 注意CMakeLists.txt中源文件和include的路径引用问题,这里是和源文件同级.
- CMakeLists.txt 常用函数含义
- 下面是常用的cmake命令.
cmake命令官网 : https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html
add_library() |
向您的 CMake 构建脚本添加源文件或库 add_library( # Specifies the name of the library. |
include_directories |
指定头文件的路径 add_library(...) # Specifies a path to native header files. |
find_library() |
添加引用的NDK 库 find_library( # Defines the name of the path variable that stores the |
target_link_libraries() |
链接多个库 target_link_libraries( native-lib imported-lib app-glue ${log-lib} ) |
add_library() |
将其它源代码编译到本地库中. add_library( app-glue |
set_target_properties 和 IMPORTED |
IMPORTED不是个函数,只是add_library的参数,添加其他预构建的本地库 然后,您需要使用 set_target_properties() 命令指定库的路径. |
4.4 关联Gradle与 CMakeLists.txt
右键点击您想要关联的模块(例如 app 模块),并从菜单中选择 Link C++ Project with Gradle。关联到之前创建的CMakeLists.txt,点OK.
4.5 完成本地的c/c++代码工作
MainActivity.java
public class MainActivity extends AppCompatActivity { // Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
} /**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
native-lib.cpp
#include <jni.h>
#include <string> extern "C" JNIEXPORT jstring JNICALL
Java_com_example_cpp14_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
5.在 Gradle 中使用 CMake 变量
https://developer.android.com/ndk/guides/cmake.html#variables
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake or ndk-build script.
externalNativeBuild { // For ndk-build, instead use ndkBuild {}
cmake { // Passes optional arguments to CMake.
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" // Sets optional flags for the C compiler.
cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2" // Sets a flag to enable format macro constants for the C++ compiler.
cppFlags "-D__STDC_FORMAT_MACROS"
}
}
} buildTypes {...} ...
}
6.指定本地库的cpu架构
默认情况下,Gradle 会针对 NDK 支持的 ABI 将您的原生库构建到单独的 .so
文件中,并将其全部打包到您的 APK 中。如果您希望 Gradle 仅构建和打包原生库的特定 ABI 配置,您可以在模块级 build.gradle
文件中使用 ndk.abiFilters
标志指定这些配置.
apply plugin: 'com.android.application' android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.tocpp5"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// This block is different from the one you use to link Gradle
// to your CMake or ndk-build script.
externalNativeBuild {
// For ndk-build, instead use ndkBuild {}
cmake {
// Passes optional arguments to CMake.
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" // Sets optional flags for the C compiler.
cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2" // Sets a flag to enable format macro constants for the C++ compiler.
cppFlags "-D__STDC_FORMAT_MACROS" abiFilters 'armeabi-v7a','arm64-v8a' }
}
30 ndk {
31 // Specifies the ABI configurations of your native
32 // libraries Gradle should build and package with your APK.
33 abiFilters 'x86', 'x86_64', 'armeabi-v7a','arm64-v8a'
34 }
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path file('src/main/jni/CMakeLists.txt')
}
}
} dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
在 defaultConfig.externalNativeBuild.cmake {}
块
或
defaultConfig.externalNativeBuild.ndkBuild {}
块
中配置另一个 abiFilters
标志。Gradle 会构建defaultConfig.ndk中的 ABI 配置,不过仅会打包在 defaultConfig.
块中指定的配置。cmake或者
{}ndkBuild
NDK(23) 使用CMake 构建 c/c++代码库的更多相关文章
- 构建自己的代码库在Code-Google上
多年工作的代码,有不少可以抽象出来作为工具类的.如果每次都把项目的工具类存放到U盘.必然会造成维护的问题.主要是你不可能天天的带u盘 去代码里复制粘贴.去code.google.com建立自己的代码库 ...
- CMake 构建项目教程-简介
CMake 构建项目教程-简介 Linux 平台构建项目,选择了CLion作为C++的IDE,而CLion默认就是使用CMake构建项目,所以这里记录了CMake在构建项目过程的一些小知识. 1. 项 ...
- 在 linux 下使用 CMake 构建应用程序
学习cmake http://xwz.me/wiki/doku.php?id=cmake 碰到的一些问题: 1.You have changed variables that require your ...
- 【经验分享】win10 cmake 构建 Tengine 工程
欢迎关注我的公众号 [极智视界],回复001获取Google编程规范 O_o >_< o_O O_o ~_~ o_O 本教程详细记录了在 win10 环境中 ...
- Jenkins+PMD构建自动化静态代码检测
前言:软件缺陷是不可避免的,要尽量减少错误并提高软件质量,主要有两在类技术,即缺陷预防和缺陷检测 缺陷预防包括编写更好的设计规范.实施代码审核制度.运行代码静态分析工具.运行单元测试等 PMD是一种开 ...
- mac book pro macOS10.13.3安装qt、qt creator C++开发环境,qt5.11.1,并解决cmake构建:qt mac this file is not part of any project the code
因为之前在Ubuntu下使用的是qtcreator开发,现在想在mac上装一个系统,因为许久未装了,还是花了点时间,不如写个博客,下次就更快安装了.在Mac OS X下使用Qt开发,需要配置Qt库和编 ...
- AndroidStudio2.2 Preview3中NDK开发之CMake和传统 JNI在目录结构和配置文件上的区别(转载)
自从AndroidStudio更新到2.2,就有了CMake和传统JNI两种开发NDK的方法,主要就是在目录结构和build.gradle上的区别,下面我们将分别介绍目录区别和build.gradle ...
- 在linux下使用CMake构建应用程序
本文介绍了一个跨平台的自动化构建系统 CMake 在 linux 上的使用方法. CMake 是一个比 automake 更加容易使用的工具,能够使程序员从复杂的编译连接过程中解脱出来.文中通过一些例 ...
- 在 linux 下使用 CMake 构建应用程序【转】
本文转载自:https://www.ibm.com/developerworks/cn/linux/l-cn-cmake/index.html CMake 简介 CMake 是一个跨平台的自动化建构系 ...
随机推荐
- iOS开发系列-文件下载
小文件下载 NSURLConnection下载小文件 #import "ViewController.h" @interface ViewController ()<NSUR ...
- 满血复活前的记录(持续更新ing)
时隔一年重新开启算法竞赛征程. 该记录大多为老课件.已经做过的习题重做和已经看过的书本重看 7.21 下午到山大 娄晨耀basic_algorithm课件中的内容: 复习线性筛原理 复习差分 做完Co ...
- android-启动另外一个Activity
启动另外一个Activity 在完成了上一节课的学习后,我们已经创建了一个带有text输入框和一个button的app. 在本课中,我们将在MainActivity类中添加SendButton的单击响 ...
- 在DataWorks中实现指定UDF只能被指定账户访问
背景 之前写过一篇文章是关于“DataWorks和MaxCompute内部权限体系的区别”有兴趣的朋友可以点击阅读查看详情.但是还是有些同学会问,我如何在DataWorks中实现我的具体某个Resou ...
- TokuDB安装
安装TokuDB 1, 创建mysql数据目录 #顺便把临时目录创建好 mkdir -p /data/mysql/tmp groupadd -r mysql useradd -g mysql -r - ...
- vue基础知识总结
vue不支持安卓6.0以下版本,切记!!! 1.创建vue实例 var vm = new Vue({ el: '#app', //所指向的dom的id data:{ }, //与dom元素绑定的数据 ...
- 密码学笔记(4)——RSA的其他攻击
上一篇详细分析了几种分解因子的算法,这是攻击RSA密码最为明显的算法,这一篇中我们考虑是否有不用分解模数n就可以解密RSA的密文的方法,这是因为前面也提到,当n比较大的时候进行分解成素数的乘积是非常困 ...
- Struts2中param的作用
1.页面传参与配置传参的区别:如果页面Form表单的参数在Action类中有相应的setter方法,则会优先取页面Form表单传过来的值,如果页面没有该属性同名的参数,则会从配置文件中取同名的参数值作 ...
- spring容器创建bean对象的方式
xml文件中有bean的配置,而且这个bean所对应的java类中存在一个无参构造器 那么这个时候spring容器就可以使用反射调用无参构造器来创建实例了(常规的方式) 通过工厂类获得实例(工厂类实现 ...
- 网络结构解读之inception系列三:BN-Inception(Inception V2)
网络结构解读之inception系列三:BN-Inception(Inception V2) BN的出现大大解决了训练收敛问题.作者主要围绕归一化的操作做了一系列优化思路的阐述,值得细看. Batch ...