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 android.app.NativeActivity 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 "libobjc.so.4.6"; when it comes to Android systems, libgnustep-base is a better behaving citizen that specifies so name in the form of "libgnustep-base.so". On regular systems, end user may not notice, as both are shipped as "libXYZ.so.A.B" and symlinked into "libXYZ.so". 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 libgnustep-base.so which references to libobjc2 based on its soname; same for libAPPNAME.so. David: The hack that I found online, where I edit libgnustep-base.so and libAPPNAME.so to replace "libobjc.so.4.6" with "libobjc.so\0\0\0\0" is just that - a hack. Can you look into the best way to force CMake to pass -soname libobjc.so 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: http://bitbucket.org/ivucica/gnustep-android http://bitbucket.org/ivucica/thegrandexperiment 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 configure.ac. <- 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 libobjc.so.4.6, libTheGrandExperiment.so and libgnustep-make.so into apk/lib/armeabi. Tool called "rpl" is used to replace .4.6 with \0. Class TGENativeActivity, subclass of android.app.NativeActivity is introduced, empty except for static {} section to load libraries objc, gnustep-base and TheGrandExperiment, so everything is ready by the time android.app.NativeActivity 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 <thera...@sucs.org> 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? > > David > > -- > This email complies with ISO 3103 > > > _______________________________________________ > Gnustep-dev mailing list > Gnustep-dev@gnu.org > https://lists.gnu.org/mailman/listinfo/gnustep-dev > -- Ivan Vučica i...@vucica.net
_______________________________________________ Gnustep-dev mailing list Gnustep-dev@gnu.org https://lists.gnu.org/mailman/listinfo/gnustep-dev