Macos 如何解决;未定义对<;myfunction>&引用;从NDK构建的静态库到NDK构建的静态库?

Macos 如何解决;未定义对<;myfunction>&引用;从NDK构建的静态库到NDK构建的静态库?,macos,android-ndk,static-libraries,linker-errors,undefined-reference,Macos,Android Ndk,Static Libraries,Linker Errors,Undefined Reference,我得到一个“未定义的‘myfunction’引用,试图从共享(.so)库调用静态(.a)库中的函数。(这是OSX上的NDK问题)。该函数是名为“ffts android”的fft库的一部分()。我可以用这个项目生成库。我唯一做的更改是从BUILD_SHARED_LIBRARY改为BUILD_STATIC_LIBRARY,这样我就可以将它合并到我们组织的Android应用程序中使用的共享库中 我非常确定我需要的函数ffts_init_1d(size_t,int)在静态库中应该存在,因为我使用nm实

我得到一个“未定义的‘myfunction’引用,试图从共享(.so)库调用静态(.a)库中的函数。(这是OSX上的NDK问题)。该函数是名为“ffts android”的fft库的一部分()。我可以用这个项目生成库。我唯一做的更改是从BUILD_SHARED_LIBRARY改为BUILD_STATIC_LIBRARY,这样我就可以将它合并到我们组织的Android应用程序中使用的共享库中

我非常确定我需要的函数ffts_init_1d(size_t,int)在静态库中应该存在,因为我使用nm实用程序(底部的输出)列出了符号表中可用的函数

然后我想我应该尝试修改NDK的一个简单示例程序,以防我的Android.mk出现问题“采样并进行必要的最简单更改,得到相同的错误。在其原始状态下,它构建一个静态库,然后将其链接到一个共享库中,就像我尝试做的那样。我刚刚在Android.mk中添加了一行,下面中间的一行,这样它就可以链接到我从ffts Android项目中构建的库:

LOCAL_STATIC_LIBRARIES := foo
LOCAL_STATIC_LIBRARIES += libffts-neon
include $(BUILD_SHARED_LIBRARY)
然后修改bar.c,使其调用与我尝试调用的相同的方法ffts_init_1d(size_t,int):

#include "bar.h"
#include "ffts.h"
#include "foo.h"

int  bar(int  x)
{
    /*return*/foo(x)-1;
    ffts_init_1d(1, 1);
    return 1;
}
最后,我将ffts.h和libffts neon.a文件移动到模块导出可以找到它们的位置,然后构建示例。它产生了与我得到的完全相同的错误

