深入浅出Android NDK之多模块依赖

目录
上一篇 深入浅出Android NDK之Application.mk以及C++支持

之前我们说过,在Android.mk中我们可以指定多个模块。
一个动态库或者可执行文件,可以依赖其他的动态库或者静态库。
在Android.mk中可以通过LOCAL_STATIC_LIBRARIES指定当前模块所依赖的静态库模块,通过指定LOCAL_SHARED_LIBRARIES指定当前模块所依赖的动态库模块。
下面我们看个例子:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := m1
LOCAL_SRC_FILES := m1.cpp
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := m2
LOCAL_SRC_FILES := m2.cpp
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := m3
LOCAL_SRC_FILES := m3.cpp
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := m4
LOCAL_SRC_FILES := m4.cpp
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := m5
LOCAL_SRC_FILES := m5.cpp
LOCAL_STATIC_LIBRARIES := m1 m2
LOCAL_SHARED_LIBRARIES := m3 m4
include $(BUILD_SHARED_LIBRARY)

在这个例子中,共有5个模块,m1,m2是两个静态模块,m3,m4是两个动态模块。
m5通过引用m1,m2,m3,m4。
依赖的意思是,m1,m2,m3,m4中定义的函数或者全局变量,可以在m5中调用。

以上的例子中,m1,m2,m3,m4直接以源码的形式进行编译。若m2,m4没有源码,只有二进制文件libm2.a,libm4.so,又该怎么做呢?请看下面这个例子:

LOCAL_PATH := $(call my-dir)

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

include $(CLEAR_VARS)
LOCAL_MODULE := m2
LOCAL_SRC_FILES := libm2.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := m3
LOCAL_SRC_FILES := m3.c
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := m4
LOCAL_SRC_FILES := libm4.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := m5
LOCAL_SRC_FILES := m5.c
LOCAL_STATIC_LIBRARIES := m1 m2
LOCAL_SHARED_LIBRARIES := m3 m4
include $(BUILD_SHARED_LIBRARY)

我们通过include $(PREBUILT_STATIC_LIBRARY)将libm2.a包装为模块m2,通过include $(PREBUILT_SHARED_LIBRARY)将libm4.so包装为模块m4。m5依然依赖m2,m4,这样就实现了libm5.so对libm2.a和libm4.so的依赖。
但还有个问题,因为我们有armeabi-v7a arm64-v8a x86 x86_64四种架构,所以libm2.a应该有四种架构,每种架构对应一个文件,libm4.so同样也是。
怎么才能实现,当架构为armeabi-v7a的时候,m2的LOCAL_SRC_FILE指向架构为armeabi-v7a的libm2.a,当架构为arm64-v8a的时候,m2的LOCAL_SRC_FILE指向架构为arm64-v8a的libm2.a呢?
为了实现这个需求,我们需要学习一个新的变量:$(TARGET_ARCH_ABI),
TARGET_ARCH_ABI是Android.mk中由系统定义的一个变量,值是当前正在编译的架构的名称。
比如假设在编译armeabi-v7a架构的时候,TARGET_ARCH_ABI的值就是armeabi-v7a,在编译arm64-v8a架构的时候,TARGET_ARCH_ABI的值就是arm64-v8a,在编译x86架构的时候,TARGET_ARCH_ABI的值就是x86,在编译x86_64架构的时候,TARGET_ARCH_ABI的值就是x86_64。

所以我们可以将不同架构的.a和.so根据放在以架构名称命名的目录下。
然后像下面这样引用:

LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libm2.a
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libm4.so

除了TARGET_ARCH_ABI变量外,还有以下变量:
TARGET_ARCH
TARGET_PLATFORM
TARGET_ABI
具体意思可以查看官方文档:
https://developer.android.google.cn/ndk/guides/android_mk#prebuilt_shared_library

对于静态库libm2.a,若libm5.so想要调用libm2.a中的函数,只需要include相应的头文件即可。
但是对于libm4.so,若libm5.so想要调用libm4.so中的函数,则lib4.so必须导出该函数到符号表。导出方法为在声明函数时加上JNIEXPORT关键字,若是C++函数还必须加上extern “C”。
比如:

extern "C" JNIEXPORT void functionA();

下一篇 深入浅出Android NDK之将Android.mk导入Android Studio

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值