SDL2 + CMake + Android (on Windows)

Ah yes, I too stumbled into this issue. I circumvented it by turning off the warning <.<
Your patch is a better solution if SDL was meant to be used with C89 compilers.

I also bumped into some other issues:

  • One was that there were missing declarations in SDL_render_gles.c file, which I fixed with a #define GL_GLEXT_PROTOTYPES at the top of the file
  • Another was that pthreads wasn’t found when linking, looking in the ndk directory it seemed that indeed there is no pthreads library so I turned it off by adding ANDROID to the condition in SDL’s main CMakeLists.txt

After this, my project compiles using your toolchain file (which is taka-no-me’s modified toolchain file if I’m not mistaken). So now I have a shared lib which should be bundled into an apk.

Thanks for the info, and thanks in clarifying that at least one of the issues I bumped into is a global issue with SDL and not something I misconfigured :slight_smile:
I wonder if my other to issues are global or I did something wrong, right now I just want a working solution and want to work from there.

I almost get it compiled with Taka-No-Me’s android-cmake toolchain, after I’ve manually changed a few generated makefile. The missing reference is SDL_main(), which probably means the main() (I built it straight from the code without include it to my project yet). From what I found -lpthread is not really needed in ndk. I have to add the -lGLESv1_CM, -lGLESv2, -llog and -landroid manually, btw.

I’ve got it compiled in Visual Studio using the MS’s version of CMake I mentioned below as well. Using very similar method to above (without the toolchain file). It only compiles to object file, so I think I have to create a java project in Android Studio and put it there manually. Not very convenience, but it works at least. I haven’t have time to test it yet though.

IMO, if SDL is written in C90/C89 standard, the android specific part should be written in that standard as well. At least of the consistency, and the warning (and the flag that promote it to an error) would not have to be turned off. I haven’t checked how the warning is added to the makefile though. Probably in the cmake script, or may be in the toolchain file?

One more thing, it looks like this kind of question pops up every now and then (I searched the forum and see a number of threads). We may need to come up with a better solution, and post it in the wiki. Don’t you think ?

mr_tawan wrote:

I almost get it compiled with Taka-No-Me’s android-cmake toolchain, after I’ve manually changed a few generated makefile. The missing reference is SDL_main(), which probably means the main() (I built it straight from the code without include it to my project yet). From what I found -lpthread is not really needed in ndk. I have to add the -lGLESv1_CM, -lGLESv2, -llog and -landroid manually, btw.

I’ve got it compiled in Visual Studio using the MS’s version of CMake I mentioned below as well. Using very similar method to above (without the toolchain file). It only compiles to object file, so I think I have to create a java project in Android Studio and put it there manually. Not very convenience, but it works at least. I haven’t have time to test it yet though.

IMO, if SDL is written in C90/C89 standard, the android specific part should be written in that standard as well. At least of the consistency, and the warning (and the flag that promote it to an error) would not have to be turned off. I haven’t checked how the warning is added to the makefile though. Probably in the cmake script, or may be in the toolchain file?

One more thing, it looks like this kind of question pops up every now and then (I searched the forum and see a number of threads). We may need to come up with a better solution, and post it in the wiki. Don’t you think ?

