[Interest] Qt5, XCB and X11

Till Oliver Knoll till.oliver.knoll at gmail.com
Fri Jul 11 17:37:12 CEST 2014


Thanks for clarifying!

Am 11.07.2014 um 16:29 schrieb Andreas Pakulat <apaku at gmx.de>:

> Hi,
> 
> On Fri, Jul 11, 2014 at 2:47 PM, Till Oliver Knoll <till.oliver.knoll at gmail.com> wrote:
>> ... by encoding "version info" into their libs, such as libfoo.0.4.2.so – but most apps simply don’t care about linking with –lfoo.0.4 (or whatever the syntax would be), so they’d also happily link with a libfoo.0.5.0.so, which in the best case might be binary compatible, but otherwise behave differently and *bang*! There you go: "Shared Objects Hell"!
> 
> While I agree that you can end up in the same dll-hell on Linux or other ELF based systems, this paragraph is largely wrong. First of all, during linking you either specify the absolute path of the library you want to link to or you just specify the name (the foo part in libfoo.so).

Hmmm, interesting! So how would you specify an absolute path then?

Usually I have in my *.pro file (ignoring for now symbolic links and "file name versioning" for simplicity's sake):

  LIBS += -L/some/non/default/library/path -lfoo

which I understand is still a relative path, right? The -L option merely gives a "hint" to the linker where to look for the "libfoo.so" at /link/ time, whereas at runtime the "libfoo" would be taken from wherever found first (according to default library locations such as /usr/lib/, LD_LIBRARY_PATH, "RPATH" etc.) - or so I thought...

Would the following result in an absolute path which would also be encoded in the binary?

  LIBS += -l/some/non/default/library/path/libfoo.so

would that be a valid syntax?

> .... This single-number filename is also whats stored in the application executables or shared libraries linking to libfoo.

I wasn't aware of that! I always thought that at runtime, if an application had simply linked against "libfoo.so" (which yes, is a symbolic link to e.g. libfoo.so.1 which again might be yet another symbolic link to libfoo.so.1.2 ("version 1.2") then the runtime linker would simply follow all symbolic links, and if those ended up at, say libfoo.so.1.4 - or even libfoo.so.2.3 - then /that/ would be the library linked against (at runtime).

But from what I understand is that only the major version ("1.x", "2.x") is encoded into the binary (because that is the one supposed to indicate "binary incompatibility"), such that in the above example my application would still accept libfoo.so.1.4 (even when originally linked against 1.2), but not libfoo.so.2.3 - is that what you're saying? Or is also the "minor" (and possibly "sub-minor") version number encoded into the binaries?

> The dynamic linker will use that one for resolving the symbols and only that one. If there is a libfoo.so.2 and a libfoo.so.1 an application that was compiled and linked against libfoo.so.1 will never get  libfoo.so.2

... but would it accept a libfoo.so.1.4, even when originally linked against a libfoo.so.1.2 (same question as above)?



For completeness sake, OS X ("Mac") takes this even a step further: every library has its own absolute path encoded as "ID" (it can also contain "@executable_path" such as to deploy it in an "App Bundle" relative to the actual executable, and every binary trying to link to that library must again refer to that same absolute path (again, @executable_path to the rescue).

Like this it is simply not possible to "accidentally" link to any other library in the system, no matter what its path, version or name is!

It takes some nasty fiddling around with the "install_name_tool" ("macdeployqt" greatly helps!), but so far this seems to be the best and most robust way I've seen to avoid the "DLL Hell" (except off course if Apple decides to update their system libraries in some "unforeseen way" ;)).


Cheers,
  Oliver
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20140711/9e259e76/attachment.html>


More information about the Interest mailing list