日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

發布時間:2025/3/20 Android 73 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android NDK编译中在libs\armeabi中加入第三方so库文件的方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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库文件的方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。