Android NDK编译中在libs\armeabi中加入第三方so库文件的方法

假设要加入库文件的名字为libffmpeg.so文件

1.要在project\jni目录下新建一目录prebuilt,把libffmpeg.so文件copy到project\jni\prebuilt中,并在目录project\jni\prebuilt中添加文件Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := ffmpeg

LOCAL_SRC_FILES := libffmpeg.so

include $(PREBUILT_SHARED_LIBRARY)

2.在project\jni目录下的Android.mk文件中加入

LOCAL_SHARED_LIBRARIES := ffmpeg

并在末尾加入

include $(LOCAL_PATH)/prebuilt/Android.mk

一般模板的写法如下:

Android NDK about Library (static library , share library and 3rd party library)

A:Static library

文件Android.mk:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jniLOCAL_SRC_FILES := hello-jni.cinclude $(BUILD_STATIC_LIBRARY)

文件Application.mk:

APP_MODULES :=hello-jni

B: Share library

文件Android.mk:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jniLOCAL_SRC_FILES := hello-jni.cinclude $(BUILD_SHARED_LIBRARY)

C: Static library+Share library

文件Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)LOCAL_MODULE := mylib_staticLOCAL_SRC_FILES := src.cinclude $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)LOCAL_MODULE := mylib_sharedLOCAL_SRC_FILES := src2.c

LOCAL_STATIC_LIBRARIES := mylib_static

include $(BUILD_SHARED_LIBRARY)

D:Using 3rd party library

文件Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)LOCAL_MODULE := thirdlib1 # name it whateverLOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libthird1.a # or $(so_path)/libthird1.so#LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/includeinclude $(PREBUILT_STATIC_LIBRARY) #or PREBUILT_SHARED_LIBRARY

include $(CLEAR_VARS)LOCAL_MODULE := mylib_use_thirdlibLOCAL_SRC_FILES := src.c

LOCAL_STATIC_LIBRARIES := thirdlib1 #or LOCAL_SHARED_LIBRARY

include $(BUILD_SHARED_LIBRARY) #if static lib,need Application.mk(needn't,I have cheked!)

  When I use the static library ,I always got the undefined reference to** error no matter what I do.After a whole tough day,I found that it's not the problem of the mk file,it's the library!Holy Shit!!

  My static library was built in cygwin of windows.Of course it can't be used in Linux!!!!Then I built it with android ndk tool and it runs perfectly!!!

 a. check your library's mode (whether it isARM)

$ file libtest.solibtest.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped

   make sure you library is ARM mode.

b. use nm to view the method of the so file

$ nm libtutorial.so |grep T00001344 a _GLOBAL_OFFSET_TABLE_000002a8 T getinformation000002b4 T getinformation2

To use android ndk tool:http://stackoverflow.com/questions/7403036/compile-library-for-android-ndk

//@Android.mk  //静态库的编写

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_PRELINK_MODULE := false

LOCAL_ARM_MODE := arm

LOCAL_SRC_FILES:= /

aa.c bb.c dd.c /

LOCAL_SHARED_LIBRARIES := /

dd ee ff /

LOCAL_C_INCLUDES += /

$(LOCAL_PATH)/../inc

LOCAL_CFLAGS += -MD /

-FF -Uarm -DMODULE -D__LINUX_ARM_ARCH__=7 /

LOCAL_MODULE:= libMyStaticLib

include $(BUILD_STATIC_LIBRARY)

//静态库生成后的文件是libMyStaticLib.a

//@Android.mk  //动态库的编写

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_PRELINK_MODULE := false

LOCAL_ARM_MODE := arm

LOCAL_SRC_FILES:= /

aa.c bb.c dd.c /

LOCAL_SHARED_LIBRARIES := /

dd ee ff /

LOCAL_C_INCLUDES += /

$(LOCAL_PATH)/../inc

LOCAL_CFLAGS += -MD /

-FF -Uarm -DMODULE -D__LINUX_ARM_ARCH__=7 /

LOCAL_MODULE:= libMyShareLib

include $(BUILD_SHARED_LIBRARY)

//动态库生成后的文件是libMyShareLib.so

实例教程如下:

例1:JNI程序使用libhello-jni.so的符号。

libhello-jni.so由hello-jni.c组成。

hello-jni.c如下:

#include

#include

#include

#define  LOG_TAG    "libhello-jni"

#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

