Tank2005 Tank2005 - 3 months ago 33
C Question

Android NDK returns an error "undefined reference to 'rand'"

I'm trying a webm decorder for Android x86 with libvpx.

I built the library by following command and got "libvpx.a".

../configure --target=x86-android-gcc --disable-vp8-encoder --disable-vp9-encoder --disable-examples --sdk-path=$ANDROID_NDK_ROOT --enable-pic --enable-postproc


When I use this library is by ndk-build on Windows, an error occurred.

C:/android/[project]/jni/../plib/libvpx.a(postproc_mmx.asm.o)(.text+0x1c8): error: undefined reference to 'rand'
C:/android/[project]/jni/../plib/libvpx.a(postproc_sse2.asm.o)(.text+0x65c): error: undefined reference to 'rand'
collect2.exe: error: ld returned 1 exit status


libvpx.a for armeabi didn't occur an error. Doesn't someone know solution?

(jni/Android.mk)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := sublib
LOCAL_SRC_FILES := sublib.cpp

LOCAL_LDLIBS := -llog

LOCAL_STATIC_LIBRARIES := libvpx_pre

include $(BUILD_SHARED_LIBRARY)

include $(LOCAL_PATH)/../plib/Android_x86.mk


(plib/Android_x86.mk)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := libvpx_pre
LOCAL_SRC_FILES := libvpx.a
LOCAL_STATIC_LIBRARIES := cpufeatures

include $(PREBUILT_STATIC_LIBRARY)

$(call import-module,android/cpufeatures)

Answer

Contrary to the initial impression (from the subject), this isn't (directly) a duplicate of Cannot load library: reloc_library[1285]: cannot locate 'rand'.

It seems that when configuring libvpx with --target=x86-android-gcc, it actually doesn't automatically pick an android compiler or try to use android headers (contrary to what it does for armv7-android-gcc). (In fact, if you compile with --target=x86-android-gcc on OS X, it doesn't even build linux/android binaries, it will end up building a binary for OS X.)

Instead it builds pretty much as usual, using the normal system compiler, with the normal system headers (unless you manually specify them), which contain a normal rand function, which isn't available on Android. (On Android versions prior to 5.0, the rand function in stdlib.h is an inline function that actually maps to the lrand48 function, which is what the binary ends up linking to).

(Also, when building for android on arm, it doesn't seem to allow you to pick which android version you're targeting, so if your NDK contains android-21, it seems that it will try to build with that, which can also give you similar errors, such as in Cannot load library: reloc_library[1285]: cannot locate 'rand'.)

Since the configure script magic doesn't seem to set up the right things for building for x86 android (as it does for arm), you should be able to set it up yourself instead, which requires setting a bit more parameters:

export PATH=<NDK>/toolchains/x86-4.8/prebuilt/*x86*/bin:$PATH
ASFLAGS="-D__ANDROID__" CROSS=i686-linux-android- LDFLAGS="--sysroot=<NDK>/platforms/android-9/arch-x86" ./configure --target=x86-android-gcc --extra-cflags="--sysroot=<NDK>/platforms/android-9/arch-x86" --disable-examples
make

With this, I'm able to build a libvpx.a which should be built against the right headers, which hopefully should work fine for you.

Comments