For the SDL_main problem:
Even if you define SDL_main (the usual way of this is to have a standard main function with SDL.h or SDL_main.h header included, which has a #define to rename your main to SDL_main), you’ll get undefined reference for main because an SDL android project doesn’t have a main, it isn’t meant to be compiled to be an executable, but as a shared library which is loaded by SDL’s java Activity class. I chekced M. Gerhardy’s working example and he does the same with with a handful of CMake macros. I also think you need that java wrapper even with MS’s solution.

I also agree that the correct fix is to apply Martin’s patch, me turning off the warning was just a quick fix.

Yes, this information should be summed up, and it should be in the official place, but first there should be a solution that works easily. It isn’t really inviting if a half-baked solution is provided which needs 13 manual steps to work :stuck_out_tongue:
Sadly it seems I won’t be able to have to much spare time in the near future.

I just submitted a patch to make the code base C89 clean.
https://bugzilla.libsdl.org/show_bug.cgi?id=3264

I still maintain my Android patch and I think it is a good way of
doing it, originally announced here:
https://forums.libsdl.org/viewtopic.php?t=10263&sid=2888ecbb7fc048bbb49de54e0c357dda
But the repo has been moved here:

I’ve been planning to revisit getting this mainlined again. But I
wanted to get my use case out the door first so it would be easier to
explain some of the motivations. But ultimately, it is about making a
prebuilt Android library that follows standard platform conventions
that you can just download and link to, like we have for many of the
other platforms.

I actually just put out a teaser video today showing a use case of
prebuilt binaries in an SDL based SDK I’ve been developing. Though
ironically there’s no Android yet because it is a Swift language
focused video (and haven’t done the Swift port to Android yet).

This one actually shows the Android part in more detail, though it
still is a little high level. The main point is that SDL is prebuilt
and your application just links to it. (And I’ve already written all
the build system stuff, so my SDK users don’t have to think about it.)

This is made possible by having a process that we can reliably build
SDL for Android as a prebuilt library ahead of time. There is also
some stuff to make the SDLmain entry point pre-build-able.

Thanks,
EricOn 2/13/16, qzole <kurucz.zoltan87 at gmail.com> wrote:

mr_tawan wrote:

I almost get it compiled with Taka-No-Me’s android-cmake toolchain, after
I’ve manually changed a few generated makefile. The missing reference is
SDL_main(), which probably means the main() (I built it straight from the
code without include it to my project yet). From what I found -lpthread is
not really needed in ndk. I have to add the -lGLESv1_CM, -lGLESv2, -llog
and -landroid manually, btw.

I’ve got it compiled in Visual Studio using the MS’s version of CMake I
mentioned below as well. Using very similar method to above (without the
toolchain file). It only compiles to object file, so I think I have to
create a java project in Android Studio and put it there manually. Not
very convenience, but it works at least. I haven’t have time to test it
yet though.

IMO, if SDL is written in C90/C89 standard, the android specific part
should be written in that standard as well. At least of the consistency,
and the warning (and the flag that promote it to an error) would not have
to be turned off. I haven’t checked how the warning is added to the
makefile though. Probably in the cmake script, or may be in the toolchain
file?

One more thing, it looks like this kind of question pops up every now and
then (I searched the forum and see a number of threads). We may need to
come up with a better solution, and post it in the wiki. Don’t you think
?

For the SDL_main problem:
Even if you define SDL_main (the usual way of this is to have a standard
main function with SDL.h or SDL_main.h header included, which has a #define
to rename your main to SDL_main), you’ll get undefined reference for main
because an SDL android project doesn’t have a main, it isn’t meant to be
compiled to be an executable, but as a shared library which is loaded by
SDL’s java Activity class. I chekced M. Gerhardy’s working example and he
does the same with with a handful of CMake macros. I also think you need
that java wrapper even with MS’s solution.

I also agree that the correct fix is to apply Martin’s patch, me turning off
the warning was just a quick fix.

Yes, this information should be summed up, and it should be in the official
place, but first there should be a solution that works easily. It isn’t
really inviting if a half-baked solution is provided which needs 13 manual
steps to work :stuck_out_tongue:
Sadly it seems I won’t be able to have to much spare time in the near
future.

I just submitted a patch to make the code base C89 clean.
https://bugzilla.libsdl.org/show_bug.cgi?id=3264

This is in revision control now, thanks!

–ryan.

I’ve just tried building using CMake today, using the taka-no-me’s android toolchain file. After adding add_definitions("-DGL_GLEXT_PROTOTYPES") into my project’s cmake file, to enable the OES EXT functions used by SDL, the code is now compiles. It does fail at the linking stage. I see 3 problems here :-

  1. -lpthread is unwanted in Android. pthread library is usable even if it’s not linked against to the lib file.
  2. OpenGL ES functions is not linked to. This indicates that -lGLESv1_CM and 'lGLESv2 is not supplied to the linker.
  3. A few android specific functions are not included into the build, causing undefined reference errors.

These three could be fix manually in the generated build file (which I have already tried once). Getting this into the CMake might be a bit challenging :).