void Java_com_example_hellojni_HelloJni_functionA(JNIEnv* env, jobject thiz)

{

LOGE("SamInfo: Enter Native functionA");

return;

}

Android.mk如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni

LOCAL_SRC_FILES := hello-jni.c

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

../../../ndk-build -B V=1

可以正常编译,再使用Eclipse编译Android工程,可正常运行。

例2:JNI程序使用libhello-jni.so的符号。

libhello-jni.so由hello-jni.c,hell-jniB.c,头文件hello-jni.h组成。

hello-jni.h如下:

#ifndef _HELLO_JNI_H

#define _HELLO_JNI_H

#include

#include

#include

#define  LOG_TAG    "libhello-jni"

#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

#endif

hello-jni.c如下:

#include "hello-jni.h"

void Java_com_example_hellojni_HelloJni_functionA(JNIEnv* env, jobject thiz)

{

LOGE("SamInfo: Enter Native functionA");

return;

}

hell-jniB.c如下:

#include "hello-jni.h"

void Java_com_example_hellojni_HelloJni_functionB(JNIEnv* env, jobject thiz)

{

LOGE("SamInfo: Enter Native functionB");

return;

}

Android.mk如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni

LOCAL_SRC_FILES := hello-jni.c hell-jniB.c

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

注意:LOCAL_SRC_FILES := hello-jni.c hell-jniB.c

此模块hello-jni由两个C文件组成,因为hello-jni.h只是依赖文件,所以不必加入。

又因为hello-jni.h在project/jni目录中,此目录本身为-I,所以也不用再Android.h中指出。

例3:JNI程序使用libhello-jni.so的符号。

libhello-jni.so依赖于libB.a.

libhello-jni.so由hello-jni.c,hell-jniB.c,头文件hello-jni.h组成。

libB.a由libstatic/B1.c,libstatic/B2.c头文件libstatic/B.h组成。

B.h 如下:

#ifndef _B_H

#define _B_H

#include

#include

#include

int iFunctionB1();

int iFunctionB2();

#define  LOG_TAG    "libStatic"

#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

#endif

B1.c:

#include "B.h"

int iFunctionB1()

{

LOGI("SamInfo: Enter static function iFunctionB1()");

return 0;

}

B2.c

#include "B.h"

int iFunctionB2()

{

LOGI("SamInfo: Enter static function iFunctionB2()");

return 0;

}

hello-jni.h:

#ifndef _HELLO_JNI_H

#define _HELLO_JNI_H

#include

#include

#include

#include "libstatic/B.h"

#define  LOG_TAG    "libhello-jni"

#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

#endif

hello-jni.c:

#include "hello-jni.h"

void Java_com_example_hellojni_HelloJni_functionA(JNIEnv* env, jobject thiz)

{

LOGE("SamInfo: Enter Native functionA");

iFunctionB1();

return;

}

hell-jniB.c:

#include "hello-jni.h"

void Java_com_example_hellojni_HelloJni_functionB(JNIEnv* env, jobject thiz)

{

LOGE("SamInfo: Enter Native functionB");

iFunctionB2();

return;

}

Android.mk如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-B

LOCAL_SRC_FILES := libstatic/B1.c libstatic/B2.c

include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni

LOCAL_SRC_FILES := hello-jni.c hell-jniB.c

LOCAL_STATIC_LIBRARIES := hello-B

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

这就是典型的一个Android.mk中包含2个Modules的例子。其中一个是产生静态库,另一个产生动态库。

动态库依赖于静态库。(一定要添加 LOCAL_STATIC_LIBRARIES := hello-B ,否则不生成静态库)

例4:JNI程序使用libA.so(由A1.c,A2,c,A.h组成)

libA.so依赖于libB.so(由B1.c,B2.c,B.h组成)

情况分析:

因为libB.so被libA.so使用。所以肯定要加入:

LOCAL_LDLIBS := -L$(LOCAL_PATH)/../libs/armeabi/   -lhello-B

但请注意:此时libA.so中所用到的libB.so 的符号只是一个空穴。并为将实现加进来。

而如果使用:

LOCAL_SHARED_LIBRARIES := hello-B

也仅仅是将libhello-B.so 添加进编译选项。并未将符号添加进去。

在Linux下,此类情况可以将动态库放置于某个目录下,然后使用export LD_LIBRARY_PATH 来解决。但Android下并无此方法。导致运行时会找不到libhello-B.so中的符号。

