[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