(NDK编译)详解使用Android.mk编译的C/C++程序过程

2023-09-20 13:25:01

想要在Android设备上运行C/C++程序可执行文件,可采用一个方法就是使用NDK编译,很多时候要比gcc编译更适合,这里我采用的是imx6q开发板上面装载了自己编写的Android6.0.1镜像,在Ubuntu64位系统上采用NDK编译。

目录

1.准备文件

2.编写Android.mk

注意

完整Android.mk代码

3.NDK编译

4.运行可执行文件


1.准备文件

首先在新建的一个文件夹中,放置自己编写的两个文件,一个是C语言程序,一个是Android.mk,C语言程序内容可以由自己决定,符合标准即可。也可以是最简单的打印hello,world

2.编写Android.mk

对于Android.mk文件的编写,需要先了解其中一些必要的设置,这里我先放出我的Android.mk 

文件内容很简短,来详细解释一下,

LOCAL_PATH := $(call my-dir)

首先必须定义好LOCAL_PATH变量,用于在开发树中查找源文件。宏函数my-dir由编译系统提供,用于返回当前路径(即包含Android.mk文件的目录)。

include $(CLEAR_VARS)

这是必要的语句,CLEAR_VARS由编译系统提供,用于清除许多LOCAL_XXX变量,如: LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES...

LOCAL_MODULE := test_app

编译的目标对象,LOCAL_MODULE变量必须定义,以标识在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。编译系统会自动产生合适的前缀和后缀,一个被命名为'sum'的共享库模块,将会生成'libsum.so'文件。

LOCAL_SRC_FILES := test_app.c

LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。我们不需要在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件,仅仅列出直接传递给编译器的源代码文件就好。

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY表示编译生成共享库,是编译系统提供的变量,指向一个GNU Makefile脚本,负责收集自从上次调用'include $(CLEAR_VARS)'以来,定义在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做

注意

可以看到我的Android.mk文件当中还有两行

LOCAL_CFLAGS += -pie -fPIE 
LOCAL_LDFLAGS += -pie -fPIE

在起初我没有添加这两行代码时,也可使用NDK成功编译出可执行文件,但放在Android系统的开发板上时无法运行并报错:only position independent executables (PIE) are supported

我通过参考error: only position independent executables (PIE) are supported 了解了这个问题以及解决办法,大体上就是从Android4.1引入了PIE这个安全机制,解决办法就是加入上述的两条语句在Android.mk文件中即可

完整Android.mk代码

给出完整的Android.mk代码,由于我的C文件叫做test_app.c,所以想要直接使用需要把下面代码中test_app换为自己电脑上C程序文件的名称即可。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)


LOCAL_SRC_FILES := test_app.c
LOCAL_MODULE := test_app

LOCAL_CFLAGS += -pie -fPIE 
LOCAL_LDFLAGS += -pie -fPIE

include $(BUILD_EXECUTABLE)

#APP_ALLOW_MISSING_DEPS=true

#APP_PLATFORM        := android-14
APP_ABI             := armeabi-v7a x86 x86_64 arm64-v8a

3.NDK编译

完成上述步骤后,在当前文件夹下打开终端,输入ndk-build的命令进行编译

/home/yinlong/Music/sdkapp/android-ndk-r14b-linux-x86_64/android-ndk-r14b/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk

成功编译后,在当前目录下出现了两个新的文件夹,生成的可执行程序都放在libs目录下

 libs目录下可以看到有多个版本,适合我的imx6q开发板的是armeabi-v7a下的程序

打开后可以看到编译好的test_app

4.运行可执行文件

把上面的文件放到Android设备中,也就是放入我的开发板中运行下面命令设置文件的读写权限,注意是要在有root权限的情况下

chmod 777 test_app

接着就可以运行NDK编译的可执行文件了 

./test_app

更多推荐

Linux之Shell基础入门

文章目录什么是shellshell入门案例什么是shell什么是shell?Shell(外壳)是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。什么是脚本?脚本简单地说

WebGL透视投影