针对此类情况,有两种方法,但都不是特别好用。分别描述如下:

方法1.

将libhello-B.so放置于/system/lib下。

且Android.mk如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-B

LOCAL_SRC_FILES := libstatic/B1.c libstatic/B2.c

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni

LOCAL_SRC_FILES := hello-jni.c hell-jniB.c

#LOCAL_SHARED_LIBRARIES := hello-B

LOCAL_LDLIBS := -llog  -L$(LOCAL_PATH)/../libs/armeabi/   -lhello-B

include $(BUILD_SHARED_LIBRARY)

此Android.mk有两个模块,分别产生libhello-B.so, libhello-jni.so. 后者依赖于前者。

 

而因为Java层程序使用:System.loadLibrary("hello-jni");

则libhello-jni.so的符号加入到Java应用程序中。而它使用到的libhello-B.so,则能够在/system/lib下找到。

方法2. 将libhello-B.so也添加如Java程序中。且放置于hello-jni之前。

System.loadLibrary("hello-B");

System.loadLibrary("hello-jni");

方法3:

可以使用dlopen()方式调用。

 据说使用-rpath可以指定应用程序查找库的目录。但Sam觉得理论上并不可能(因为Java无法指定Wl,-rpath).也没有尝试出来。

例5:JNI程序使用libA.so(由A1.c A2.c, A.h组成)

libA.so依赖于libB.so(由B1.c, B2.c, B.h组成)

libB.so依赖于libC.so(由c.c组成)和libD.a(由d.c组成)

libC.so依赖于libD.a (由d.c组成)

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-B

LOCAL_SRC_FILES := libstatic/B1.c libstatic/B2.c

LOCAL_STATIC_LIBRARIES := D

LOCAL_LDLIBS := -llog -lC -L$(LOCAL_PATH)/../libs/armeabi/

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni

LOCAL_SRC_FILES := hello-jni.c hell-jniB.c

#LOCAL_SHARED_LIBRARIES := hello-B

LOCAL_LDLIBS := -llog  -L$(LOCAL_PATH)/../libs/armeabi/   -lhello-B

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := C

LOCAL_SRC_FILES := c.c

LOCAL_LDLIBS := -llog

LOCAL_STATIC_LIBRARIES := D

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := D

LOCAL_SRC_FILES := d.c

LOCAL_LDLIBS := -llog

include $(BUILD_STATIC_LIBRARY)

请注意:如此写法:则libD.a中的符号分别被:libC.so, libB.so两次引用。

例6: JNI程序使用libA.so(由A1.c A2.c, A.h组成)

并引用外部生成的:libE.so, libF.a.

Sam:经常发生这样的情况,某NDK工程A生成一个动态库,供另一个NDK工程B使用。我们常把此动态库放到B工程的lib/armeabi下。 但ndk-build时,它会首先删除lib/armeabi下所有.so文件。

所以可以使用 PREBUILT_SHARED_LIBRARY

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-B

LOCAL_SRC_FILES := libstatic/B1.c libstatic/B2.c

LOCAL_SHARED_LIBRARIES := prelib

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni

LOCAL_SRC_FILES := hello-jni.c hell-jniB.c

#LOCAL_SHARED_LIBRARIES := hello-B

LOCAL_LDLIBS := -llog  -L$(LOCAL_PATH)/../libs/armeabi/   -lhello-B

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := prelib

LOCAL_SRC_FILES := libE.so

include $(PREBUILT_SHARED_LIBRARY)

注意:当 PREBUILT_SHARED_LIBRARY 时,LOCAL_SRC_FILES不再是.c文件,而是动态库。它可以放置在jni下。编译时,它会自动被copy到lib/armaebi下。

请注意模块名。它将被用作LOCAL_SHARED_LIBRARIES

转载于:https://blog.51cto.com/6151207/1622730