So, as an FYI, I think all these things had been addressed in my
aforementioned AndroidCMake branch.

This was the initial commit from (yikes, quite) a while back.

I had to do some merge resolution last week which I wasn’t thrilled
about, but it’s resolved (for now).

-EricOn 2/20/16, mr_tawan <mr_tawan at hotmail.com> wrote:

I’ve just tried building using CMake today, using the taka-no-me’s android
toolchain file. After adding add_definitions("-DGL_GLEXT_PROTOTYPES") into
my project’s cmake file, to enable the OES EXT functions used by SDL, the
code is now compiles. It does fail at the linking stage. I see 3 problems
here :-

  1. -lpthread is unwanted in Android. pthread library is usable even if it’s
    not linked against to the lib file.
  2. OpenGL ES functions is not linked to. This indicates that -lGLESv1_CM
    and 'lGLESv2 is not supplied to the linker.
  3. A few android specific functions are not included into the build, causing
    undefined reference errors.

These three could be fix manually in the generated build file (which I have
already tried once). Getting this into the CMake might be a bit challenging
:).

So, as an FYI, I think all these things had been addressed in my
aforementioned AndroidCMake branch.

Having not followed this conversation (sorry!)…should I pull this branch into the main repo? Is it generally useful at this point?

–ryan.

Eric Wing wrote:> On 2/20/16, mr_tawan <@mr_tawan> wrote:

So, as an FYI, I think all these things had been addressed in my
aforementioned AndroidCMake branch.

This was the initial commit from (yikes, quite) a while back.
https://bitbucket.org/ewing/sdl_androidcmake/commits/66c2d15f3abcbd84207557baa600e85574aef064

I’ve just read the commit message in the link you refer, and realized how ignorance I was :-).

I believe my changes are useful and would like to see them mainlined.
I have successfully been using them to make prebuilt SDL binaries that
I can use in projects, as well as other people using my prebuilt
binaries in their projects. This provides an alternative to embedding
the entire SDL source tree into your project and building world. Build
systems are hard, and Android is particularly bad. And I spent a lot
of time vetting the compiler switches used by the CMake toolchain to
try to match what Android wants to do natively.

But before this should be mainlined, there were some concerns brought
up by Gabriel Jacobo. I was supposed to talk to you or Sam directly,
but I got sidetracked. I wanted to have more real world cases
demonstrating how these things are used, and thus beneficial. It?s
been a long time so my memory is hazy, but I think the crux of the
concerns were my changes to decouple Android application specific
things from the libSDL core. This manifested itself first by shifting
stuff to libSDLmain. But even that has some very per-application stuff
that prevents pre-compiling a libSDLmain, so I think the second thing
was I had to suggest a convention for the user?s main application .so.
There are #ifdef concenssions to try to not break existing behavior
where you compile everything as one gi-normous blob (though they
probably need to be retested since I haven?t touched them in so long).

Anyway, I?m happy to discuss these things in more detail. I want to
make sure everybody is happy before this gets pushed in. You did
happen to catch me at a strange time. I?m trying to get SwiftAndroid
working as we speak. This potentially may stress my changes. I?m
hoping to see that everything still holds without changes.

Thanks,
EricOn 2/21/16, Ryan C. Gordon wrote:

So, as an FYI, I think all these things had been addressed in my
aforementioned AndroidCMake branch.

Having not followed this conversation (sorry!)…should I pull this branch
into the main repo? Is it generally useful at this point?

–ryan.

Any progress on this? I tried compiling SDL from gradle with cmake, but got a bunch of compile errors so I’m guessing the suggested changes were never pulled.

Now that the standard android gradle plugin supports cmake directly it would be nice to finally migrate to cmake on android too.

