问题
I am trying to incorporate some compiled C code into an Android app. I've been able to use the NDK to build the source and it has produced both a .so (7kB) and a .a (nearly 2MB).
I'm using Xamarin and all the instructions say to include the .so in the project. I've done that and the application loads the library. However it throws an EntryPointNotFoundException exception. This doesn't surprise me because the .so contains nothing except RTL support functions. The actual code is in the .a.
So I have two questions: 1. How can I link the .a into my Android library? or 2. How can I get NDK to package everything into a single .so?
For what it's worth here is the .mk file:
ROOT := $(call my-dir)
# Build libopus
LOCAL_PATH := ../opus-1.2.1/opus-1.2.1
include $(CLEAR_VARS)
#include the .mk files
include $(LOCAL_PATH)/celt_sources.mk
include $(LOCAL_PATH)/silk_sources.mk
include $(LOCAL_PATH)/opus_sources.mk
LOCAL_MODULE := opus
#fixed point sources
SILK_SOURCES += $(SILK_SOURCES_FIXED)
#floating point sources - this throws badly!
#SILK_SOURCES += $(SILK_SOURCES_FLOAT)
#ARM build
CELT_SOURCES += $(CELT_SOURCES_ARM)
SILK_SOURCES += $(SILK_SOURCES_ARM)
LOCAL_SRC_FILES := \
$(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES)
LOCAL_LDLIBS := -lm -llog
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/silk \
$(LOCAL_PATH)/silk/float \
$(LOCAL_PATH)/celt
LOCAL_CFLAGS := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
#LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT=1 -DDISABLE_FLOAT_API -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
LOCAL_CPPFLAGS := -DBSD=1
LOCAL_CPPFLAGS += -ffast-math -O3 -funroll-loops
#include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opus-share
#LOCAL_SRC_FILES := libopus.a
LOCAL_STATIC_LIBRARIES := opus
include $(BUILD_SHARED_LIBRARY)
Thanks.
回答1:
I can confirm that changing to LOCAL_WHOLE_STATIC_LIBRARIES was indeed the solution. Also the original mk is attempting to be both fixed and floating point. So the final fix to all this:
# This .mk has to be in a folder called jni. Because :(
ROOT := $(call my-dir)
# Build libopus.a (static library)
LOCAL_PATH := ../opus-1.2.1/opus-1.2.1
include $(CLEAR_VARS)
#include the .mk files
include $(LOCAL_PATH)/celt_sources.mk
include $(LOCAL_PATH)/silk_sources.mk
include $(LOCAL_PATH)/opus_sources.mk
LOCAL_MODULE := opus
#fixed point sources
SILK_SOURCES += $(SILK_SOURCES_FIXED)
#floating point sources - this throws badly!
#SILK_SOURCES += $(SILK_SOURCES_FLOAT)
#ARM build
CELT_SOURCES += $(CELT_SOURCES_ARM)
SILK_SOURCES += $(SILK_SOURCES_ARM)
LOCAL_SRC_FILES := \
$(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES)
LOCAL_LDLIBS := -lm -llog
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/silk \
$(LOCAL_PATH)/silk/fixed \
$(LOCAL_PATH)/celt
LOCAL_CFLAGS := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT=1 -DDISABLE_FLOAT_API -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
#LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
LOCAL_CPPFLAGS := -DBSD=1
LOCAL_CPPFLAGS += -ffast-math -O3 -funroll-loops
include $(BUILD_STATIC_LIBRARY)
# Now create a dynamic library that contains the static library
include $(CLEAR_VARS)
LOCAL_MODULE := opus-share
#LOCAL_SRC_FILES := opus
LOCAL_WHOLE_STATIC_LIBRARIES := opus
include $(BUILD_SHARED_LIBRARY)
This was built using the Windows NDK and I had to put that file (called Android.mk) into a directory called 'JNI'.There may be some trick to avoid doing that involving environment variables but I gave up trying to fight it. Combine that with opus 1.2.1 source code and platform specific mk files like this:
APP_ABI := arm64-v8a
APP_PLATFORM := android-19
APP_STL := c++_static
APP_BUILD_SCRIPT := Android.mk
and you have .so files for Android. Just change the ABI value appropriately.
来源:https://stackoverflow.com/questions/54418971/entry-point-not-found-android-so-file