our rts/ghc-prim/base shared library tricks don't work on Android
I experimented with building dynamically linked executables on Android, and figured I should record my findings somewhere. (I'm interested in dynamic Haskell libraries because I'd like to eventually get ghci on Android, though obviously that would also require a bunch of packaging work!)
Building a GHC with dynamic library support was no major problem, and I could build a dynamically linked "Hello, world" executable too. The problem arose when trying to actually run the executable: I got a message to the effect that there were unresolved symbols (that live in libHSrts) when loading libHSbase.
I tried relinking the executable to put libHSrts before libHSbase in the list of NEEDED shared libraries, and now I instead got an error about missing symbols (that live in libHSbase) when loading libHSrts.
I then tried rebuilding libHSrts against libHSbase... and then I got the first error again, about missing symbols (that live in libHSrts) when loading libHSbase, while loading libHSrts.
I didn't try also rebuilding libHSbase against libHSrts, because at that point the base library would be dependent on the RTS flavor, which we don't really want.
It appears based on these tests that the Android dynamic loader only looks for missing symbols in a shared library in the dependencies of that library in a depth-first fashion, while the Linux ld.so seems to do something more like loading every (direct and indirect) dependency of the executable first and then resolving symbol references between them all at once.
I didn't fully characterize the Android loader behavior though, and it's possible that if we could remove the references from libHSrts to libHSbase and libHSghc-prim, then we could list libHSrts first among the dependencies of an executable, and hopefully once libHSrts has been loaded, the loader would then use its symbols to resolve references when loading the libHSghc-prim and libHSbase libraries, even without those libraries having NEEDED entries for libHSrts. Removing the references from libHSrts to libHSbase/libHSghc-prim should be fairly mechanical if we can use constructors in the latter libraries (basically emulate dynamic linking by adding a global variable to libHSrts which is a struct holding the addresses of the base/ghc-prim symbols it needs, and have constructors in those libraries fill in those addresses on load).
If that doesn't work, another possibility may be to statically link libHSrts (or whatever part of it we need) into the executable and export libHSrts's dynamic symbols so that they can be used by libHSghc-prim (or other Haskell libraries). I also haven't tested whether this kind of mutual recursion between an executable and its shared library dependencies works on Android.