本文目录
1、NDK编译C/C++ Native代码的通用方法
android编译目录关系如下:
jni/Android_lib.mk
jni/Android_app.mk
jni/common.mk
jni/Application.mk
libs:编译后自动创建,存放各个架构平台stripped的可执行文件和库
obj:编译后自动创建,存放各个架构平台not stripped的目标文件、可执行文件和库。
out:自己创建的目录,存放各个架构平台的动静态库和可执行文件。
build_android.py、build_android.sh:编译脚本 参考: Android平台通用编译环境
通用模块编译可以通过编写Android_lib.mk,Android_app.mk和common.mk以及Application.mk文件采用ndk-build进行编译。
模板如下:
1.1 common.mk:
设置源文件目录以及头文件目录:配置LOCAL_C_INCLUDES和LOCAL_SRC_FILES。
##主要指定源文件路径和头文件路径
SRC_DIR := ../../../src
##头文件路径
LOCAL_C_INCLUDES := ./ \
$(DIR_SRC) \
$(DIR_SRC)/../include \
$(DIR_SRC)/$(INCLUDEASM)
##纯C文件路径
C_SRCS := $(DIR_SRC)/test1.c \
$(DIR_SRC)/test2.c \
$(DIR_SRC)/test3.c \
$(DIR_SRC)/test4.c \
$(DIR_SRC)/test5.c
##汇编文件路径
A_SRCS :=
ifeq($(PURE_C),0)
#x86架构
ifeq($(findstring x86, $(TARGET_ARCH_ABI)), x86)
IFLAGS += -I$(SRC_DIR)/x86
A_SRCS += $(DIR_SRC)/x86/test1.asm \
$(DIR_SRC)/x86/test2.asm
endif
#arm架构
ifeq($(findstring armeabi, $(TARGET_ARCH_ABI)), armeabi)
IFLAGS += -I$(SRC_DIR)/arm
A_SRCS += $(DIR_SRC)/arm/test1.asm \
$(DIR_SRC)/arm/test2.asm
endif
endif
##设置汇编文件
LOCAL_SRC_FILES := $(C_SRCS) $(A_SRCS)
1.2 Android_lib.mk:
Android.mk 文件位于项目 jni/ 目录的子目录中,用于向构建系统描述源文件和共享库。 它实际上是构建系统解析一次或多次的微小 GNU makefile 片段。 Android.mk 文件用于定义 Application.mk、构建系统和环境变量所未定义的项目范围设置。
设置编译参数、特定平台编译参数、编译动静态库配置:配置LOCAL_PATH,LOCAL_MODULE,LOCAL_CFLAGS,LOCAL_CPPFLAGS。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libxxx
##参数初始化
DEBUG ?= 0
SHARED ?= 1
INCLUDEASM :=
#设置汇编优化使能
ifeq ($(PURE_C),1)
OPTIM := 1
else
OPTIM := 0
endif
#设置GDB调试使能
ifeq ($(DEBUG),1)
GDBEN := -g
else
GDBEN := -O3
endif
#设置公用编译参数
CFLAGS := -Wall
CFLAGS += -fPIC
CFLAGS += -std=c99
CFLAGS += $(GDBEN)
#特定架构编译参数
ifeq($(TARGET_ARCH_ABI),arm64-v8a)
INCLUDEASM = aarch64
CFLAGS += -march=armv8-a
CFLAGS += -D_REENTRANT
CFLAGS += 架构相关优化宏
endif
ifeq($(TARGET_ARCH_ABI),armeabi-v7a)
INCLUDEASM = arm
CFLAGS += -march=armv7-a -mfpu=neon -marm
CFLAGS += -D_REENTRANT
CFLAGS += 架构相关优化宏
endif
ifeq($(TARGET_ARCH_ABI),x86_64)
INCLUDEASM = x86
CFLAGS += -march=x86-64 -m64 -msse -msse2 -msse3 -msse4.1
CFLAGS += -D_REENTRANT
CFLAGS += 架构相关优化宏
endif
ifeq($(TARGET_ARCH_ABI),x86)
INCLUDEASM = x86
CFLAGS += -march=i686 -m32 -msse -msse2 -msse3 -msse4.1
CFLAGS += -D_REENTRANT
CFLAGS += 架构相关优化宏
endif
#设置编译参数
LOCAL_CFLAGS := $(CFLAGS)
LOCAL_CPPFLAGS := $(CFLAGS)
#include $(LOCAL_PATH)/common.mk
#配置编译静态库、动态库
ifeq ($(SHARED),1)
include $(BUILD_SHARED_LIBRARY)
else
include $(BUILD_STATIC_LIBRARY)
endif
1.3 Android_app.mk:
设置编译参数、特定平台编译参数、编译可执行文件配置:配置LOCAL_PATH,LOCAL_MODULE,LOCAL_CFLAGS,LOCAL_CPPFLAGS。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libxxx
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../demo/ \
$(LOCAL_PATH)/../../../include/
#设置公用编译参数
CFLAGS := -Wall
CFLAGS += -fPIC
CFLAGS += -std=c99
CFLAGS += $(GDBEN)
#特定架构编译参数
ifeq($(TARGET_ARCH_ABI),arm64-v8a)
INCLUDEASM = aarch64
CFLAGS += -march=armv8-a
endif
ifeq($(TARGET_ARCH_ABI),armeabi-v7a)
INCLUDEASM = arm
CFLAGS += -march=armv7-a -mfpu=neon -marm
endif
ifeq($(TARGET_ARCH_ABI),x86_64)
INCLUDEASM = x86
CFLAGS += -march=x86-64 -m64 -msse -msse2 -msse3 -msse4.1
endif
ifeq($(TARGET_ARCH_ABI),x86)
INCLUDEASM = x86
CFLAGS += -march=i686 -m32 -msse -msse2 -msse3 -msse4.1
endif
#设置编译参数
LOCAL_CFLAGS := $(CFLAGS)
LOCAL_CPPFLAGS := $(CFLAGS)
LOCAL_LDFLAGS := $(LOCAL_PATH)/../out/$(TARGET_ARCH_ABI)/libxxx.a
LOCAL_STATIC_LIBRARIES := $(LOCAL_PATH)/../out/$(TARGET_ARCH_ABI)/libxxx.a
#设置demo源文件
SRC_DIR =$(LOCAL_PATH)/../../../demo
DEMO_SRCS := $(SRC_DIR)/demo.c
LOCAL_SRC_FILES := $(DEMO_SRCS)
include $(BUILD_EXECUTABLE)
1.4 Application.mk:
设置APP_ABI,APP_PLATFORM和NDK_TOOLCHAIN_VERSION等。
APP_ABI := x86 x86_64 armeabi armeabi-v7a arm64-v8a
APP_PLATFORM := android-9
NDK_TOOLCHAIN_VERSION := 4.9
系统宏用法:
APP_ABI
默认情况下,NDK 构建系统为 armeabi ABI 生成机器代码。 此机器代码对应于基于 ARMv5TE、采用软件浮点运算的 CPU。 您可以使用 APP_ABI 选择不同的 ABI。
APP_PLATFORM
此变量包含目标 Android 平台的名称。
APP_BUILD_SCRIPT
默认情况下,NDK 构建系统在 jni/ 下查找名称为 Android.mk 的文件。
如果要改写此行为,可以定义 APP_BUILD_SCRIPT 指向替代构建脚本。 构建系统始终将非绝对路径解释为 NDK 顶级目录的相对路径。
NDK_TOOLCHAIN_VERSION
将此变量定义为 4.9 或 4.8 以选择 GCC 编译器的版本。 64 位 ABI 默认使用版本 4.9 ,32 位 ABI 默认使用版本 4.8。要选择 Clang 的版本,请将此变量定义为 clang3.4、clang3.5 或 clang。 指定 clang 会选择 Clang 的最新版本
关于系统变量、宏和函数宏的用法更多可参考:
https://developer.android.google.cn/ndk/guides/android_mk
https://developer.android.google.cn/ndk/guides/application_mk
THE END!
本博文只能阅读,谢绝转载,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2963033731@qq.com