Android NDK编译中在libs\armeabi中加入第三方so库文件的方法相关推荐

  1. android中ndk编译错误,Android NDK编译常见错误及解决方案

    Android NDK编译常见错误及解决方案 Error 1:$ ndk-build/cygdrive/c/andy/abc/obj/local/armeabi-v7a/objs/abc//hello ...

  2. android jni不适用ndk,Android NDK编译之undefined reference to 'JNI_CreateJavaVM'

    利用Android NDK编译动态库,在C文件中调用了两个JNI函数:JNI_GetDefaultJavaVMInitArgs和JNI_CreateJavaVM.编译的时候始终报以下错误: XXX: ...

  3. android 编译 sdl,使用android ndk编译SDL2示例错误r14

    我已经测试过在我的ubuntu 16.04机器上构建SDL2源代码(2.0.5)中的示例.使用android ndk编译SDL2示例错误r14 根据https://wiki.libsdl.org/An ...

  4. android.mk ndk编译选项优化,Android NDK 编译脚本分析 之一

    版权信息:本文为本人原创,欢迎转载,但请著明出处,并保留本版权信息. Android NDK编译脚本编写起来还是是比较简单条理的,然而它的语法和传统的linux GNU Make编译脚本的编写似乎有很 ...

  5. NDK编译php,Android NDK编译常见错误及解决方案

    Android NDK编译常见错误及解决方案 Error 1:$ ndk-build/cygdrive/c/andy/abc/obj/local/armeabi-v7a/objs/abc//hello ...

  6. Android NDK 编译PjSip 2.6 之 搭建PjSip apk开发环境 (三)

    Android NDK 编译PjSip 2.6 之 PjSip编译 (二)中已经把so 和java文件编译出来.可以开始搭建apk的开发环境. 我们导入PjSip的example apk程序,编译生成 ...

  7. android 加载三方so的方法_Android开发教程之动态加载so库文件的方法

    Android开发教程之动态加载so库文件的方法,我想对于静态加载 so 库文件,大家都已经很熟悉了,这里就不多说了.在 Android 开发中调用动态库文件(*.so)都是通过 jni 的方式,而静 ...

  8. android.mk 添加v7_Android.mk引入第三方jar包和so库文件的方法

    以SystemUI为例,如果需要在SystemUI中引入第三方jar包以及so库,可作如下处理: 首先,在frameworks\base\packages\SystemUI下新建libs目录: 将需要 ...

  9. 在安卓项目中使用gifsicle编辑GIF动图-Android NDK 编译 gifsicle 为可执行文件记录

    一.前言 最近项目中有需要压缩GIF的需求,最开始时试图使用FFmpeg通过降低GIF的分辨率和帧率的来减少GIF文件体积,但实际测试下来,大多数情况下压缩效果并不理想,甚至会出现降低分辨率后导出的G ...

最新文章

  1. antd option宽度自适应_网站自适应模板是什么
  2. 20180525小测
  3. 微软Azure AspNetCore微服务实战第2期(内附PPT下载)
  4. 计算机丢失用户名,问下经验人士电脑用户名丢失怎么办
  5. pageoffice提示网络连接意外错误
  6. 小白的一周学习汇总!
  7. Cesium 鼠标单击和双击事件
  8. 12款常用的数据挖掘工具推荐
  9. IP地址的定义及分类
  10. stm32 win7 64位虚拟串口驱动安装失败解决办法
  11. shopnc怎么使用 php,ShopNC单用户版/安装php
  12. 波士顿房价预测python决策树_机器学习第二练---波士顿房价预测
  13. Android 中view的解释
  14. 超详细: Type-C接口Macbook笔记本无法充电(时连时断)的傻瓜处理流程
  15. node 安装(新)
  16. java web前端哪个城市,Java Web 是前端还是后端
  17. 谈分答商业模式中的收入模式
  18. 红米Note 4X详细刷成开发版开启ROOT超级权限的教程
  19. 杭电OJ 1095(C++)
  20. linux堡垒机开源软件,开源堡垒机-01-JumpServer的安装

热门文章

  1. Python:tkinter滚动抽奖器
  2. 【杂谈】当当最新购书优惠来了,满300-60,AI好书推荐
  3. 【AI不惑境】残差网络的前世今生与原理
  4. 中国滤清器制造行业竞争格局分析与发展战略规划研究报告2022年版
  5. Git的思想和基本工作原理
  6. NF5270M3服务器主板安装系统,NF5270M3 – 主板相关
  7. 乡村振兴谋定齐鲁道路-农业大健康·李昌平:放权改革创新
  8. 解决Ubuntu“下载额外数据文件失败 ttf-mscorefonts-installer”的问题 (转载)
  9. 用C++对C++语法格式进行分析
  10. Spring.Net的IOC入门