Android ndk NDK:如何在不考虑体系结构的情况下包含预构建的共享库

Android ndk NDK:如何在不考虑体系结构的情况下包含预构建的共享库,android-ndk,Android Ndk,我正在研究移植Box2D,以了解更多关于android移植的知识 我可以得到项目编译,我看到以下 ls libs/ armeabi armeabi-v7a 现在我想做一些类似的事情,但我不知道如何让它足够聪明来选择arch(比如我想添加x86)。如何在不硬编码.so路径的情况下将.so包含到spec arch中?这很有效 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := box2D-prebuilt LOCAL_

我正在研究移植Box2D,以了解更多关于android移植的知识

我可以得到项目编译,我看到以下

ls libs/

armeabi armeabi-v7a

现在我想做一些类似的事情,但我不知道如何让它足够聪明来选择arch(比如我想添加x86)。如何在不硬编码.so路径的情况下将.so包含到spec arch中?

这很有效

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := box2D-prebuilt
LOCAL_SRC_FILES := ../Box2D/libs/$(TARGET_ARCH_ABI)/libbox2D.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := box2DHello
LOCAL_SRC_FILES := \
    $(subst $(LOCAL_PATH)/,, \
    $(wildcard $(LOCAL_PATH)/*.cpp))
LOCAL_LDLIBS := -lm -llog
LOCAL_SHARED_LIBRARIES := box2D-prebuilt
include $(BUILD_SHARED_LIBRARY)

只需定义您希望在android.mk和Application.mk中支持的体系结构,如NDK文档(Application-mk.html和PREBUILTS.html)中所述:

V.预构建二进制文件的ABI选择: 如前所述,提供预构建的共享库至关重要 在构建期间与目标ABI兼容。为此,, 检查TARGET_ARCH_ABI的值,其值将为:

armeabi=>以ARMv5TE或更高CPU armeabi-v7a为目标时 =>针对ARMv7或更高版本的CPU x86=>针对x86 CPU时mips=>针对mips CPU时

请注意,armeabi-v7a系统可以很好地运行armeabi二进制文件

下面是一个示例,其中我们提供了预构建库的两个版本 并根据目标ABI选择要复制的一个:

include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
在这里。我们假设要复制的预构建库在 以下目录层次结构:

Android.mk            --> the file above
armeabi/libfoo.so     --> the armeabi prebuilt shared library
armeabi-v7a/libfoo.so --> the armeabi-v7a prebuilt shared library
include/foo.h         --> the exported header file
注意:请记住,您不需要提供预构建的armeabi-v7a 库,因为armeabi one可以轻松地在相应的 设备


libmath-prebuild.so是一个预构建的库,它具有buyya_read.c使用的一些函数。首先使用ndk build生成libmath-prebuild.so并保存在jni文件夹中,buyya_read.c保存在elcipse的ur项目中

Android.mk(To generate libbuyya_read.so to use as jni library using prebuilt library)
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := math-prebuilt
    LOCAL_SRC_FILES = libmath-prebuilt.so
    include $(PREBUILT_SHARED_LIBRARY)

    include $(CLEAR_VARS)
    LOCAL_MODULE    := buyya_read
    LOCAL_SRC_FILES := buyya_read.c
    LOCAL_LDLIBS    := -llog
    LOCAL_SHARED_LIBRARIES := math-prebuilt
    include $(BUILD_SHARED_LIBRARY)

buyya_read.c
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <jni.h>
#include <stdio.h>

JNIEXPORT jint JNICALL Java_com_buyya_BuyyaJava_sum(JNIEnv *env,
    jclass thiz, jint a, jint b) {
hello();
int res = add(a, b);
return res;
}

math.c // using this generate libmath-prebuilt.so
#include <stdio.h>
void hello()
{
    printf("Hello world!\n");
}
int add(int a, int b)
{
    printf("Hello world!\n");
    return a+b;
}

Make file to generate libmath-prebuilt.so
Android.mk
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE    := math-prebuilt
    LOCAL_SRC_FILES := math.c
    LOCAL_LDLIBS    := -llog
    #LOCAL_EXPORT_C_INCLUDES:=../jni/
    include $(BUILD_SHARED_LIBRARY)
Android.mk(生成libbuyya_read.so作为使用预构建库的jni库)
本地路径:=$(调用我的目录)
包括$(清除变量)
本地_模块:=数学预构建
LOCAL_SRC_FILES=libmath-prebuild.so
包括$(预建共享库)
包括$(清除变量)
本地_模块:=buyya_读取
本地\u SRC\u文件:=buyya\u read.c
本地_LDLIBS:=-llog
本地共享库:=数学预构建
包括$(构建共享库)
buyya_read.c
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
JNIEXPORT jint JNICALL Java\u com\u buyya\u BuyyaJava\u sum(JNIEnv*env,
jclass thiz,jint a,jint b){
你好;
int res=添加(a,b);
返回res;
}
math.c//使用此函数生成libmath-prebuild.so
#包括
void hello()
{
printf(“你好,世界!\n”);
}
整数相加(整数a,整数b)
{
printf(“你好,世界!\n”);
返回a+b;
}
生成文件以生成libmath-prebuild.so
Android.mk
本地路径:=$(调用我的目录)
包括$(清除变量)
本地_模块:=数学预构建
本地_SRC_文件:=math.c
本地_LDLIBS:=-llog
#本地导出包括:=../jni/
包括$(构建共享库)
您可以在下图中看到项目目录结构。

任何人想要了解有关android.mk问题的良好文档,请参考以下内容:


我发现它用简单的语言很好地解释了,涵盖了Android.mk的大部分场景。希望有帮助。

Android NDK官方
你好libs
CMake示例

关键是要打包所有您关心的
。版本,例如:

  • distribution/gperf/lib/arm64-v8a/libgperf.so
  • distribution/gperf/lib/x86_64/libgperf.so
然后用:
${ANDROID\u ABI}
在CMake上选择正确的一个


我在:

上进一步解释了这个例子,看起来你的答案与我的答案基本相同。谢谢你的帮助!我面临同样的问题,但我只需要使用.so文件。我已按照您的指示编写本地\u路径:=$(调用我的目录)包含$(清除变量)本地\u模块:=box2D预构建本地\u SRC\u文件:=../box2D/libs/$(目标\u ARCH\u ABI)/libbox2D。因此本地\u导出\u包括:=$(本地\u路径)/。。包含$(预构建的共享库),但这会在prebuiltlibaray.mk中给出错误