We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2758 - Android issues with NDK r10c and API-21
Summary: Android issues with NDK r10c and API-21
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: build (show other bugs)
Version: 2.0.3
Hardware: x86_64 Android (All)
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-20 06:31 UTC by Sylvain
Modified: 2016-10-14 13:58 UTC (History)
2 users (show)

See Also:


Attachments
patch (1.17 KB, patch)
2015-06-17 06:46 UTC, Sylvain
Details | Diff
patch (1.82 KB, patch)
2015-06-17 06:55 UTC, Sylvain
Details | Diff
patch for SDL / tests (5.56 KB, patch)
2015-06-17 07:06 UTC, Sylvain
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sylvain 2014-10-20 06:31:30 UTC
Latest NDK r10c has been released
https://developer.android.com/tools/sdk/ndk/index.html

When targeting the API-21, the lib SDL2.so is not loaded because a few functions are claimed to be missing (ex: signal, sigsetaction, atof, ...)

I am not sure about the correct solution to perform: referencing shared libraries "libc" and "libm" does not seems to solve the problem.
Comment 1 Gabriel Jacobo 2014-10-20 12:37:58 UTC
Can you post the error log?
Comment 2 Sylvain 2014-10-20 16:43:54 UTC
The first error is : 

E/AndroidRuntime(24105): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "signal" referenced by "libSDL2.so"...

-> If, I comment HAVE_SIGNAL, HAVE_SIGACTION

I have : 

E/AndroidRuntime(25255): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "atof" referenced by "libSDL2.so"...

-> If, I comment HAVE_ATOF:

E/AndroidRuntime(25671): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "sigemptyset" referenced by "libSDL2.so"...

... Then : 

E/AndroidRuntime(29050): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "srand" referenced by "libSDL2.so"...


Adding libc, libm does not solve the problem.
*Downgrading* to API-level 20 does solve the problem
Comment 3 Gabriel Jacobo 2014-10-21 14:10:35 UTC
I tried reproducing with the latest NDK for Linux, using androidbuild.sh and testgles2.c, the issue does not show up with the default project settings.

Let me know if you find out what's going on.
Comment 4 Sylvain 2014-10-21 14:14:15 UTC
In case, it helps, here's some precision :

- api level 21
- ndk-r10c
- Linux 64-bit (x86)
- arch = arm-v7a

I will try later with testgles2
Comment 5 Sylvain 2014-10-21 19:12:14 UTC
I can get the same problem with testgles2. I start with
../build-scripts/androidbuild.sh com.blabla.blabla testgles2.c 

I go to the build dir.
This build an .apk with the "dlopen" issue.

 ndk-build clean
 android update project  --target android-21 --path `pwd`
 ndk-build -j
 ant debug install


This build a correct .apk

 ndk-build clean
 android update project  --target android-20 --path `pwd`
 ndk-build -j
 ant debug install
Comment 6 Sylvain 2015-04-24 09:45:26 UTC
Update.

This issue still exists with the NDK-r10d. 
When using API 21 and running on an old device (android < 5.0 ?) some function are missing.

functions are (at least) : signal, sigemptyset, atof, stpcpy (strcat and strcpy), srand, rand.


Very few modifications on SDL to get this working :

on SDL
======

Undefine android configuration :

HAVE_SIGNAL
HAVE_SIGACTION
HAVE_ATOF

In "SDL_systrhead.c", comment out the few block of lines with "sigemptyset".

Android.mk:
remove the compilation of "test" directory because it contains a few rand/srand calls

SDL_image / png
===============

There are 4 calls to "atof(param)" in "pngget.c" that can get replaced by "strtod(param,NULL)".



Also, there are more discussions about this in internet : 
https://groups.google.com/forum/#!topic/android-ndk/RjO9WmG9pfE
http://stackoverflow.com/questions/25475055/android-ndk-load-library-cannot-locate-srand
Comment 7 Sam Lantinga 2015-06-17 05:20:26 UTC
Can you provide a tested patch for this issue?

Thanks!
Comment 8 Sylvain 2015-06-17 06:46:08 UTC
Created attachment 2182 [details]
patch

Patch for SDL_image
Comment 9 Sylvain 2015-06-17 06:55:05 UTC
Created attachment 2183 [details]
patch

Patch for SDL
Comment 10 Sylvain 2015-06-17 07:06:07 UTC
Created attachment 2184 [details]
patch for SDL / tests

Also a patch for SDL test.

replacing srand() by srand48()
replacing rand() by lrand48()

maybe otherfunction are to be replaced.
Comment 11 Sam Lantinga 2015-06-17 07:09:44 UTC
This is partially fixed with these commits:
https://hg.libsdl.org/SDL/rev/f2d87d87509f
https://hg.libsdl.org/SDL_image/rev/6292ebae060a

The rand/srand issue needs more work, and we probably need to add a config.h define for this.
Comment 12 Sylvain 2015-06-17 07:26:35 UTC
Ok Thanks!

Anyway a quick workaround for "rand/srand" is to remove the compilation of "src/test/*.c" from "SDL/Android.mk".
Comment 13 Sylvain 2016-06-30 07:57:51 UTC
After a long time, I found out more clearly what was going wrong.

The native libraries should be built with a "APP_PLATFORM" as low as possible.
Ideally, APP_PLATFORM should be equals to the minSdkVersion of the AndroidManifest.xml
So that the application never runs on a lower APP_PLATFORM than it has been built for.

An additional good patch would be to write explicitly in "jni/Application.mk": APP_PLATFORM=android-10

(If no APP_PLATFORM is set, the "targetSdkVersion" of the AndroidManifest.xml is applied as an APP_PLATFORM to the native libraries. And currently, this is bad, because targetSdkVersion is 12, whereas minSdkLevel is 10.
And in fact, there is a warning from ndk: "Android NDK: WARNING: APP_PLATFORM android-12 is larger than android:minSdkVersion 10 in ./AndroidManifest.xml".)


to precise what happened in the initial reported test-case:
Let say the "c" code contains a call to "srand()".

with APP_PLATFORM=android-21, libSDL2.so contains a undef reference to "srand()".
with APP_PLATFORM=android-10, libSDL2.so contains a undef reference to "srand48()".

but srand() is missing on devices with APP_PLATFORM=android-10 (it was in fact replaced by srand48()). 
So, if you build for android-21 (where srand() is available), you will really have a call to "srand()" and it will fail on android-10.
That was the issue. The path tried to fix this by in fact always calling srand48().


SDL patches that were applied are beneficial anyway, there are implicitly allowing they backward compatibility of using android-21 on a android-10 platform.
It can be helpful in case you want to target a higher APP_PLATFORM than minSdkVersion to have potentially access to more functions.
Eg you want to have access to GLES3 functions (or other) of "android-21". But, if dlopen() fails (on android-10), you do a fall-back to GLES2.
Comment 14 Sylvain 2016-06-30 08:43:04 UTC
In fact, I would revert this commit:
https://hg.libsdl.org/SDL/rev/f2d87d87509f

because it has disabled some signals that commons to all platforms.

(And so, it's better to explicitly add "APP_PLATFORM=android-10" to jni/Application.mk)
Comment 15 Sam Lantinga 2016-10-14 13:58:50 UTC
Fixed, thanks!
https://hg.libsdl.org/SDL/rev/dde37ddd81bc