windows环境下(X86架构)实现Android(ARM架构)交叉编译, 以及端侧平台调试运行

在这里插入图片描述

背景介绍

  • 什么是交叉编译(Cross_Compile)?

所谓"交叉编译",是指编译源代码的开发编译平台和执行源代码编译后程序的目标运行平台是两个不同的平台。

  • 为什么要使用交叉编译呢?

1、目的平台上无法实现本地编译(native compile),主要因为目的平台上的资源贫乏(内存小、无显示设备等);

2、有能力实现源代码编译的平台CPU架构或操作系统与目标平台不同。


干货分享:欢迎收藏点赞加关注


windows环境交叉编译

一、MinGW和NDK工具安装和环境配置

讲MinGW和NDK之前,我们先要了解一下如何在linux环境下实现Android平台交叉编译的工具。

linux环境下编译Android平台可执行程序/算法库需要用到gcc编译器NDK工具。Linux一般自带gcc编译器,不需要额外再下载安装,可以通过gcc –v查看其版本号。NDK (原生开发套件) 是一套工具,使您能够在 Android 应用中使用 C 和 C++ 代码。

下载地址:最新版本android-ndk-r23b-linux.zip


OK,那在windows环境下,需要用到MinGWNDK工具。

MinGW(Minimalist GNU for Windows)提供了一套简单的再windows环境下基于gcc的开发环境。是将gcc编译器和GNU Binutils移植到windows平台下的产物,包括一系列头文件、库和可执行文件。在windows平台模拟了linux平台gcc的开发环境。

下载地址:

NDK工具实现的功能相同:在 Android 应用中使用 C 和 C++ 代码。

下载地址:最新版本android-ndk-r23b-windows.zip

MinGW和NDK工具安装好之后,需要在系统环境变量中添加PATH :

C:\…\MinGW\bin

C:\…\ndk\android-ndk-r23b

二、编译过程

交叉编译可以选择通过 ndk-build(Android.mk /Application.mk)的方式或者CMake(CMakeLists.txt)的方式。本文重点讲述一下ndk-build方式,CMake是Android Studio 编译原生库的默认构建工具,参考:

1.Android.mk 和Application.mk脚本配置

在刚才安装的NDK目录 C:\…\ndk\android-ndk-r23b\ 下创建一个jni文件夹。并将C/C++代码复制到该路径下,并在该路径下创建Android.mk 和Application.mk文件。

展示一个样例:

Android.mk:

LOCAL_PATH := $(call my-dir)  # 指定了当前.mk文件的路径
include $(CLEAR_VARS)  # 清空了除了LOCAL_PATH之外的所有LOCAL_xxx变量的值

LOCAL_MODULE_CLASS := STATIC_LIBRARIES # 将用于决定编译时的中间文件存放的位置
LOCAL_MODULE := libtest # 编译生成的目标名
LOCAL_MODULE_TAGS := optional # 该模块在所有版本下都编译

判断目标CPU架构名,如果为arm,则添加配置块,与CPU架构版本无关

ifeq ($(TARGET_ARCH), arm)
LOCAL_ARM_MODE := thumb
LOCAL_CFLAGS += -mthumb
endif

判断当前的cpu/abi的类型,取值包括:

32位:armeabi、armeabi-v7a、x86、mips 64位:arm64-v8a、x86_64、mips64

ifeq ($(TARGET_ARCH_ABI), $(filter arm64-v8a armeabi-v7a, $(TARGET_ARCH_ABI)))
LOCAL_CFLAGS += -D__ARCH_ARM__
endif

判断abi类型

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_CFLAGS += -D__ARMV7__
LOCAL_ARM_MODE := arm
else
LOCAL_ARM_MODE := arm
endif

头文件

INCLUDE_PATH := $(LOCAL_PATH)/src
LOCAL_C_INCLUDES := \ # 额外的C/C++编译头文件路径,用LOCAL_PATH表示本文件所在目录
$(INCLUDE_PATH)/A/
$(INCLUDE_PATH)/B/ \

源文件 wildcard 一句话引入单个目录(不包括子目录)下的所有c/cpp源文件

SRC_PATH := $(LOCAL_PATH)/src
MY_CPP_LIST := $(wildcard $(LOCAL_PATH)/main.c)
MY_CPP_LIST += $(wildcard $(SRC_PATH)/A/.c) #追加到变量MY_CPP_LIST 里
MY_CPP_LIST += $(wildcard $(SRC_PATH)/A/
.cpp)
MY_CPP_LIST += $(wildcard $(SRC_PATH)/B/.c)
MY_CPP_LIST += $(wildcard $(SRC_PATH)/B/
.cpp)

LOCAL_SRC_FILES := ( M Y C P P L I S T : (MY_CPP_LIST: (MYCPPLIST:(LOCAL_PATH)/%=%) # 编译该模块需要的源文件

( M Y C P P L I S T : (MY_CPP_LIST: (MYCPPLIST:(LOCAL_PATH)/%=%)语法的意思是对MY_CPP_LIST中每一项,应用冒号后面的规则,规则是 ( L O C A L P A T H ) / (LOCAL_PATH)/%=%,意思是查找所有 (LOCALPATH)/(LOCAL_PATH)/开头的项,并截取后面部分

LOCAL_CFLAGS += -DHAVE_CONFIG_H -D__ARM_NEON -DNR_NEON # 宏定义 -DXXX
LOCAL_CFLAGS += -mfloat-abi=softfp -mfpu=neon # 使能neon指令集

LOCAL_CFLAGS += -fPIE -fPIC # 兼容 5.0+
LOCAL_LDFLAGS += -fPIE -pie

LOCAL_CPPFLAGS := -std=c++11 # 支持 c++ 11标准 需要在Application.mk中加入:APP_STL := gnustl_static
#LOCAL_CPPFLAGS += -std=c++1y # 支持 c++ 14标准

include $(BUILD_EXECUTABLE) # 编译可执行文件
#include $(BUILD_STATIC_LIBRARY) # 表示编译成静态库
#include KaTeX parse error: Expected 'EOF', got '#' at position 24: …HARED_LIBRARY) #̲ 表示编译成动态库</code…->#

1、 将可执行程序 push到手机中

adb push <电脑上的文件路径> <设备里的路径>

2、adb shell 进入手机,并cd 到可执行程序的路径下

3、chmod 777 <可执行程序名称>

4、./<可执行程序名称> 运行

5、查看输出结果是否符合预期。


应用场景:

例如:neon优化之后,需要在arm平台进行单元测试/模块测试一致性验证等。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值