samples/module-exports/jni/bar/bar.c:8: undefined reference to `ffts_init_1d'
<> P>模块导出项目和FFTS Android项目都是纯C代码,而我们的代码库是C++,所以我试图调用一个由C代码从C++构建的静态库。然而,头文件ffts.h已经有了所需的代码来适应这个标准:

#ifdef __cplusplus
extern "C"
{
下面是nm实用程序的输出。在我看来,它似乎列出了我试图调用的函数,那么为什么它不可用呢

./nm -g libffts-neon.a

ffts.o:
         U _GLOBAL_OFFSET_TABLE_
         U __aeabi_uidiv
         U __aeabi_uidivmod
         U __aeabi_unwind_cpp_pr0
         U __aeabi_unwind_cpp_pr1
         U __android_log_print
         U __errno
         U cos
         U exit
00000000 T ffts_execute
00000000 T ffts_free
00000000 T ffts_free_1d
         U ffts_generate_func_code
00000000 T ffts_init_1d
         U ffts_init_is
         U ffts_init_offsets
         U firstpass_16_b
         U firstpass_16_f
         U firstpass_2
         U firstpass_4_b
         U firstpass_4_f
         U firstpass_8_b
         U firstpass_8_f
         U free
         U malloc
         U mprotect
         U munmap
         U perror
         U sin
         U valloc

ffts_real.o:
         U __aeabi_unwind_cpp_pr0
         U __aeabi_unwind_cpp_pr1
         U cos
00000000 T ffts_execute_1d_real
00000000 T ffts_execute_1d_real_inv
         U ffts_free
00000000 T ffts_free_1d_real
         U ffts_init_1d
00000000 T ffts_init_1d_real
         U free
         U malloc
         U sin
         U valloc
. . .
以下是我使用V=1(详细输出)调用ndk构建时得到的结果:

这是Android.mk文件。稍加修改,如下所述:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_CFLAGS := -DFOO=2
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/foo
LOCAL_EXPORT_CFLAGS := -DFOO=1
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar/bar.c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/bar
LOCAL_STATIC_LIBRARIES := libffts-neon
LOCAL_STATIC_LIBRARIES += foo
include $(BUILD_SHARED_LIBRARY)

您必须定义预构建的静态库libffts neon.a,以便模块使用。其思想是,每个库(静态或共享、预构建或编译)都应该有其单独的部分,并分配其单独的本地\u模块名称。因此,您缺少以下魔法:

include $(CLEAR_VARS)
LOCAL_MODULE := libffts-neon
LOCAL_SRC_FILES := obj/local/armeabi-v7a/libffts-neon.a
include $(PREBUILT_STATIC_LIBRARY)
这可以放在您的Android.mk中的任何位置,或者使用include指令并将其保存为单独的文件

请注意,本地\u静态\u库指的是模块名称,而不是实际文件的名称。因此,以下内容也可以:

include $(CLEAR_VARS)
LOCAL_MODULE := qqq
LOCAL_SRC_FILES := obj/local/armeabi-v7a/libffts-neon.a
include $(PREBUILT_STATIC_LIBRARY)
…
LOCAL_STATIC_LIBRARIES += qqq
include $(BUILD_SHARED_LIBRARY)
另一个注意事项是,您可以将预构建库放在任何位置,ndk build将根据需要将其复制到相应的目录中


Official的细节令人惊讶,它解决了多ABI支持和预构建库的其他黑暗角落的问题。

libffts_neon显然是为armeabi-v7a构建的,但您的so是为armeabi构建的。用同样最小的Android.mk试试ndk build APP_ABI=armeabi-v7a,也许会有帮助。同样的错误。Application.mk是为所有人定义的,因此它确实试图构建一些不起作用的组合。但我定义了它,正如您所指出的,仅用于armeabi-v7a,并且得到了相同的错误。为了清楚起见,我正在构建模块导出示例,如问题中所示进行了修改。仅供参考,该示例在其objs/local/armeabi-v7a文件夹中构建其.a库,因此我将libffts neon.a文件放在该文件夹中。只是注意到错误消息发生了轻微的变化。在它出现之前,samples/module exports/jni/bar/bar.c:8:未定义对“ffts_init_1d”的引用。重新定义APP_ABI后,它现在是jni/bar/bar.c:8:错误:未定义对“ffts_init_1d”的引用可能它没有在正确的目录中查找库?运行
ndk build V=1
并将控制台输出粘贴到它工作的地方(或粘贴到pastebin上)。非常感谢。想提供一个我可以选择为正确答案的答案吗?一个问题:您发送的文档让我对如何使用本地_模块感到困惑。我在新的预构建部分使用“我的FFT”,然后在构建共享库的最后一部分中将“我的FFT”分配到本地静态库中,从而使其正常工作。但是在V=1输出中没有提到“我的FFT”。本地_模块有什么用途?仅在.mk文件中提供重命名?
include $(CLEAR_VARS)
LOCAL_MODULE := qqq
LOCAL_SRC_FILES := obj/local/armeabi-v7a/libffts-neon.a
include $(PREBUILT_STATIC_LIBRARY)
…
LOCAL_STATIC_LIBRARIES += qqq
include $(BUILD_SHARED_LIBRARY)