[GHC] #10324: our rts/ghc-prim/base shared library tricks don't work on Android
GHC
ghc-devs at haskell.org
Sat Apr 18 16:20:41 UTC 2015
#10324: our rts/ghc-prim/base shared library tricks don't work on Android
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: feature | Status: new
request | Milestone:
Priority: low | Version: 7.10.1
Component: Compiler | Operating System: Other
Keywords: | Type of failure: None/Unknown
Architecture: | Blocked By:
Unknown/Multiple | Related Tickets:
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
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.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10324>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list