当前位置: 首页 > 编程日记 > 正文

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

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

文以简单的例子讲述如何在任意目录把自己写的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

相关文章:

SurfaceView 间取得焦点

在SurfaceView中我们的onKeyDown虽然重写了view的函数&#xff0c; 但一定需要我们在初始化的时候去声明焦点 //添加这个来取得按健事件this.setFocusable(true);this.setFocusableInTouchMode(true);this.requestFocus();如果这些方法&#xff0c;会造成按键无效&#xff0c;提…

Oracle字符串转BooIean,利用Java的多线程技术实现数据库的访问.pdf

利用Java的多线程技术实现数据库的访问.pdf第 卷第 期 计算机应用22 12 Voi .22 , No . 12年 月2002 12 Computer Appiications Dec . , 2002文章编号&#xff1a; ( )1001 - 9081 2002 12 - 0121 - 03利用Java 的多线程技术实现数据库的访问刘 巍&#xff0c;唐学兵(武汉大学 …

Linux音频设备驱动

在Linux中&#xff0c;先后出现了音频设备的两种框架OSS和ALSA&#xff0c;本节将在介绍数字音频设备及音频设备硬件接口的基础上&#xff0c;展现OSS和ALSA驱动的结构。17.1&#xff5e;17.2节讲解了音频设备及PCM、IIS和AC97硬件接口。17.3节阐述了Linux OSS音频设备驱动的组…

japid-controller自动绑定的数据类型

参考文献&#xff1a;http://www.playframework.org/documentation/1.2.3/controllers 当参数名和HTTP请求中的参数名&#xff08;即界面中的name&#xff09;相同时&#xff0c;后台Controller可以直接获取该变量的值。变量分两大类&#xff1a; 1. Simple types 所有的基本数…

NAT,Easy IP

R3配置 [V200R003C00] #snmp-agent local-engineid 800007DB03000000000000snmp-agent #clock timezone Indian Standard Time minus 05:13:20clock daylight-saving-time Day Light Saving Time repeating 12:32 9-1 12:32 11-23 00:00 2005 2005 #drop illegal-mac alarm #…

linux用户在哪个文件夹,LINUX中用命令成功建立一个用户后信息会记录在哪个文件中...

LINUX中用命令成功建立一个用户后信息会记录在哪个文件中发布时间:2007-07-28 10:14:57来源:红联作者:MPiops增加用户帐号后新建用户的命令十分简单&#xff0c;在命令行下使用 useradd 命令&#xff1a;useradd david该命令做了下面几件事&#xff1a;1)在 /etc/passwd 文件中…

iOS开发—block介绍

