[Interest] Qt5, XCB and X11

Andreas Pakulat apaku at gmx.de
Fri Jul 11 20:52:45 CEST 2014


Hi,

On Fri, Jul 11, 2014 at 5:37 PM, Till Oliver Knoll <
till.oliver.knoll at gmail.com> wrote:

> 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...
>

I'm not really using qmake, but I'd try:

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

Assuming that qmake just passes this to g++/ld that'll work fine. No extra
flags or anything are needed for that. This does have a side-effect though,
the absolute path is going into the executable too. I'm not sure right now
how thats usually handled (usually cmake takes care of this kind of thing
for me), but there are ways to make such binaries relocatable (search for
rpath, runpath and $ORIGIN).


> .... 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"),
>

As I said, not necessarily the major version. There are projects which
increase their soversion within minor releases. The important thing is that
they increase it whenever the library changes its binary interface (for C
this usually means removing or changing existing functions, for C++ things
get more complicated). Vice versa a project may do a new major release but
not change the soversion if the library API has not changed.


> 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?
>

Never looked at the sources of ld (or other linkers for Linux/ELF), but my
understanding is that it reads the library you link to, which is usually
libfoo.so (resolving symlinks) and reads out the soversion from that file.
Then it writes to the binary that it is currently linking
libfoo.<soversion> as the library to be loaded during runtime. When the
binaryso it  is later on loaded the dynamic linker looks at the table of
dependencies and tries to find the files on disk. It'll find
libfoo.so.<soversion> and try to open it to read the symbols from it. If
libfoo.so.<soversion> is a symlink the OS will transparently open the
target file, the linker does not even know this happens.

It really does not matter wether the actual file is called libfoo.so.2.3,
libfoo.so.1.4 or clowns.library, as long as there is a file libfoo.so.1 or
a link (symlink or hardlink) that points to the 'correct' file.

> 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)?
>

The linker never sees libfoo.so.1.4 or libfoo.so.1.2 (unless you specify it
exactly like this on the gcc commandline), it only ever sees libfoo.so or
libfoo.so.1.


> 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"
> ;)).
>

Its true that it makes it harder, but it also means having to carry around
more duplicated code. Recently had to add Qt5 libs for a dozen example apps
we ship and that was not quite that easy to get up and running (without
also shipping a dozen copies of Qt5 which frankly is a bit too much).

You can however get the same thing done on Linux and (to a lesser extent)
on Windows as several companies demonstrate (including the qt-project with
qtcreator) with their products (vmware shipped even X11 IIRC in the past).

Andreas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20140711/3c440b78/attachment.html>


More information about the Interest mailing list