1. 程式人生 > >NDK build 引入第三方動態庫

NDK build 引入第三方動態庫

最近的實踐中,有一個開源庫在linux上執行良好,但是想把它打包到android平臺,需要在ndk編譯使用

這個開源庫,是有原始碼的,在linux上編譯出so庫,在ndk編譯有錯誤,具體錯誤碼,記不清楚了,但是很明顯是linux平臺的gcc/g++編譯的,而不是ndk的交叉編譯環境出來的so庫,所以ndk編譯不成功。那麼。。。如何解決的

1. ndk交叉編譯原始碼第三方庫

如果別人給的動態庫是linux環境編譯的,看來還真不好直接用在Android環境中。需要Android平臺的編譯出來的so庫

- 建立jni目錄,開原始碼全部拷貝進jni。示例的Android.mk 是帶了Opencv-android SDK

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ../../../sdk/native/jni/OpenCV.mk

MY_CPP_LIST := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%)

LOCAL_C_INCLUDES += $(LOCAL_PATH) \
                    $(JNI_H_INCLUDE)

LOCAL_LDLIBS     += -llog -ldl -pthread -lm
LOCAL_SHARED_LIBRARIES += \
                        libandroid \


LOCAL_MODULE := asm
#LOCAL_CFLAGS += -pie -fPIE
#LOCAL_LDFLAGS += -pie -fPIE
include $(BUILD_SHARED_LIBRARY)
#include $(BUILD_EXECUTABLE)
 - Application.mk

 因為要用到STL,Application.mk 需要配置STL

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_CFLAGS += -Wno-error=format-security
APP_ABI := armeabi-v7a

現在,我們開源庫的android動態庫編譯出來了

2. 拷貝android.so庫到真實專案的jni/prebuild 下

這個so庫,需要在 主Android.mk 中重新prebuilt一下,所以暫時讓它待在prebuild目錄下,在這個目錄下同時需要建立一個Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := asm_prebuild
LOCAL_SRC_FILES := libasm.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/stasm_lib.h
include $(PREBUILT_SHARED_LIBRARY)

重新建立一個asm_prebuild 庫,將會用在最終專案的jni/Android.mk 裡,這一步不需要ndk-build, 會在主Android.mk一起編譯

3.  主Android.mk

這個是在最終專案的jni下,帶自己的程式碼和Android.mk & Application.mk

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ../../../sdk/native/jni/OpenCV.mk


LOCAL_SRC_FILES  := \
                    com_example_camerademo_JniClient.c \
                    delu.cpp

LOCAL_C_INCLUDES += $(LOCAL_PATH)/inc \
                    $(JNI_H_INCLUDE)

LOCAL_LDLIBS     += -llog -ldl -pthread -lm
LOCAL_SHARED_LIBRARIES += \
                        libandroid \
                        asm_prebuild


LOCAL_MODULE := delu
LOCAL_CFLAGS += -pie -fPIE
LOCAL_LDFLAGS += -pie -fPIE
#include $(BUILD_SHARED_LIBRARY)
include $(BUILD_EXECUTABLE)

include $(LOCAL_PATH)/prebuild/Android.mk

帶了Opencv的android SDK,三方庫在LOCAL_SHARED_LIBRARIES裡面, -pie也帶了,不帶在android shell裡不能直接執行(生成的BUILD_EXECUTABLE)

生成的是可執行的delu,adb push 到手裡裡,直接執行, 注意最後一行, 是順帶了prebuild的第三方庫

Appliaction.mk

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_CFLAGS += -Wno-error=format-security
APP_ABI := armeabi-v7a
#APP_PLATFORM := android-8

這個Application.mk跟剛才那個一樣,主要是帶STL和APP_ABI

兩個SRC_FILES, 一個是com.example*,是用在jni跟java互動的,一個是咱自己的CPP程式碼,實現了呼叫三方庫的api和基本邏輯,如果是自己執行到手機的可執行檔案,只需要CPP程式碼,且需要加個main函式。

-THE END