On Thu, 2013-07-25 at 00:11 -0300, Jo?o Paulo Rechi Vita wrote: > On Jul 18, 2013 10:32 AM, "Tanu Kaskinen" <tanu.kaskinen at linux.intel.com> > wrote: > > So there will be bluez4-util.so and bluez5-util.so, and those will > > contain identical symbols. It's possible to load both bluez 4 and 5 > > modules at the same time, so the bluez*-util libraries will conflict in > > a way that will cause crashing or weird behavior. Since we lost the > > opportunity to have a shared Bluetooth core for all backends, I think it > > would be OK to change the generic "pa_bluetooth" prefix (and "pa_bt", if > > it's still used somewhere) to "pa_bluez5". That would resolve the symbol > > conflict between the two libraries. > > > > Good catch, I haven't thought about this problem before. > > > Another, perhaps easier solution would be to use symbol versioning in > > the libraries. I'm not 100% sure that this works, but I think it should > > work. > > > > How does it works? I have never done or seen it anywhere. We use symbol versioning for libpulse. We have this in configure.ac: # Check whether the linker supports the -version-script option. # The Make variable $(srcdir) needs to be in the LDFLAGS in that form, # so that it is expanded the right way in every subdir. AX_CHECK_LINK_FLAG(["-Wl,-version-script=${srcdir}/src/map-file"], [VERSIONING_LDFLAGS='-Wl,-version-script=$(abs_top_srcdir)/src/map-file']) AC_SUBST([VERSIONING_LDFLAGS]) So the -Wl,-version-script=foo is what tells the linker to use symbol versioning. In Makefile.am we use VERSIONING_FLAGS like this: libpulse_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_VERSION_INFO) and libpulse_simple_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_SIMPLE_VERSION_INFO) and libpulse_mainloop_glib_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO) The contents of src/map-file are as follows: PULSE_0 { global: pa_ascii_filter; pa_ascii_valid; pa_bytes_per_second; pa_bytes_snprint; pa_bytes_to_usec; pa_channel_map_can_balance; pa_channel_map_can_fade; ... local: *; }; All public functions are listed under "global:", and "local:" matches everything else. Functions marked as local are usable by the shared library itself only, they aren't linkable from outside. PULSE_0 is the namespace or "version" for the listed functions. In case of bluez*-util, the namespace would be different for the two libraries, which hopefully would cause the linker to distinguish between the two sets of symbols. I don't know any way to check the version information of linked symbols of a running executable, so the only good way to verify that this actually works would be to run pulseaudio with both bluez 5 and bluez 4 modules loaded, and swap the bluetoothd version while pulseaudio is running. If pulseaudio is able to stream audio to a headset regardless of the running bluetoothd version, then the symbol versioning is working. I would prefer changing the symbol prefix from pa_bluetooth to pa_bluez5, because it's simper and more fool-proof, but if you choose to implement symbol versioning instead, that's acceptable to me. -- Tanu