[Top][All Lists]

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

Re: Live GNUstep Android game ( Golf Blitz )

From: David Chisnall
Subject: Re: Live GNUstep Android game ( Golf Blitz )
Date: Tue, 7 May 2019 09:53:27 +0100
User-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1

The build system is a constant source of pain for people trying to use GNUstep. It's very easy to use if you are making a GNUstep project, but it is a huge pain if you are either:

- Making a project that uses GNUstep.
- Making a project that uses GNUstep and XCode on Mac / iOS.

With the exception of FreeBSD (which has a truly horrible build system based on BSD Make that has gradually accreted over several decades), every other project that I work on uses CMake as the build system.

CMake can generate XCode project files (and Eclipse, Visual Studio, and a bunch of other things). It can also generate ninja files for fast parallel builds and emit json compilation databases for all of the clang tools to work with. CMake isn't great, it's just the least bad of the alternatives.

A few things that are easy with CMake + CTest that are part of my normal workflow everywhere else and are really hard with GNUstep:

- Building all of the tests so that I can run just the one that failed.

- Doing a 32-way parallel build of all of the tests, so my CPU cores are busy building the tests.

- Building multiple different combinations of tests (the runtime's tests are almost all built with both ABIs and with -O0 and -O3).

- Running 32 tests in parallel. The libobjc2 test suite contains a few hundred tests and completes in around 5 seconds on my desktop. On the CI machines, which have 4 cores, it takes 10-21 seconds doing a 4-way parallel test (30 seconds on the FreeBSD tests, but that's on Cirrus CI, which is slower than Azure Pipelines). One of the tests uses a LOT of memory, so it is marked to make sure that different configurations of it do not run in parallel with each other.

- Generating IDE project files so I can run refactoring tools in a GUI.

- Building with Ninja, so I get a parallel build of the entire project that uses all of my cores.

- Building multiple configurations from a single source checkout. I typically have a release, debug, and debug + ASan build for things I'm working on. I'll use a release build for basic feature testing (because the tests run faster), switch to Debug when things go wrong, and use Debug + ASan if it looks as if there's a memory management issue. With CMake (and any vaguely modern build system), the build is driven from the object directory and the configuration is stored there, so it's easy to have a separate build directory for each one. GNUstep's build system doesn't even allow out-of-tree builds (though autoconf + GNU Make do).

- CI reporting for the test suite. Systems like Jenkins have support for parsing JUnit XML or similar formats to report the tests passing / failing over time. CTest doesn't generate this natively, but there's an XSLT that will translate XTest output to JUnit XML, so you can see graphs of the number of tests succeeding and failing over time.

- Reconfiguring the build in a tool designed for humans (CMake has a curses interface and X and Windows GUIs that show each of the configuration options and some help text. If I want to toggle something on or off in a build, I run cmake (or cmake-gui on Windows), use the search function to find the option, toggle it, and my build is now reconfigured. IDEs increasingly have native support for this built in, so you don't even need a separate tool if you live in an IDE.

I still write code in vim and build on the command line, but I am very much aware that this puts me in a minority. Most developers now use IDEs and expect a lot of the surrounding tooling to work and GNUstep Make is a significant impediment to this.


On 06/05/2019 23:37, Jordan Schidlowsky wrote:
Thanks Ivan!  So, many thoughts on this...

First off, I'd start with cross-compilation.  In the industry I work in, the deployment platform is generally not the development platform.  ( Actually it seems like a general 'open computing platform' is getting harder to find as a lot of platforms are becoming more and more locked down ).  I suspect this won't change, and Android, iOS, Fuchsia, Switch, etc, will continue to be platforms that aren't suitable for development, but require deployment to.  The GNUstep make/build, although capable of being cross compiled, definitely feels like a process that is designed for deployment on the development platform.  I sometimes felt like the build environment, and test suites could be 'modernized'.  I'm not sure how, and I'm not a build tools guy by any means, but it just feels like my industry is moving completely towards different environments for development and deployment, (with deployment platforms being VERY locked down).  libobjc2 was pretty simple to integrate, with the exception of the tests (which I still haven't found an easy way to easily run them on platform).

The main hardships and trouble points with getting GNUStep running on Android is somewhat of a loaded question.  The main issues arise from what parts of Foundation are generally language related (objc) and what parts are platform related (NSBundle, NSUserDefaults for example).  To me, this is actually one of the biggest problems of the ObjC language, and probably has contributed to it's lack of widespread adoption.  I know there are other projects like ObjFW, that basically duplicate a ton of existing data structures, when it really shouldn't be necessary.  If some kind of small standard library for ObjC existed that was NS* compatible it would be quite useful without having to 100% commit to all the other platform stuff.  IMHO I think Foundation should have be split into two frameworks: language classes, and platform classes.  And if there isn't a clear division in some scenarios the platform specific stuff should be taken out and implemented as categories in another framework  (just my 2 cents).

In our games we do a TON of UI work...  Like a massive amount...  To the point where the UI code is probably 95% of the codebase and the actual game logic is maybe 5-6%.  ObjC is a pretty nice language for UI work, as there's just so much you can do with dynamic dispatch that you can't do with a statically dispatched language.  Refactoring, adaptability, forwarding,  runtime introspections, memory profiling/debugging, there's just a whole bunch of issues that are much easier to deal with and adapt to if you are willing to sacrifice a few cycles here and there.  IMO UI code is one of these areas.  Menu's, windows, scenes, buttons, layers, etc, all benefit from this immensely.  Our game logic, which needs to be super fast, is written in c++ and c.

But anyways, ya, shoe horning the platform specific stuff in GNUStep onto android is probably the hardest part...   A prime example is NSBundle.  Applications on android are basically zip files, who's assets are generally inflated on the fly, so there's just no clean way to adapt the NSBundle API on Android.  For example how do you express 'pathForResource' within a filesystem AND within a zip file?  It just doesn't work without ugly, ugly hacks, and it really shouldn't work because fundamentally they are different platforms and do things differently.  Our solution to most of these issues is to just not use the API, which is generally manageable for games because games really just require a thin wrapper around IO, display/sound.  Of which we use a VERY thin UIKit wrapper for input, and OpenGLv2 rendering which is already cross platform for the most part, which means we really are only using a small subset of GNUStep.

Android IDE support is also not great.  And actually this is one of the few things I like about CMake, because it can generate various backends for your projects (one of which is Xcode).  But basically you have to end up using Android Studio or XCode at some point if you want to ship on iOS or Android, so having a build process that can generate those project files as a backend is quite nice.  We use most of GNUStep and all dependencies to CMake so we could have the whole stack in Android studio so we can do a 'one-click' build/deploy/run/debug.  This allows one to quickly and easily edit & debug (within the IDE which is quite nice) stuff in libdispatch, or libffi, compile and run with address-sanitizer, or whatever really...  With things not really being stable on that platform this was kind of a must.  The biggest annoyance is Android Studio not having language support for ObjC.  I'm not sure what it's using for c/c++ syntax, libclang, or clangd, or what, but ObjC is definitely not supported.  This leads to a mild annoyance, but we usually just develop in XCode and then update/compile/run in Android Studio.  At least we have debugging support within Android Studio, which is very nice.

Anyways, I could probably rant on for hours on the subject, but those are some of the main pain points for us getting stuff running on Android!   Also all our development has also been done on Macs.  No linux, or BSD development machines in the office.

On May 4, 2019, at 9:35 AM, Ivan Vučica <address@hidden <mailto:address@hidden>> wrote:

Congrats! Really happy to hear about this!

Beyond putting together a new build process, what would you point at as the most troublesome part in getting cocos2d-based software running with GNUstep-on-Android?

On Sat 4 May 2019 at 14:18, Jordan Schidlowsky <address@hidden <mailto:address@hidden>> wrote:

    Hey all, just wanted to share with everyone on the list we FINALLY
    launched our Android game built on GNUstep, Golf Blitz.   It of
    course has an iOS counterpart but the Android build is built on
    top of GNUstep.   If you have an android device you can find it
    easily in the Google Play store by searching for "Golf Blitz",
    it's free.  It's a quite strange multiplayer golf game...

    Some highlights:

    Runtime: gnustep-runtime-1.9
    Arch: armv7a softfp
    Graphics: GLESv2, cocos2d
    Uses blocks, arc, and libdispatch heavily.  Libdispatch isn't
    built into any runloop and we kinda bootstrap the apps main thread
    onto a java render thread...  We also just drain the main dispatch
    queue manually and the start of our game loop.
    Libs-base version:   9bcef37ae0bdf2ce5a1baacac2a3288cb39e2f03
    Cloud game servers:  Google cloud

    Next up on my todo list is the get the game running on the 2.1
    runtime (thanks David for all your work!), as Google has a
    requirement that all new game updates have to be built as arm64
    binaries by August.   I definitely will be able to provide a
    decent amount of testing for that runtime and arch.

    Discuss-gnustep mailing list
    address@hidden <mailto:address@hidden>

Sent from Gmail Mobile
Discuss-gnustep mailing list
address@hidden <mailto:address@hidden>

Discuss-gnustep mailing list

reply via email to

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