2019独角兽企业重金招聘Python工程师标准>>>

文以简单的例子讲述如何在任意目录把自己写的C代码使用NDK提供的交叉编译该工具来编译成Android可使用的静态库/动态库。

1. 准备环境
首先,你得安装了Android的NDK编译工具,假设你的NDK的根目录在 /opt/android/ndk .

当然,最好你能在环境变量里配置一下路径,否则使用ndk-build命令的时候,都得加上路径的前缀了。

修改 ~/.bashrc

export NDK_HOME=/opt/android/ndk
export PATH=$NDK_HOME:$PATH
NDK_HOME=/opt/android/ndk
export PATH=$NDK_HOME:$PATH
1
2
3
4
然后执行:

$ source ~/.bashrc
/.bashrc
1
2
2. 编写 .c 文件
假设你在 ~/math 目录下编写了一个 math.c 文件,内容如下:

#include <stdio.h>

int add( int a , int b ) {
    return a+b;
}

int add( int a , int b ) {
    return a+b;
}
1
2
3
4
5
6
7
8
9
10
OK,后面我们就准备在 ~/math 目录下,将这个.c文件编译为Android可使用的静态库/动态库了。

3. 编译成动态库
编写 Android.mk 文件,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := dmath
LOCAL_SRC_FILES := math.c
include $(BUILD_SHARED_LIBRARY)
:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := dmath
LOCAL_SRC_FILES := math.c
include $(BUILD_SHARED_LIBRARY)
在 ~/math 目录下,执行 ndk-build 命令,参数如下:

$ ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
根据前一篇文章,我们可以知道,NDK_PROJECT_PATH 指定了需要编译的代码的工程目录,这里给出的是当前目录,APP_BUILD_SCRIPT给出的是Android makefile文件的路径,当然,如果你还有 Application.mk 文件的话,则可以添加 NDK_APPLICATION_MK=./Application.mk

执行完ndk-build命令后,你会发现当前目录下,生成了 obj 和 libs 文件夹,这样,你的libdmath.so动态库就已经制作完成了,在 libs/armeabi 目录下。

4. 编译为静态库
编译为静态库,与编译为动态库唯一的区别就是 Android.mk 文件的写法不同,另外,如果要编译为静态库,则必须有其他的代码引用该静态库代码,ndk-build才会真正执行,否则无法成功生成静态库,这里,我们编写一个 Android.mk ,将 math.c 同时编译成静态库和动态库。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := smath
LOCAL_SRC_FILES := math.c
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := dmath
LOCAL_STATIC_LIBRARIES := smath
LOCAL_SRC_FILES := math.c
include $(BUILD_SHARED_LIBRARY)
:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := smath
LOCAL_SRC_FILES := math.c
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := dmath
LOCAL_STATIC_LIBRARIES := smath
LOCAL_SRC_FILES := math.c
include $(BUILD_SHARED_LIBRARY)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
同样,在 ~/math 目录下执行:

$ ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
1
你会在生成的 libs/armeabi 目录下看到动态库libdmath.so,在 obj/local/armeabi 目录下看到静态库 libsmath.a

关于在任意目录将c/c++代码编译为Android可使用的静态库/动态库就介绍到这里了,了解了这个编译过程,对你将来用ndk编译第三方库会很有帮助,另外,如果希望编译为C/C++应用程序在Android机器上运行的话,只需要在代码中加一个main函数,修改Android.mk中的最后一行为 include $(BUILD_EXECUTABLE) 即可。有任何疑问欢迎留言或者来信lujun.hust@gmail.com交流。

5. ndk-build的编译选项
所有给ndk-build的选项都会直接传给GNU Make,由make运行NDK的编译脚本。几个常见调用方式如下:

ndk-build 编译
  ndk-build clean 清掉二进制文件
  ndk-build NDK_DEBUG=1     编译为可调试版的二进制文件
  ndk-build NDK_DEBUG=0     编译为release版
  ndk-build V=1                       执行ndk-build且打印出它所执行的详细编译命令。
  ndk-build -B                          强制重新编译
  ndk-build -B V=1                   -B 和 V=1 的组合
  ndk-build NDK_LOG=1          打印出内部的NDK日志信息(用于调试NDK自己)
  ndk-build NDK_APPLICATION_MK=<文件路径>      用这里指定的路径寻找Application.mk文件
  ndk-build -C <project路径>  先cd进入<project路径>,然后执行ndk-build。
1
2
3
4
5
6
7
8
9
10
6. 编译过程,怎么查看脚本中(makefile)中的变量
$(warning $(XXXX))
1
7. jni中如何指定编译器
在jni/Application.mk中添加

NDK_TOOLCHAIN_VERSION :=4.9
1
NDK_TOOLCHAIN_VERSION. Define this variable as 4.9 to select that version of the GCC compiler. Define this variable as clang to select the Clang compiler,

针对r14b 安卓编译包出现的编译错误:

warning: shared library text segment is not shareable
requires dynamic R_X86_64_PC32 reloc against ‘ff_pw_8’ which may overflow at runtime; recompile with -fPIC

8. ndk工程目录编译后libs与obj目录下库文件的区别
    As part of the build process, the files in the libs folder have been stripped of symbols and debugging information. So you’ll want to keep two copies of each of your .so files: One from the libs folder to install on the Android device, and one from the obj folder to install for GDB to get symbols from.
   libs目录下生成的库是剥离了符号表与调试信息的,而obj下的库是带有调试信息的。
