[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