[Development] Co-installation & library naming rules
Thiago Macieira
thiago.macieira at intel.com
Fri Sep 21 16:47:11 CEST 2012
This is long, so I'll give you my recommendation first. If you agree with me,
you don't have to read the rest. If you disagree, you have to read my
arguments.
Recommendation:
---------------
Include the major version number (5) in all library base names, like on
Windows, on all platforms. On Windows we already have QtCore5.dll and
QtV85.dll, so I recommend having libQtCore5.so.5. For Mac, I'm not sure of the
naming scheme, but the recommendation applies.
This recommendation also applies to the static library archives
(libQtCore5.a), qmake library files (libQtCore5.prl), libtool archives
(libQtCore5.la) and pkgconfig files (QtCore5.pc). CMake files already have the
version number. but in a different place (Qt5Core).
I recommend harmonising the cmake names, either by changing them to QtCore5 or
by changing the library naming to match the cmake files (libQt5Core.so,
Qt5Core.pc, etc). Or one of the other alternatives at the bottom of this
email.
PS: this recommendation does not apply to executables. See follow-up email.
Rationale:
----------
This is a rewriting of the book in how to name a library.
== Current ==
Up until now, libraries on Linux and other ELF-based Unix systems have been
named freely. Since the dynamic linker and the compile linker operate on
different names, this has opened up some opportunities for co-installation.
The regular linker searches for libXXX.so or libXXX.a when given the -lXXX
flag. When it links to a shared object, it reads that object's soname (so-
called because it appears in the ELF dynamic tag DT_SONAME) and records it in
this object's header, with the tag DT_NEEDED. That's the name that the dynamic
linker will search for at runtime. The linker also offers an option to set the
soname of the library being created to anything, defaulting to the output file
name.
By *convention*, version numbers are numerical and include two or more
numbers. Qt uses the same scheme that Linux kernels did prior to the 2.6.x
series and now again with the 3.x series: three numbers, labeled "major",
"minor" and "micro" (or "patch-level").
Also by convention, buildsystems include the major version number in the
library's soname. That is, when building QtCore version 4.8.2, the following
files are relevant:
libQtCore.so the file that -lQtCore will search
libQtCore.so.4 the file that matches the soname
libQtCore.so.4.8.2 the actual library, not a symlink
(libQtCore.so.4.8 is not relevant, since absolutely no one uses it)
As a consequence of the behaviour of the dynamic linker, it is possible to
install in parallel two different major versions of a given library, so that
applications and other libraries built with the previous version can continue
working.
In particular, note that it's also possible to load two different major
versions of a given library into memory, as the dynamic linker only cares
about the full soname. More often than not, that's a bad idea.
Note: does not apply to Qt Quick 2, since the version number is already part
of the base library name.
== Enter other tools ==
CMake, libtool, pkgconfig and tools built around them introduce another level
of complexity. As was shown by CMake months ago, we cannot have the Qt 5
packages called "Qt" as those conflict with the ones in Qt 4. The same now
applies to the pkgconfig files.
Buildsystems based on pkgconfig will often have a requirement of the form:
QtCore >= 4.6 QtGui >= 4.6
or even simply:
QtCore QtGui
Those requirements do match the Qt 5 libraries:
$ pkg-config --libs QtCore \>= 4.6 QtGui \>= 4.6
-L/home/thiago/obj/qt/qt5/qtbase/lib -lQtCore -lQtGui
Whether that is correct or not is unknown to pkg-config. It could be right if
the application has already been ported to Qt 5. In the case of most
applications existing today, it is incorrect.
But it could be right for other libraries. For example, for libpng:
$ pkg-config --libs libpng \>= 1.2
-lpng15
The fact that our pkg-config files have the same name also impacts the co-
installability of Qt 4 and Qt 5, and a little more: Linux distributions *will*
carry Qt 4 for a number of years to come (they still have Qt 3). Therefore,
they must be able to at least have both sets of packages in their
repositories. The problem comes when their buildsystems make reference to pkg-
config files, such as in RPM-based distros:
BuildRequires: pkgconfig(QtCore)
Since the distribution contains packages for both versions of QtCore, it is
now ambiguous which one would be selected for building. Selecting the 5
version now would be wrong, just as selecting version 4 in a few years' time.
== Proposal ==
The library naming rules must be modified. They should be:
1) when making a new release that retains source and binary compatibility,
retain the library soname;
2) when making a new release that retains source compatibility but not binary,
change the soname but retain the base library name;
3) when making a new release that does not retain source or binary
compatibility, change the base library name.
In addition, all files must carry names derived from or linked to the library's
base name or soname. That is:
a) files needed at runtime must be linked to the soname
b) files needed at compile-time only must be linked to the base name.
In the specific case of the qtbase libraries, we do not intend to ever make a
source-compatible binary-breaking release, so the two version numbers are the
same. We could even drop the duplication (i.e., have soname libQtCore5.so or
libQt5Core.so) or we could reset the soname version to 1.
It could happen for other libraries. For example, a hypothetical Qt Quick 3
could also use V8 but require binary incompatible changes. For that reason, we
may want libQtV85.so.1 and libQtV85.so.2.
Or, for that reason, Qt Quick 2 could decide to make such a release:
libQtQuick2.so libQtQuick2.so.1 & libQtQuick2.so.2
Naming alternatives:
--------------------
I: base name QtCore5, soversion 5
link option: -lQtCore5 searches for libQtCore5.so & libQtCore5.a
soname: libQtCore5.so.5
actual lib: libQtCore5.so.5.0.0
pkg-config: QtCore5.pc
update cmake files
II: base name Qt5Core, soversion 5
link option: -lQt5Core
soname: libQt5Core.so.5
actual lib: libQt5Core.so.5.0.0
pkg-config: Qt5Core.pc
keep cmake files
III: base name QtCore5, drop soversion
link option: -lQtCore5
soname libQtCore5.so
actual lib: libQtCore5.0.0.so
pkg-config: QtCore5.pc
update cmake files
sub-alternatives:
bis) base name QtCore-5 (like glib)
ter) base name QtCore.5 (like Mac OS X)
IV: base name QtCore5, reset soversion to 1
link option: -lQtCore5
soname: libQtCore5.so.1
actual lib: libQtCore5.so.1.0.0
update cmake files
V: base name Qt5Core, reset soversion to 1
link option: -lQt5Core
soname: libQt5Core.so.1
actual lib: libQt5Core.so.1.0.0
keep cmake files
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20120921/86948699/attachment.sig>
More information about the Development
mailing list