参考网址:https://blog.csdn.net/bidgod/article/details/6930440

9. 待续
参考网址:http://www.tuicool.com/articles/QZJ3qa

参考网址:http://blog.csdn.net/crash163/article/details/52228412
--------------------- 
作者:listener51 
来源:CSDN 
原文:https://blog.csdn.net/listener51/article/details/84026778 
版权声明:本文为博主原创文章,转载请附上博文链接!

转载于:https://my.oschina.net/u/4000302/blog/3027723

【Android开发】:在任意目录执行NDK编译相关推荐

  1. Android开发实践:在任意目录执行NDK编译

    本文暂时不讲述如何用NDK编译第三方开源代码库,而是先以简单的例子讲述如何在任意目录把自己写的C代码编译成Android可使用的静态库/动态库. 1. 准备环境 首先,你得安装了Android的NDK ...

  2. Android开发学习笔记(二)——编译和运行原理(1)

    接着上一篇的内容,继续从全局了解Android.在清楚了Android的平台架构(可以看作是静态原理)后,还需要掌握其动态原理.动态原理包含两部分,一部分是编译原理,另一部分是运行原理.有人会说,搭建 ...

  3. Android开发学习笔记(10):NDK安装手顺及应用

    网上看了很多人这方面的帖子,基本都是基于r3以前的版本,因为Android NDK r4是近期发布,其中有些改变,所以将此安装过程重新梳理. 安装环境Windows 7 64bit (之前在Ubunt ...

  4. Android开发实践:如何设置NDK的编译选项

    1. 概述 首先回顾一下 Android NDK 开发中,Android.mk 和 Application.mk 各自的职责. Android.mk,负责配置如下内容: (1) 模块名(LOCAL_M ...

  5. Android Adobe Reader 任意代码执行分析(附POC)

    livers · 2014/04/18 14:05 0x00 描述 前几天老外在fd还有exploit-db上,公布了Adobe Reader任意代码执行的漏洞. 漏洞编号: CVE: 2014-05 ...

  6. 构建Android的交叉编译器、用NDK编译移植

    在之前的文章中提到了用arm-none-linux-gnueabi-gcc交叉编译移植程序到Android平台上.也提到了,Android中没有glibc,所以arm-none-linux-gnuea ...

  7. linux之如何在任意目录执行我常用的脚本文件

    1.问题 比如我们在ubuntu上开发Android的时候,经常会用到jadx. pidcat.py ,但是我们希望在任何目录都能执行这些命令, 如果不知道pidcat.py是什么东西的,可以先百度 ...

  8. Android 开发 | App 工程目录结构

    包括两个分类:app 和 Gradle Scripts. app 目录包括: manifests 子目录,只有一个 AndroidManifest.xml 文件,它是 App 的运行配置文件. jav ...

  9. Android开发学习之路-脱壳反编译

    前言 想研究下某app里面的实现技术,使用常规的反编译发现竟然是加固的,所谓Apk加固,就是对dex文件进行加密,防止App被反编译,保证apk的安全.市面上有很多的加固平台,有360加固,腾讯乐固, ...

最新文章

  1. 在java中方法重载的要求,Java方法的重载
  2. 3天初版部署7天快速迭代!百度飞桨携手北京地铁落地AI口罩检测方案
  3. C++ deque底层实现
  4. 【统计学习】概率论与统计学基础
  5. spark环境搭建(idea版本)
  6. 快速制作U盘WIN PE启动盘简易指南
  7. (转载)Android两种Tab分页的方式:TabActivity和ActivityGroup以及Android项目几种常见的应用架构...
  8. 【51单片机快速入门指南】6.3:DS18B20 单总线数字温度计的多路读取
  9. JavaScript中一个对象数组按照另一个数组排序
  10. M1芯片MacBook Pro/Air能兼容哪些软件?M1 mac软件兼容一览表
  11. 帆软按钮控件变查询_如何设置finereport按钮控件的可用时间
  12. oracle函数lad,01-查询Oracle中所有用户信息
  13. java中删除特定后缀名文件
  14. 【Spark-core学习之六】 Spark资源调度和任务调度
  15. WinAPI: waveInGetPosition - 获取当前输入设备的输入位置
  16. disp语句怎么格式 matlab_matlab输出语句print
  17. 最强MySQL笔记(超详细版)(一)
  18. Thoughtworks
  19. Oracle GL - 使用标准程序获取/创建CCID
  20. 自然语言推断(NLI)、文本相似度相关开源项目推荐(Pytorch 实现)

热门文章

  1. 关于登录记住密码使用cookie的详解
  2. Android Intent的几种用法全面总结
  3. 多线程并发编程需要注意虚假唤醒Spurious wakeup
  4. 动态执行流程分析和性能瓶颈分析的利器——gperftools的Cpu Profiler
  5. 堆状态分析的利器——gperftools的Heap Profiler
  6. 概率论中高斯分布(正态分布)介绍及C++11中std::normal_distribution的使用
  7. 通过transpose和flip实现图像旋转90/180/270度
  8. 利用OpenCV求取图像的重心
  9. 鸿蒙系统首批更新机器,鸿蒙系统升级名单
  10. wpf 窗口的返回值_如何:获取页函数的返回值