Don't version shared libraries on Android.
authorJonathan Pryor <jonpryor@vt.edu>
Wed, 5 Dec 2012 04:08:44 +0000 (23:08 -0500)
committerJonathan Pryor <jonpryor@vt.edu>
Wed, 5 Dec 2012 04:08:44 +0000 (23:08 -0500)
Wanted: profiler support on Android. ;-)

...which seems sane enough: we have this nifty pluggable profiler
mechanism already, we have profilers built as separate shared libs
(e.g. libmono-profiler-log.so), let's just "somehow" load one, call
the init function, and we're off to the races, right?

void* h = dlopen ("path/to/libmono-profiler-log.so", RTLD_LAZY)
// h == null; dlerror() is:
//    Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library
//    "libmonosgen-2.0.so.0" needed by "libmono-profiler-log.so"; caused by
//    load_library(linker.cpp:745): library "libmonosgen-2.0.so.0" not found

Ouch. So the problem is that libmonosgen-2.0.so contains a versioned
SONAME ("libmonosgen-2.0.so.0"), and thus libmono-profiler-log.so
contains a versioned SONAME reference, which cannot be resolved.
(Android doesn't allow versioned .so's to be placed within .apks.)

Fix the first: make libmonosgen-2.0.so unversioned. That way,
libmono-profiler-log.so contains an unversioned library reference, and
Android is appeased!

(Unversion libmono-profiler-log.so for good measure.)

Fix the second: with the above fix in place, libmono-profiler-log.so
SITLL won't be loaded, with dlerror(3) reporting:

Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate
symbol "monoeg_g_log" referenced by "libmono-profiler-log.so"

The issue here is that libmonosgen-2.0.so contains unexported symbol
references from eglib, e.g. monoeg_g_log(), and dlopen() won't use
those unexported symbols. So just add the glib link references to
libmono-profiler-log.so, and everything is kosher. Yay.

mono/mini/Makefile.am
mono/profiler/Makefile.am

index 8ebf01aa0dfad413c5b10643bfae801eee4eed0d..f4e6a71804e9417ee4bd9015c00ece2a761d9c31 100644 (file)
@@ -547,6 +547,10 @@ libmonosgen_2_0_la_SOURCES =
 libmonosgen_2_0_la_CFLAGS = $(mono_sgen_CFLAGS)
 libmonosgen_2_0_la_LIBADD = libmini.la $(sgen_libs) $(LIBMONO_DTRACE_OBJECT)
 
+if PLATFORM_ANDROID
+libmonosgen_2_0_la_LDFLAGS = -avoid-version
+endif
+
 if MOONLIGHT
 libmono_moon_la_SOURCES = $(libmini_la_SOURCES)
 if MOONLIGHT_BOEHM
index c69c8dbcae583bbe43fe4f2dc0b78325e08b2ebf..a6f029ab59049bd9db9348715527bbd936609c9b 100644 (file)
@@ -17,6 +17,9 @@ lib_LTLIBRARIES = libmono-profiler-cov.la libmono-profiler-aot.la libmono-profil
 if PLATFORM_DARWIN
 libmono_profiler_log_la_LDFLAGS = -Wl,-undefined -Wl,suppress -Wl,-flat_namespace
 endif
+if PLATFORM_ANDROID
+libmono_profiler_log_la_LDFLAGS = -avoid-version
+endif
 endif
 endif
 endif
@@ -57,6 +60,10 @@ libmono_profiler_iomap_la_LIBADD = $(LIBMONO) $(GLIB_LIBS) $(LIBICONV)
 libmono_profiler_log_la_SOURCES = proflog.c
 libmono_profiler_log_la_LIBADD = $(LIBMONO) $(Z_LIBS)
 
+if PLATFORM_ANDROID
+libmono_profiler_log_la_LIBADD += $(GLIB_LIBS)
+endif
+
 mprof_report_SOURCES = decode.c
 mprof_report_LDADD = $(Z_LIBS)