I tried to build the current SDL main branch also with ndk-build just to be sure the problem is when using cmake. There was a separate problem: the armeabi build was spilling a lot of strange errors when using clang (Same errors that someone was having here: https://stackoverflow.com/questions/42674298/sdl2-sample-build-error-with-android-ndk-r14). Seems that armeabi build with clang is broken at the moment.

I did a little more digging and testing on the cmake problem and I was able to build the branch by Eric Wing with a super simple gradle configuration pretty much directly from android studio. Very nice.

Just by adding something like this to my android studio generated build.gradle:

externalNativeBuild {
    cmake {
        path "../../../libs/SDL_AndroidCMake/CMakeLists.txt"
    }
}

Well. Almost. The build was still giving errors on armeabi-v7a abi:

C:\Users\xxx\AppData\Local\Temp\SDL_spinlock-745b5e.s: Assembler messages:
C:\Users\xxx\AppData\Local\Temp\SDL_spinlock-745b5e.s:53: Error: thumb conditional instruction should be in IT block -- `strexeq r3,r2,[r0]'
    clang.exe: error: assembler command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

After some quick googling I fixed it by adding a build flag “-Wa,-mimplicit-it=thumb” (don’t really know what that actually does, but I just wanted to see if things will compile). The problem with that was that android cmake integration doesn’t allow defining per abi flags. Looking at the source I figured that if I switched to GCC, instead of the default clang, that part of code would not be compiled. So by forcing GCC I was able to produce valid looking libSDL2.so and libSDL2main.so

defaultConfig {
    externalNativeBuild {
        cmake {
            //cFlags "-Wa,-mimplicit-it=thumb"
            arguments "-DANDROID_TOOLCHAIN=gcc"
        }            
    }
}

Seems that SDLs Android.mk adds “.arm” to the end of the file that is causing the error and it’s somehow forcing the file to be compiled in ARM mode instead of THUMB and it makes it work. Should the same thing be done in the cmake build? Or would adding the implicit-it=thumb flag somewhere in the SDL CmakeLists.txt do the trick?

I’m still ramping up on all the issues & shortcomings of the Android
Studio fork of CMake. Even though I’m still ramping up, I’ve already
hit quite a list of roadblocks like this one. (It’s a real shame
Google managed to ignore all the work done by both the open source
community at large on the OpenCV toolchain and the work done by the
official CMake team.)

I don’t think adding the thumb switch globally is the right thing to
do. I think it only makes sense on ARM architectures and not the x86 &
MIPS architectures.

And gcc is also not the right thing. gcc is already deprecated and
Google is trying very hard to completely remove it from the NDK.

I’m not familiar enough with thumb to know if there is another way to
approach this.

But I suspect the per-architecture flags are ultimately the right and
best solution. Even if there is a workaround for this, I suspect we’ll
eventually want those flags for other things. For example, in the
audio thread going on in the list right now, Ryan mentioned a desire
for a NEON backend for the resampler. Unless Android is automatically
making NEON switches the default now, (originally it was not because
originally Google decided to make NEON optional for the armeabi-v7a
architecture which was a terrible mistake), we would need a per-arch
switch for that.

I know Google/Android bug reports often go nowhere, but occasionally a
few get the attention of Google. Is there any traction or ETA when
they might fix this in their CMake fork?

-Eric

Yeah, reverting back to GCC is definitely not a solution. I was just testing things to get stuff to compile. Also I really have little to no knowledge on arm/thumb assembly or why the one file needs to be in ARM mode. Again I was just twiddling with things trying to get SDL to compile.

I think that the per architecture flags are not actually a problem because you can set them on the cmake side. Cmake is called separately for each abi and there are some variables passed in that you can check to see what abi is being built at the moment (https://developer.android.com/ndk/guides/cmake.html). I was just trying to do it directly from the gradle config, because I didn’t want to modify the SDL build files if possible.

There is an issue to make it possible to configure per abi options directly from gradle too: https://issuetracker.google.com/issues/37124186 but like I said, I think all this configuration should be done on the cmake side of things anyway.

But what I could not figure out is a proper way to set the arm mode on a per file basis from cmake. The only way I came up with was adding something like this to SDL/CMakeLists.txt:

if (ANDROID_ABI STREQUAL "armeabi" OR
    ANDROID_ABI STREQUAL "armeabi-v7a" OR
    ANDROID_ABI STREQUAL "armeabi-v7a with NEON")
  set_source_files_properties(${SDL2_SOURCE_DIR}/src/atomic/SDL_spinlock.c PROPERTIES COMPILE_FLAGS -marm)
endif()

The android cmake stuff is defining -mthumb for all compiled source but this adds -marm after that for that one file that overrides the earlier setting. It works but having to override the compiler options directly is not very nice.

I also took a look at the nightmare that is SDLmain. I think that it’s the biggest obstacle currently for making a sane android build env. SDLmain and the app entry point is such a pain to deal with on so many platforms that I kind of wish the whole concept could be reworked.

I looks like the Gradle side has a feature to specify arm mode instead of thumb. Have you tried flipping it to arm?

As for SDLmain and the app entry point, my branch has some changes to make the app entry point more flexible and decoupled. I have a different experiment elsewhere where I even make is overridable in the AndroidManifest.xml which I might bring over some day.

There are also fundamental changes I would like to see in SDLmain, such as a new alternative one people could opt-into that works on the main UI thread and has callback hooks similar to the iOS and Emscripten support SDL has. (The non-main thread issue creates massive headaches the moment you have to start integrating features that touch native UI, plus people currently seem to hit nasty edge case life-cycle bugs with the current background/resume/quit stuff.)

But fundamentally, the concept of SDLmain can’t really go away. Because Android treats the native side as a second class citizen and all apps must originate in Java, there is no real alternative for this.

What things did you have in mind to fix/rework SDLmain?

Maybe I haven’t really thought this though, but if I was starting from scratch I’d maybe dump the whole separate SDL_main library and do something a lot of header only libraries do: basically the user would define something before including sdl in EXACTLY one source file and the include would add the appropriate entry point code there. So on windows a WinMain would be inserted to that file and on android a jni callback and so on.

Usage would be something like:

#define SDL_ENTRY_POINT
#include <SDL.h>

int SDL_Main(int argc, char **argv) {
    return 0;
}

I’d also probably drop abusing int main(int argc, char **argv) because the redefinition seems to just add confusion and I don’t really see the benefit in it.

Now that I think of it, this kind of system would probably be possible to add in addition to the current stuff. So you would just not link to SDL_main if you defined the entry point already like above.

I tried but I don’t think it can be used to change the type for individual files. I created an issue about this: https://issuetracker.google.com/issues/62264618

I cleaned up my testings a bit and put it on github if you want to check it out.

Basically my goal is to create a simple and clean cmake based SDL project template that is crossplatform without so much hassle to setup for each platform.

1 Like

Actually, I was suggesting you try building everything under ARM instead of Thumb.

I kind of doubt SDL is getting any significant benefits from thumb anyway.

I took a stab at fixing SDL CMakeLists to work with android. I looked at the changes in your fork, but decided not to try to merge those back to the current SDL also partly because there already were some related fixes there.

Also I was thinking that maybe the changes could make it to 2.0.6 and maybe it’s better to not do any bigger changes to handling the SDLmain stuff for now to have a better chance at getting the fix pulled and getting at least something working in.

I’d appreciate if you or somebody who has been using cmake with SDL and android took a look if the changes look OK. Mainly because I haven’t used cmake to build android without gradle so I don’t know if the changes would cause any problems to that approach. The current official SDL version was compiling Android_main.c as part of SDL2.so and just had a dummy SDLmain. I’m not sure what the reason for that was, but I changed it and I didn’t see any linking problems.

I updated the github test project linked earlier to use this patched SDL version:
https://github.com/suikki/simpleSDL/blob/master/contrib/android_fixes.patch