目录透视投影透视投影可视空间可视空间构造效果图Matrix4.setPerspective()三角形与可视化空间的相对位置示例代码代码详解示例效果投影矩阵的作用透视投影矩阵对物体进行了两次变换透视投影变换示意图透视投影在透视投影下,产生的三维场景看上去更是有深度感,更加自然,因为我们平时观察真实世界用的也是透视投影。在

Java高级-反射

反射1.介绍2.获取Class对象的三种方法3.获取类的构造器4.获取类的成员变量5.获取类的成员方法6.反射的作用和应用场景1.介绍反射加载类,并允许以编程的方式解剖类的各种成分(成员变量、方法、构造器等)反射步骤1.加载类,获取类的字节码:Class对象2.获取类的构造器:Constructor对象3.获取类的成员

JS 继承

JS继承的方式一、继承是什么?二、继承实现的方式2.1原型链继承2.2原型式继承2.3构造函数继承2.4组合继承2.5寄生式继承2.6寄生组合式继承2.7extends方法一、继承是什么?继承(inheritance)是面向对象软件技术当中的一个概念。如果一个类别B“继承自”另一个类别A,就把这个B称为“A的子类”,而

软件工程 第一次随堂练习

以下答案是经过人工智能生成,个人理解得出的答案,若有不同见解,请在评论区留言或私信说明下列需求分别属于下面的哪种类型,为什么?A.业务需求B.用户需求C.系统级(功能)需求D.性能需求E.质量需求F.约束G.对外接口H.数据需求I.过程需求J.项目需求K.其他需求(硬件需求、人力需求等)1.经过10天培训的收银员能熟练

页面静态化、Freemarker入门

页面静态化介绍页面的访问量比较大时,就会对数据库造成了很大的访问压力,并且数据库中的数据变化频率并不高。那需要通过什么方法为数据库减压并提高系统运行性能呢?答案就是页面静态化。页面静态化其实就是将原来的动态网页(例如通过ajax请求动态获取数据库中的数据并展示的网页)改为通过静态化技术生成的静态网页,这样用户在访问网页

《IP编址与路由:网络层的关键技术》

前言:在TCP/IP协议栈中,网络层位于第三层,起到了承上启下的关键作用。它不仅负责处理来自数据链路层和传输层的请求,还需确保数据包的正确转发。本文将深入探讨IP编址与路由的相关知识,帮助您更好地理解网络层的重要性和应用。目录IP地址分类:ARP/RARP协议原理:路由器工作原理:IP地址分类:IPv4和IPv6是两种

Vue基础语法【下】

目录一、事件处理器1.事件修饰符.stop.prevent.capture.self.once2.按键修饰符.enter.tab.delete.esc.space.up.down.left.right.ctrl、.alt、.shift、.meta二、表单赋值与取值三、自定义组件1.组件介绍2.局部组件3.全局组件4.组

智慧公厕:改变公共厕所管理与运营的未来

在现代社会中,公共厕所是城市建设的重要组成部分。然而,长期以来,公共厕所管理与运营一直是一个令人头疼的问题。由于各种原因,公共厕所常常陷入管理难、环境差、设备设施陈旧的状态,给人们的生活带来困扰。然而,智慧公厕出现正在改变这一局面。通过更透切的感知、更全面的互连和更深入的智能,智慧公厕为城市的公共厕所管理与运营带来了前

FPGA设计时序约束一、主时钟与生成时钟

​目录一、主时钟create_clock1.1定义1.2约束设置格式1.3Addthisclocktotheexistingclock1.4示例1.5差分信号二、生成时钟generate_clock2.1定义2.2格式2.2.1byclockfrequency2.2.2byclockedges2.2.3示例2.2.4自

python学习之【文件读写】

前言上一篇文章​​python学习——【第十四弹】​​​中学习了python中的包与内置模块,这篇文章接着学习python中的文件读写。编码方式在学习文件读写之前,我们先了解下python当中的编码方式:字节(Byte)是计量单位,表示数据量多少,是计算机信息技术用于计量存储容量的一种计量单位,通常情况下一字节等于八位

热文推荐