4

I am creating a command line C++ test application (executable) to be run on my rooted android device.

The executable uses multiple prebuilt C libraries, one of which use 'rand()'. During linking state i get the error "undefined reference of 'rand'"

To check if the paths are set properly, I have tried below approaches with no success.

First Approach: I define the rand() in my test source.

I notice that i get mutiple definition error, the first definition being in bionic/libc/include/stdlib.h

Second Approach: Used rand() in my test application

I notice that the linker does not complain about undefined symbol here

Third Approach: Unarchived and archived all the object files

Found that I still get the undefined reference error.

When the C library that uses 'rand' is compiled into an executable using C test file the mentioned linker error is not seen.

I cannot modify the prebuilt static libraries and need to use the library with my C++ based test application.

Any inputs will be very welcome.

Deepak
  • 1,101
  • 9
  • 14
  • It sounds to me like the library expects rand to return 'int rand' instead of 'unsigned int rand'. If it's statically linked why use a 'hack' and compile/link a test C file? – std''OrgnlDave Mar 29 '12 at 14:00
  • The rand is a standard C module and is linked while creating a shared object or an executable. The static library provided to me, uses the rand() call and does not have it's definition included. – Deepak Mar 30 '12 at 05:16
  • I would suggest looking into a symbol dumper. I know what rand() is and I find it likely that your static library was compiled against a different version than your C library uses. You may be able to clear this up in a number of ways (providing your own rand, providing a 'wrapper' to C rand, etc...) but your best bet is to check a symbol dump. I would also direct you to http://stackoverflow.com/questions/4768180/rand-implementation – std''OrgnlDave Mar 30 '12 at 07:26

2 Answers2

1

Not enough points to comment so ...

If you look in bionic's stdlib.h, you will see that rand() is defined as

static inline int rand(void) { ... }

i.e. the actual code for the function is there in the header file.

This is why your first approach gives you a multiple-definition error.

You second approach succeeds for the same reason, and (as the function is in-line) generates no 'extern' reference in the object file to cause a search of any libraries.

Next. Your C++ code will be linking against either libc or libstdc++ (you'll need to check). Your prebuilt static library was obviously compiled against a stdlib.h which did not have an inline implementation of rand().

You need to do an LDD (or readelf) command on the static and see which library its looking for that isn't there on your platform. It is most likely that the library has the same name as the bionic one, which doesn't export a rand() symbol, and hence the loader is failing to resolve the reference.

Now, as to fixing this ... are you able to at least rebuild the static libs, if not change them? Is your C test file being cross-compiled for android, or natively?

kdopen
  • 8,032
  • 7
  • 44
  • 52
0

Use 'android-ndk32-r10-windows-x86_64.zip', not 'android-ndk64-r10-windows-x86_64.zip'

APP_ABI := armeabi armeabi-v7a x86

The 3 api is 32bit.

SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73