Android.mk中配置so库

本文详细介绍了在Android开发环境中如何判断SO库文件的位数,并提供了将SO库打包到APK的具体步骤。通过在Android.mk文件中配置,可以实现SO库的正确引用和编译,适用于32位和64位的不同需求。
AI助手已提取文章相关产品:

Android.mk中配置so库

在系统源码开发环境下,往往需要单编某个模块来debug,会涉及到打包so的问题。

第三方so库打包到apk

1、如何判断so库文件是32 bit/64 bit?

2、 如何将so库打包到apk ?

如何判断第三方库文件是32 bit/64 bit?

需要使用Linux 命令: file xxx.so。可以看到的xxx.so的格式

如何将so库打包到apk ?

需要将so放在apk目录下(一般新建lib/lib64文件),或者放在系统源码目录的某个文件下。
然后采用prebuilt 的方式,在当前so 所在目录下写 Android.mk文件

   LOCAL_PATH := $(call my-dir)
   include $(CLEAR_VARS)
   LOCAL_MODULE := 此so 库名(不加so后缀)
   LOCAL_SRC_FILES_32 := xxx.so (表示是32 bit 的so)
   LOCAL_SRC_FILES_64 := xxx.so (表示是64 bit的so)
   LOCAL_MULTILIB := 32/64/BOTH(只编译32bit/64bit/both)
   LOCAL_MODULE_CLASS := SHARED_LIBRARIES
   LOCAL_MODULE_SUFFIX := .so
   include $(BUILD_PREBUILT)

然后此so 就可以被直接在apk 的Android.mk 使用,例如:
在alps\packages\apps\Tester 添加一个apk, Android.mk写法

     LOCAL_PATH := $(call my-dir)
     include $(CLEAR_VARS)
     LOCAL_MODULE_TAGS := tests
     LOCAL_SRC_FILES := $(call all-java-files-under, src)
     #需要引用的静态库
     LOCAL_STATIC_JAVA_LIBRARIES := \jxl \AChartEngine_fat
     LOCAL_PACKAGE_NAME :=Tester
     LOCAL_CERTIFICATE := platform
     LOCAL_PROGUARD_FLAG_FILES := proguard.flags
     LOCAL_DEX_PREOPT := false
     LOCAL_PROGUARD_ENABLED := disabled
     # 对前面prebuilt 的动态库的引用
     LOCAL_JNI_SHARED_LIBRARIES +=xxx
     # 此apk 限制为32 bit
     LOCAL_MULTILIB := 32
     include $(BUILD_PACKAGE)

此apk 引用的静态库(位置:alps\packages\apps\Tester\libs\jxl.jar 与AChartEngine_fat.jar)

对于静态库采用prebuilt 的编译方式,LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES是关键。

     include $(CLEAR_VARS)
     LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=jxl: libs/jxl.jar \
                                       AChartEngine_fat:  libs/AChartEngine_fat.jar \
     LOCAL_MODULE_TAGS := optional
     include $(BUILD_MULTI_PREBUILT)
     # Use the following include to make our test apk.
     include $(call all-makefiles-under,$(LOCAL_PATH))

您可能感兴趣的与本文相关内容

