[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Android (Was: Cross-compiling GNUstep?)

From: Doug Warren
Subject: Re: Android (Was: Cross-compiling GNUstep?)
Date: Mon, 30 Dec 2013 08:32:54 -0800

Nice work Ivan, some other thoughts from going through the same thing:

NativeActivity may be different, but in my case the thread that called LoadLibrary is not used for me any more after that.  This causes NSThread MainThread to never be used though is set.  

It would be nice to hook the activity through NSRunLoop, we never did and just worked around it with categories where it was an issue.

What did you need API 14 for?  We currently have API8 supported in the store.

Now would also be a good time to mention imp_implementationWithBlock() requires filesystem access and assumes that you can call getEnv("TMP") to get the write directory.  I think someone here reimplemented it as mmap/mprotect but I haven't had a chance to check on it yet.

On Sun, Dec 29, 2013 at 4:51 PM, Ivan Vučica <address@hidden> wrote:
Hi all,

(David, please take a look below)

I've sit down tonight and got gnustep-base to run under Android. The hardest part is having to manually load the dynamic libraries; apparently Android's is dumb enough to fail miserably when it has to (oh shock and horror) load a library that the .so containing native depends on.

(For those who don't know, Android applications cannot be written purely in native code. Even NativeActivity class, introduced relatively late and used primarily for games, is code written in Java that loads a shared object library and calls native code at appropriate times.)

Native code on Android in any non-console application is delivered as an .so. If it shows up on screen, it's not a standalone ELF executable. Simple as that. Hence the modus operandi is this: Application is always written in Java. Java code uses JNI to load an .so. Java code then calls C functions as appropriate. Native code may call back into Java. 

-- Where was I stuck?

When it comes to usual GNU/Linux systems, libobjc2 is a good behaving citizen that specifies soname in the form of ""; when it comes to Android systems, libgnustep-base is a better behaving citizen that specifies so name in the form of "". On regular systems, end user may not notice, as both are shipped as "" and symlinked into "". libobjc2 follows the recommendations, though, and libgnustep-base does not.

Doesn't really matter on Android, as the requirements are completely opposite; if you put a binary in "...apkroot/lib/armeabi" and it doesn't have the extension .so, it won't get shipped. Dynamic loader will choke when trying to load which references to libobjc2 based on its soname; same for


The hack that I found online, where I edit and to replace "" with "\0\0\0\0" is just that - a hack. 

Can you look into the best way to force CMake to pass -soname to the linker, but just on Android? I have a CMake toolchain file for Android, but I'm unsure how to specify that the version number should not be suffixed on Android.

-- So, what does the .apk that I have do?

Nothing much:
  NSString * hello = @"hello";
  LOGI([hello UTF8String]);
which is just enough to see the output in Android's "logcat".

-- Where is the updated script to build gnustep-base for Android, and where is the demo application?

In private Bitbucket repositories. While I'm looking forward to approval to release relevant code from my employer, I'll stay cautious. When/if I get the approval, I'll push the updated code into publicly available repositories.

Publicly available code:

First repository contains non-up-to-date code to fetch Android SDK and NDK, create standalone toolchain, fetch gnustep-make, gnustep-base and libobjc2, patch gnustep-base appropriately, build and "install" libobjc2, gnustep-make and gnustep-base.

Second repository demonstrates how to build an Android application without having to use the Android build system. Sadly, it has a lot of hardcoded paths, and Windows paths at that. Updated version still has a lot of hardcoded paths, but at least they're under Linux (and match the .../gnustep-android paths).

-- What did I have to do?

I'll describe the updates to gnustep-android repo, in case approval doesn't come or someone wants to upstream the changes.

First, since the two patches that I had were not applying cleanly, I removed them. Maybe relevant fixes, relating to 'daylight' and 'dladdr branch in objc-load code' are upstream already.

Second, -base's SSL subdirectory was being used even when --disable-openssl was passed. Worse, when its configure was called, it did not receive the same flags as the root configure, so it was throwing errors around. This has been fixed by introducing ENABLE_OPENSSL variable in a couple of places (as opposed to HAVE_OPENSSL, since this relates solely to flag being passed; it is my understanding that further detection is being done in the SSL/ directory's configure) and slightly cleaning up the relevant part of <- This introduced patch numbered 03.

Third, -base's make install failed because gdomap could not be built. As it is useless for Android anyway, in case Android is being targeted (GNUSTEP_TAGET_OS linux-androideabi), no longer is subproject Tools appended to the appropriate library. Neither are NSTimeZones, Resources and Tests; solely because it makes little sense to build anything relating to resources or to run tests while cross compiling. On Android, we'll have to deal with any resource loading in a different way, anyway, so whatever is in Resources/ and NSTimeZones/ can be skipped for now.  <- This introduced patch numbered 04.

Fourth, to make thegrandexperiment work, I've switched to android-14. (android-8 doesn't include EGL/ headers, it seems.)

Those were changes to gnustep-android. What changed in thegrandexperiment?

Linux code path was added to Makefile. If TEST_OBJC=true, Makefile uses objcopy with strip argument to copy, and into apk/lib/armeabi. Tool called "rpl" is used to replace .4.6 with \0. Class TGENativeActivity, subclass of is introduced, empty except for static {} section to load libraries objc, gnustep-base and TheGrandExperiment, so everything is ready by the time kicks off.

-- What next?

These are all changes that'd be dumb to replicate, so I'm looking forward to hearing from whoever I need to get approval from. Everything was done in my spare time, so I hope there won't be any issues. It's worth noting that patches for gnustep-base itself are rather small.

On Sun, Dec 29, 2013 at 12:56 PM, David Chisnall <address@hidden> wrote:
Hello everyone,

I'm trying to cross-compile GNUstep, and since I'm sure I'm not the first person to try this, I wondered if anyone had written up how to do it?  I am trying to build from FreeBSD/amd64 for FreeBSD/MIPS64.  I have a cross-compiler and sysroot setup.  Building the runtime was trivial - just point cmake at the cross-compile toolchain file - what do I need to do for Make / base so that:

- It knows that I don't actually want -make on the target platform.
- I get an installed version somewhere on my local machine that I can copy to a different location on the remote
- All of the correct cross-compile flags are passed to the compiler

I think Ivan has been through all of this recently for Android?


This email complies with ISO 3103

Gnustep-dev mailing list

Ivan Vučica

Gnustep-dev mailing list

reply via email to

[Prev in Thread] Current Thread [Next in Thread]