2

I have a situation more or less as illustrated here; it exists both on Windows and Linux, but I’ll draw it using Linux notation which is slightly clearer: enter image description here

libbar.so.1 and libbar.so.2 contain procedures with the same names and signatures but different behaviours. If I link the applications ‘naïvely’, then symbols from the library that is loaded last will ‘hide’ the ones from the one that is loaded first (at least, if I understand this reference correctly) and I have no way of using both libraries at the same time nor determining which library’s symbols actually get used on the day.

Certainly, the error messages I’m getting at runtime are consistent with this mental model.

Now, if I could recompile all the libraries, then as described in the reference I could use the –default-symver option (at least when compiling with and linking with gcc) to disambiguate fully the symbols from each library, and force libfoo.so to look for the function baz@@libbar.so.1 and the application to look for the function baz@@libbar.so.2 with no ambiguity.

What, though, if I can only recompile my application and libbar.so.2? Will libfoo.so ignore the function baz@@libbar.so.2, or will it look no further than the baz part of it and, potentially, still use it instead of the one in libbar.so.1?

It’s a full cross-platform application so I have exactly the same issue to address on Windows. Here, I have an inkling that I may be able to use the SxS mechanism as the situation isn’t all that different from, say, having an application compiled in VS2019 that links to a library compiled in VS2013; so that the application would need to link to one version of the runtimes and the library would need to link to the other. But whilst I know how to handle this with system libraries, I’m less sure how to proceed with other libraries.

Eos Pengwern
  • 1,467
  • 3
  • 20
  • 37
  • I guess you have already considered using `namespace`. You could then indicate why it is not an option for you. – Damien Sep 21 '20 at 08:01
  • Moving `libbar` into a different namespace would definitely be the simplest cross platform solution – Alan Birtles Sep 21 '20 at 08:51
  • The terms to google is "make two versions of same library coexist". – rustyx Sep 21 '20 at 09:14
  • 1
    @Damien If these were my own libraries then namespaces would definitely be the way forward. In this case, the two 'libbar' are actually two different versions of Python, and I'm hoping to avoid making changes to the Python source code that are too wide-ranging - at least not until I've exhausted any possibility of solving this using just compiler flags. – Eos Pengwern Sep 21 '20 at 12:27
  • Windows DLL machinery is actually completely different from Linux. There shouldn't be any problem using your libraries on Windows as is, provided they have different names. You shouldn't need SxS for this. – n. m. could be an AI Sep 21 '20 at 12:53
  • 1
    As for Linux, you might be able to to build your libbar.so.2 with -Bsymbolic and load it dynamically with dlopen and RTLD_LOCAL flag, this way it will keep its symbols completely separate from symbols of other shared libraries. – n. m. could be an AI Sep 21 '20 at 12:59
  • @n. 'pronouns' m. I hand't heard about that option before and it looks very promising. I'll try it out and report back in a few hours. – Eos Pengwern Sep 21 '20 at 13:11
  • @n. 'pronouns' m. OK, more than a few hours. It's dawned on me how big a recompilation this is going to be; in my case 'libbar.so.2' is actually libpython2.7.so.1.0, and if I recompile that then it will affect a cascade of other things that also depend on it. I'm also wondering whether the use of a linker script may be a better option than -Bsymbolic; Intel certainly recommends that approach: https://software.intel.com/content/www/us/en/develop/articles/performance-tools-for-software-developers-bsymbolic-can-cause-dangerous-side-effects.html – Eos Pengwern Sep 22 '20 at 11:12
  • @n. 'pronouns' m. A naive question, perhaps; but is -Bsymbolic necessary if I use dlopen with RTLD_LOCAL | RTLD_DEEPBIND. On the face of it, the latter option has the same effect by ensuring that the library being loaded will give precedence to its own symbols rather than pulling in predefined symbols from outside? – Eos Pengwern Sep 23 '20 at 12:42
  • 1
    Yes I think using RTLD_DEEPBIND is better than -Bsymbolic, I just forgot about this option. – n. m. could be an AI Sep 23 '20 at 13:16
  • @n. 'pronouns' m. I've more or less concluded that any solution based on dl_open isn't going to work in this specific case, at least not without a cosmic amount of rewriting. Since, in my case, 'libbar.so.1' and 'libbar.so.2' are different versions of libpython, 'libbar.so.2" is linked not only from the main application from also from many other C++ libraries that have been wrapped using either SWIG or Shiboken (depending on whether they use Qt or not), which expect to use the symbols defined in without any indirection. I'll see if I can try out -default-symver instead, – Eos Pengwern Sep 23 '20 at 23:13
  • If libbar.so.2 is Python 2.7, it is inevitable that you will need to rework, abandon, or freeze *everything* that relies on it, rather sooner than later. – n. m. could be an AI Sep 24 '20 at 09:54

0 Answers0