<think> 我们正在讨论Android.mk文件加载so的方法。根据引用[1]和引用[3],Android.mk文件是用来编译生成so文件的,同时也可以配置so文件打包到apk中。引用[2]提到了如何加载第三方的so。现在,用户想知道在Android.mk文件中如何加载so(可能是预编译的so)。 在Android.mk中加载so(即预编译的)通常有两种情况: 1. 将预编译的so打包到apk中(在libs目录下)。 2. 在编译另一个so时,链接这个预编译的so。 我们分别来看: 一、将预编译的so打包到apk中 在Android.mk中,我们可以使用`LOCAL_PREBUILT_LIBS`或者`LOCAL_JNI_SHARED_LIBRARIES`来指定预编译的so,然后将其打包到apk的libs目录下。 例如: ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := my_prebuilt_lib LOCAL_SRC_FILES := libs/armeabi/libprebuilt.so include $(PREBUILT_SHARED_LIBRARY) ``` 然后在你的应用模块中,通过`LOCAL_JNI_SHARED_LIBRARIES`来引用这个预编译模块: ```makefile include $(CLEAR_VARS) LOCAL_MODULE := my_module ... # 其他设置 LOCAL_JNI_SHARED_LIBRARIES := my_prebuilt_lib include $(BUILD_PACKAGE) ``` 二、在编译另一个so时链接预编译的so 如果我们正在编译一个so(例如叫`libnative.so`),它需要链接一个预编译的so(例如`libprebuilt.so`),则需要在编译模块中通过`LOCAL_SHARED_LIBRARIES`来指定。 例如: ```makefile include $(CLEAR_VARS) LOCAL_MODULE := native LOCAL_SRC_FILES := native.c LOCAL_SHARED_LIBRARIES := prebuilt # 这里prebuilt是上面预编译模块的LOCAL_MODULE include $(BUILD_SHARED_LIBRARY) ``` 注意:预编译模块必须先定义,然后才能在后面的模块中引用。 另外,关于引用[1]中提到的,可以通过`APP_ABI`来指定生成哪些平台的so,同样在预编译的情况下,我们也需要为不同的ABI提供对应的so文件,并在Android.mk中正确指定路径。 例如,对于多ABI的支持,我们可以将不同ABI的so文件放在不同的目录下,然后在Android.mk中根据`TARGET_ARCH_ABI`来指定: ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := prebuilt ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) LOCAL_SRC_FILES := libs/armeabi-v7a/libprebuilt.so else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) LOCAL_SRC_FILES := libs/arm64-v8a/libprebuilt.so else ifeq ($(TARGET_ARCH_ABI),x86) LOCAL_SRC_FILES := libs/x86/libprebuilt.so endif include $(PREBUILT_SHARED_LIBRARY) ``` 这样,在编译时会根据目标ABI选择对应的预编译。 总结: 1. 打包预编译so到apk:使用`PREBUILT_SHARED_LIBRARY`模块,然后在应用模块中通过`LOCAL_JNI_SHARED_LIBRARIES`引用。 2. 编译时链接预编译so:在编译so的模块中,使用`LOCAL_SHARED_LIBRARIES`引用预编译模块(该预编译模块已经通过`PREBUILT_SHARED_LIBRARY`定义)。 下面我们来写回答。 </think> ### Android.mk文件加载SO方法详解 在Android NDK开发中,Android.mk文件是管理原生代码的核心配置文件。加载SO主要涉及两种场景:编译生成SO和集成预编译SO。 #### 🔧 一、编译生成SO(源码编译) ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # 基础配置 LOCAL_MODULE := my_module # 生成的SO名(libmy_module.so) LOCAL_SRC_FILES := src1.cpp \ src2.cpp # 源码文件列表 # 配置编译标志 LOCAL_CFLAGS := -DDEBUG -O2 # 编译参数 LOCAL_LDLIBS := -llog -lz # 链接系统 # 多ABI支持(引用[1]) APP_ABI := armeabi-v7a arm64-v8a x86 include $(BUILD_SHARED_LIBRARY) # 生成动态 ``` 关键参数说明: - `LOCAL_MODULE`:定义生成的SO名称,格式为`lib<name>.so` - `BUILD_SHARED_LIBRARY`:指定生成动态链接 - `APP_ABI`:控制生成的ABI架构(引用[1]) - 数学关系:$$ \text{输出文件} = \text{lib} \oplus \text{LOCAL\_MODULE} \oplus \text{.so} $$ #### 📦 二、集成预编译SO(第三方) ```makefile include $(CLEAR_VARS) # 预编译配置 LOCAL_MODULE := prebuilt_lib LOCAL_SRC_FILES := prebuilt/libs/$(TARGET_ARCH_ABI)/libthird.so include $(PREBUILT_SHARED_LIBRARY) # 主模块配置 include $(CLEAR_VARS) LOCAL_MODULE := main_module LOCAL_SHARED_LIBRARIES := prebuilt_lib # 链接预编译 include $(BUILD_SHARED_LIBRARY) ``` 关键技巧: 1. **路径规范**: ```makefile # 按ABI组织目录结构 libs/ ├── arm64-v8a/ │ └── libthird.so └── armeabi-v7a/ └── libthird.so ``` 2. **动态链接声明**: - `LOCAL_SHARED_LIBRARIES`:声明运行时依赖 - `LOCAL_STATIC_LIBRARIES`:声明静态链接 3. **调试信息处理**(引用[2]): - 带调试符号的SO:`obj/local/<abi>/lib*.so` - 发布版SO:`libs/<abi>/lib*.so` #### 📦 三、集成到APK打包 ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Java模块配置 LOCAL_PACKAGE_NAME := MyApp LOCAL_SRC_FILES := $(call all-java-files-under, src) # JNI声明(引用[3]) LOCAL_JNI_SHARED_LIBRARIES := my_module prebuilt_lib include $(BUILD_PACKAGE) ``` #### ⚙️ 四、编译指令 ```bash # 清理构建 ndk-build clean # 编译所有ABI版本 ndk-build APP_ABI="all" # 调试模式编译 ndk-build NDK_DEBUG=1 ``` #### 📚 相关问题 1. 如何解决`UnsatisfiedLinkError`错误? 2. Android Studio中如何配置CMake集成SO? 3. 不同ABI版本的SO兼容性如何处理? 4. 如何通过addr2line解析SO崩溃堆栈(引用[2])? 5. JNI中如何正确加载多个依赖的SO? 6. `System.loadLibrary()`和`System.load()`有何区别? > 核心提示:SO加载路径遵循规则:$$ \text{APK安装路径} \mapsto \frac{\text{data}}{\text{data}}/\text{pkg}/{\text{lib}} $$,确保文件名匹配Android.mk中的`LOCAL_MODULE`声明[^1][^3]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值