Android NDK for x86_64没有bcopy和index的参考

Rez*_*eza 6 android android-ndk

我正在尝试使用Android NDK为x86_64架构编译Lame声音库.我收到以下链接错误未定义引用bcopyindex:

jni/libmp3lame/encoder.c:471: error: undefined reference to 'bcopy'
jni/libmp3lame/encoder.c:476: error: undefined reference to 'bcopy'
jni/libmp3lame/id3tag.c:1125: error: undefined reference to 'index'
jni/libmp3lame/newmdct.c:1036: error: undefined reference to 'bcopy'
jni/libmp3lame/util.c:685: error: undefined reference to 'bcopy'
Run Code Online (Sandbox Code Playgroud)

代码成功编译了x86和arm架构.

因此,我通过NDK的libs挖了一下,发现bcopyindex都出口了libc.so用于x86和ARM平台,而不是x86_64的(见下文objdump输出).

$> objdump -d android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/libc.so | grep bcopy -A 6
0000b000 <bcopy>:
    b000:   e52db004 push   {fp}    ; (str fp, [sp, #-4]!)
    b004:   e28db000 add    fp, sp, #0
    b008:   e28bd000 add    sp, fp, #0
    b00c:   e8bd0800 ldmfd  sp!, {fp}
    b010:   e12fff1e bx lr


$> objdump -d android-ndk-r10d/platforms/android-21/arch-x86/usr/lib/libc.so | grep -A 6 bcopy
00009fb0 <bcopy>:
    9fb0:   55                   push   %ebp
    9fb1:   89 e5                   mov    %esp,%ebp
    9fb3:   5d                   pop    %ebp
    9fb4:   c3                   ret


$>  objdump -d android-ndk-r10d/platforms/android-21/arch-x86_64/usr/lib/libc.so | grep -A 6 bcopy
<<NOTHING FOUND>>
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?下面是我的Android.mk和Application.mk文件.

Application.mk:

APP_ABI:=x86_64
APP_PLATFORM := android-21
Run Code Online (Sandbox Code Playgroud)

Android.mk:

LOCAL_PATH := $(call my-dir)

APP_PLATFORM := android-21

include $(CLEAR_VARS)

LOCAL_MODULE        := libmp3lame

LOCAL_SRC_FILES     := \
...<list-of-.c-files>...

LOCAL_LDLIBS += -llog

include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

sle*_*ica 9

你可以用Application.mk(docs)中的一行干净利落地解决这个问题:

APP_CFLAGS += -DSTDC_HEADERS
Run Code Online (Sandbox Code Playgroud)

为什么?

LAME假定某些符号可以在没有明确包含的情况下访问#include.但是,它也提供了一种表明必须明确包含的方法.

在我的发行版中,冲突文件(machine.hid3tag.c)有这样的东西:

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#endif
Run Code Online (Sandbox Code Playgroud)

这是您需要通过设置STDC_HEADERS预处理器变量来触发的块.上面的行带有-D标志,告诉C编译器创建它.

  • 超级感谢快速简便的解决方案!也有同样的效果,我在 Android.mk 中使用了 LOCAL_CFLAGS += -DSTDC_HEADERS (2认同)

jww*_*jww 0

我有它strings.h,但它是#define

$ cd /opt/android-ndk-r10d
$ grep -R bcopy * | grep x86_64
platforms/android-21/arch-x86_64/usr/include/linux/mroute6.h:#define IF_COPY(f, t) bcopy(f, t, sizeof(*(f)))
platforms/android-21/arch-x86_64/usr/include/strings.h:#define bcopy(b1, b2, len) \
platforms/android-21/arch-x86_64/usr/include/strings.h:#define bcopy(b1, b2, len) (void)(__builtin_memmove((b2), (b1), (len)))
Run Code Online (Sandbox Code Playgroud)

这是它的样子(取自 header strings.h):

#if defined(__BIONIC_FORTIFY)
#  define bcopy(b1, b2, len) \
    (void)(__builtin___memmove_chk((b2), (b1), (len), __bos0(b2)))
#  define bzero(b, len) \
    (void)(__builtin___memset_chk((b), '\0', (len), __bos0(b)))
#else
# define bcopy(b1, b2, len) (void)(__builtin_memmove((b2), (b1), (len)))
# define bzero(b, len) (void)(__builtin_memset((b), '\0', (len)))
#endif
Run Code Online (Sandbox Code Playgroud)

早期版本的 Android 运行时将其作为库调用提供。例如,请参阅如何理解bionic的bcopy.c中的这段代码?

这听起来像是标题在 发生变化的另一种情况android-21。也就是说,它是一个过去在库中作为导出呈现的函数,但现在可以在标头中使用。例如,请参阅无法加载库:reloc_library[1285]:无法定位 'rand'

我认为解决方法是使用 重新编译 Lame 声音库android-21,而不是使用早期版本的工具链。

此外,还有各种config.h评论如下:

/* HAS_BCOPY:
 *  This symbol is defined if the bcopy() routine is available to
 *  copy blocks of memory.
 */
#define HAS_BCOPY   /**/
Run Code Online (Sandbox Code Playgroud)

您可以找到config.hat,例如,android-ndk-r10d/prebuilt/darwin-x86_64/lib/perl5/5.16.2/darwin-2level/CORE/config.h

如果它不是显而易见的东西(就像您已经在下面进行编译android-21并且arch是正确的),那么我们需要查看您的项目是如何设置的(比如看起来是什么样子Application.mk,或者--sysroot正在使用什么)。