- (void)viewDidLoad {[super viewDidLoad];NSLog("我在玩手机");NSLog("手机没电了");[self chargeMyIphone:^{NSLog("出门逛街");}];NSLog("我在看电视"); }-(void)chargeMyIphone:(void(^)(void))finishBlock {double delayInSecon…

Sap Byd Soap使用 SSL 客户端证书

1.修改通讯安排为使用SSL客户端证书2.设置客户端证书上传证书,或者上传并下载证书3.用SoapUI 测试系统选择下载来的证书,或者自己创建的通讯证书,并输入密码配置好后就可以测试系统了4.关于验证失败.byd 系统 有时候,系统生效会比较慢,如果不行,请等待3分钟,还是不行,从头在试下…

IOS开源项目汇总

扫描wifi信息&#xff1a;http://code.google.com/p/uwecaugmentedrealityproject/http://code.google.com/p/iphone-wireless/ 条形码扫描&#xff1a;http://zbar.sourceforge.net/iphone/sdkdoc/install.html tcp/ip的通讯协议&#xff1a;http://code.google.com/p/cocoaas…

linux命令face,linux下配置face_recognition

1、如linux下已有python2.7,但需要更新一下python 2.7至python2.xsudo add-apt-repository ppa:fkrull/deadsnakes-python2.7sudo apt-getupdatesudo apt-get upgrade2、部署步骤安装Boost, Boost.Pythonsudo apt-get install build-essential cmakesudo apt-get install libgt…

微服务系列(五):事件驱动的数据管理

编者的话&#xff5c;本文来自 Nginx 官方博客&#xff0c;是「Chris Richardson 微服务」系列的第五篇文章。第一篇文章介绍了微服务架构模式&#xff0c;并且讨论了使用微服务的优缺点&#xff1b;第二和第三篇描述了微服务架构模块间通讯的不同方面&#xff1b;第四篇研究了…

js基础知识温习:Javascript中如何模拟私有方法

本文涉及的主题虽然很基础&#xff0c;在很多人眼里属于小伎俩&#xff0c;但在JavaScript基础知识中属于一个综合性的话题。这里会涉及到对象属性的封装、原型、构造函数、闭包以及立即执行表达式等知识。 公有方法 公有方法就是能被外部访问并调用的方法。 // 在对象中 var R…

格式化测试数据,组装用于插入表中的sql语句

最近闲的蛋疼&#xff0c;每每在写测试例子的时候&#xff0c;万恶的测试数据需要手工书写insert语句的向表中插入&#xff0c;很费事&#xff0c;于是就像写个脚本来实现自动生成插入语句 测试数据&#xff1a; 100 北京 20120203123 100 天津20120203123 101 湖南20120203nul…

linux内核功能有,好消息!LINUX内核2.6.18终于支持实时功能了

LINUX内核2.6.18终于支持实时功能了,这是个好消息。当LINUX实时功能加强后&#xff0c;它在嵌入式系统的应用就会更广泛了。在这一版发布前&#xff0c;为了使嵌入式系统的LINUX具有实时特性&#xff0c;需要给标准和LINUX系统加上具有实时功能的补丁。实际上&#xff0c;就算是…

Asp.Net 构架(HttpModule 介绍)

Http 请求处理流程 和 Http Handler 介绍 这两篇文章里&#xff0c;我们首先了解了Http请求在服务器端的处理流程&#xff0c;随后我们知道Http请求最终会由实现了IHttpHandler接口的类进行处理(应该记得Page类实现了IHttpHandler)。从 Http 请求处理流程 一文的最后的一幅图中…

.net下WinDbg使用说明

加载调试文件 .loadby sos mscorwks #.Net 3.5版本及以下 .loadby sos clr #.Net 4.0 WinDbg的基本命令 !threads #显示所有线程 !dumpheap #显示托管堆的信息 !dumpheap -stat #统计堆栈内存 !clrstack #显示调用栈 !dumpobj #显示一个对象的内容 !dumparray #显示数组…

【系列】EOS开发3 EOS提供的程序和工具

上一篇文章使用了nodeos命令来启动eos服务&#xff0c;这一篇文章&#xff0c;就来介绍一下eos提供的相关程序和工具。 nodeos EOSIO的核心守护进程&#xff0c;它可通过插件配置来启动一个节点。 cleos 这是一个命令行工具&#xff0c;它跟nodeos开放的REST API接口进行交互。…

Linux qgis 编译,QGIS简介与源代码编译

QGIS(http://qgis.org)是一个集成了很多个开源的空间数据处理库的桌面GIS软件&#xff0c;支持Python脚本。QGIS基于QT和SIP进行开发&#xff0c;支持Windows\Linux\MacOS等操作系统&#xff0c;可以访问MySQL/PostGRE等数据库的空间数据&#xff0c;可以连接到OpenstreetMap拉…

一步步写自己SqlHelper类库(五):Command对象

1.Command对象基础 当我们使用Connection对象里面的方法打开数据库后&#xff0c;要查询自己所需的数据或对数据库的内容进行增删改时&#xff0c;Command对象就派上用场了&#xff01; MSDN定义&#xff1a;建立与数据源的连接后&#xff0c;利用Command对象来执行命令并从数据…

MVC-前台调用后台action 传递upload file 参数问题

在后台获取upload file 数量的时候发现count一直为0&#xff0c;经检查发现了问题 &#xff0c;代码如下&#xff1a; 前台&#xff1a; var data $("#DetailForm").serialize(); $.ajax({ url: Url.Action("SaveRequest", "RegistrationRequest&quo…

Storybook 5.0正式发布:有史以来变化最大的版本\n

Storybook 5.0&#xff08;SB5&#xff09;于近日正式发布&#xff0c;这是目前为止最大的一个版本。新版本的内容包括&#xff1a; 全新的开发者体验&#xff1b;带有主题的组件库&#xff1b;改进的前端插件架构&#xff1b;全新的Storybook网站。 Storybook的进展和未来 Sto…

linux6直连存储挂载磁盘,CentOS7mount网络磁盘的详细步骤

在配置前一定先关闭防火墙systemctl disable firewalldsystemctl stop firewalldsystemctl mask firewalld一.修改iscsi客户端的用户名vi /etc/iscsi/initiatorname.iscsiInitiatorName iqn.************&#xff1b;【注&#xff1a;eg&#xff1a;iqn.2017-09.com.centos:cl…

如何将Java源代码文件的编码从GBK转为UTF-8?

有时候看到有意思的demo&#xff0c;在头痛导入项目的编码和workspace的编码不一样的时候 我试着将 笔记本打开一个类一个类的复制&#xff0c; demo的类比较少的时候 可以忍受&#xff0c;demo的类多的时候 除了靠之外 别无办法 今天再找仿ios样式demo的时候 实在受不了乱码&a…

电子书格式怎么在线转换为PDF格式

电子书格式怎么在线转换为PDF格式&#xff0c;现在很多朋友喜欢用PDF格式的电子书&#xff0c;因为其有纸质书的排版和格局&#xff0c;但实际生活中出现的最多的是TXT等格式的电子书&#xff0c;那如何将其进行转换成PDF格式的呢&#xff0c;下面就由小编来告诉大家转换的解决…

设计模式笔记(18)---迭代器模式(行为型)

Gof定义 提供一种方法顺序访问一个聚合对象中的各个元素&#xff0c; 而又不暴露该对象的内部表示。 动机 在软件构建过程中&#xff0c;集合对象内部结构常常变化各异。但对于这些集合对象&#xff0c;我们希望在不暴露其内部结构的同时&#xff0c;可以让外部客户代码透明地访…

linux卸载mpfr,Red Hat Linux在安装gcc时遇到的问题汇总

找到了一个比较老的RedHatlinux&#xff0c;想要装上apachetomcat。由于是在虚拟机中运行&#xff0c;我想先装一个vmware-tools提高性能。但是安装的过程中我发现竟然找不到gcc。于是我就去网上(] http://www.linuxidc.com/Linux/2009-01/18242.htm 与 http://www.linuxidc.co…

【数据结构】某些难理解点

1 typedef char ListData;2 //表示以后可以用ListData来代替char类型3 4 typedef struct node{ //此处node&#xff0c;只在结构体中出现和使用5 ListData data;6 struct node *link;7 }ListNode; //表示将整个结构体命名为ListNode&#xff0c;也就是说…

利用jQuery实现用户名片小动画

我爱撸码&#xff0c;撸码使我感到快乐&#xff01;大家好&#xff0c;我是Counter。下面给大家介绍利用jQuery实现的小动画&#xff0c;非常的简便&#xff0c;如果有原生js操作的话&#xff0c;那么就不止这么多行了。至于CSS&#xff0c;个人觉得&#xff0c;这边CSS布局也蛮…

Linux二进制导出配置文件,Go打包二进制文件的实现

背景众所周知&#xff0c;go语言可打包成目标平台二进制文件是其一大优势&#xff0c;如此go项目在服务器不需要配置go环境和依赖就可跑起来。操作需求&#xff1a;打包部署到centos7笔者打包环境&#xff1a;mac os方法&#xff1a;进入main.go所在目录&#xff0c;输入如下命…

crud springmvc

实体类&#xff1a;Student.java Java代码 package demo.entity; public class Student { private int id; private String name; private String sex; private String address; public int getId() { r…