TipsAndTricks/PackagingNonversionedLibrary: Difference between revisions

From Yocto Project
Jump to navigationJump to search
No edit summary
Line 1: Line 1:
= How to Package an Unversioned Library =
= How to Package an Unversioned Library =


First some background: libraries in Linux systems are generally versioned so that it is possible to have multiple versions of the same library installed, to ease upgrades or support older software. For example in versioned libraries the actual library is called <tt>libfoo.so.1.2</tt>, and then there will be a <tt>libfoo.so.1</tt> symbolic link to <tt>libfoo.so.1.2</tt>, and finally a <tt>libfoo.so</tt> symbolic link to <tt>libfoo.so.1.2</tt>. When linking a binary against a library you typically tell it the unversioned file name (<tt>-lfoo</tt> to the linker) but the linker will follow the symbolic link and actually link against the versioned filename. The unversioned symbolic link is only used at development time, so is packaged along with the headers in the development package <tt>${PN}-dev</tt>, with the actual library and versioned symbolic links in <tt>${PN}</tt>. As versioned libraries are far more common than unversioned libraries, the default packaging rules assume versioned libraries.
Libraries in Linux systems are generally versioned so that it is possible to have multiple versions of the same library installed, which eases upgrades and support for older software. For example, suppose that in a versioned library an actual library is called "libfoo.so.1.2", a symbolic link named "libfoo.so.1" points to "libfoo.so.1.2", and a symbolic link named "libfoo.so" points to "libfoo.so.1.2". Given these conditions, when you link a binary against a library, you typically provide the unversioned file name (i.e. -lfoo to the linker).  However, the linker follows the symbolic link and actually links against the versioned filename. The unversioned symbolic link is only used at development time. Consequently, the library is packaged along with the headers in the development package ${PN}-dev along with the actual library and versioned symbolic links in ${PN}. Because versioned libraries are far more common than unversioned libraries, the default packaging rules assume versioned libraries.


However this means that packaging an unversioned library means a bit of work in the recipe, as by default libfoo.so will get packaged into <tt>${PN}-dev</tt> (triggerring a QA warning that a non-symlink library is in a <tt>-dev</tt> package), and binaries in the same recipe will link to the library in <tt>${PN}-dev</tt> (triggering more QA warnings). To solve this the unversioned library needs to be packaged into <tt>${PN}</tt> where it belongs. These are the (abridged) default <tt>FILES</tt> variables in <tt>bitbake.conf</tt>:
It follows that packaging an unversioned library requires a bit of work in the recipe.  By default, "libfoo.so" gets packaged into ${PN}-dev, which triggers a QA warning that a non-symlink library is in a -dev package, and binaries in the same recipe link to the library in ${PN}-dev, which triggers more QA warnings. To solve this problem, you need to package the unversioned library into ${PN} where it belongs. Following are the abridged default FILES variables in bitbake.conf:


SOLIBS = ".so.*"
  SOLIBS = ".so.*"
SOLIBSDEV = ".so"
  SOLIBSDEV = ".so"
FILES_${PN} = "... ${libdir}/lib*${SOLIBS} ..."
  FILES_${PN} = "... ${libdir}/lib*${SOLIBS} ..."
FILES_SOLIBSDEV ?= "... ${libdir}/lib*${SOLIBSDEV} ..."
  FILES_SOLIBSDEV ?= "... ${libdir}/lib*${SOLIBSDEV} ..."
FILES_${PN}-dev = "... ${FILES_SOLIBSDEV} ..."
  FILES_${PN}-dev = "... ${FILES_SOLIBSDEV} ..."


<tt>SOLIBS</tt> defines a pattern that matches real shared object libraries, and <tt>SOLIBSDEV</tt> matches the development form (unversioned symlink). These are then used in <tt>FILES_${PN}</tt> and <tt>FILES_${PN}-dev</tt> which puts the real libraries into <tt>${PN}</tt> and the unversioned symbolic link into <tt>PN-dev</tt>. To package unversioned libraries, this needs to be modified as follows in the recipe:
SOLIBS defines a pattern that matches real shared object librariesSOLIBSDEV matches the development form (unversioned symlink). These two variables are then used in FILES_${PN} and FILES_${PN}-dev, which puts the real libraries into ${PN} and the unversioned symbolic link into PN-dev. To package unversioned libraries, you need to modify the variables in the recipe as follows:


SOLIBS = ".so"
  SOLIBS = ".so"
FILES_SOLIBSDEV = ""
  FILES_SOLIBSDEV = ""


This says that <tt>.so</tt> is the real library, and unsets <tt>FILES_SOLIBSDEV</tt> so that no libraries get packaged into <tt>PN-dev</tt>. This is required because unless <tt>PACKAGES</tt> is changed <tt>PN-dev</tt> collects files before <tt>PN</tt>, so <tt>PN-dev</tt> must not collect any of the files we want in <tt>PN</tt>.
The modifications cause .so to be the real library and unsets FILES_SOLIBSDEV so that no libraries get packaged into PN-dev. The changes are required because unless PACKAGES is changed, PN-dev collects files before PNPN-dev must not collect any of the files you want in PN.


When installing the library, use the <tt>install</tt> command rather than the <tt>oe_soinstall</tt> helper function. <tt>oe_soinstall</tt> will cause an error due to recursive symbolic linking (see its implementation in <tt>utils.bbclass</tt> for more details).
Finally, loadable modules (i.e. essentially unversioned libraries that are linked at runtime using dlopen() instead of at build time) should generally be installed in a private directory. However, if they are installed in ${libdir}, then the modules can be treated as unversioned libraries.
 
Finally loadable modules, essentially unversioned libraries that are linked at runtime using <tt>dlopen()</tt> instead of at build time, should generally be installed in a private directory. However if they are installed in <tt>${libdir}</tt> then they can be treated as unversioned libraries.

Revision as of 19:37, 18 August 2016

How to Package an Unversioned Library

Libraries in Linux systems are generally versioned so that it is possible to have multiple versions of the same library installed, which eases upgrades and support for older software. For example, suppose that in a versioned library an actual library is called "libfoo.so.1.2", a symbolic link named "libfoo.so.1" points to "libfoo.so.1.2", and a symbolic link named "libfoo.so" points to "libfoo.so.1.2". Given these conditions, when you link a binary against a library, you typically provide the unversioned file name (i.e. -lfoo to the linker). However, the linker follows the symbolic link and actually links against the versioned filename. The unversioned symbolic link is only used at development time. Consequently, the library is packaged along with the headers in the development package ${PN}-dev along with the actual library and versioned symbolic links in ${PN}. Because versioned libraries are far more common than unversioned libraries, the default packaging rules assume versioned libraries.

It follows that packaging an unversioned library requires a bit of work in the recipe. By default, "libfoo.so" gets packaged into ${PN}-dev, which triggers a QA warning that a non-symlink library is in a -dev package, and binaries in the same recipe link to the library in ${PN}-dev, which triggers more QA warnings. To solve this problem, you need to package the unversioned library into ${PN} where it belongs. Following are the abridged default FILES variables in bitbake.conf:

 SOLIBS = ".so.*"
 SOLIBSDEV = ".so"
 FILES_${PN} = "... ${libdir}/lib*${SOLIBS} ..."
 FILES_SOLIBSDEV ?= "... ${libdir}/lib*${SOLIBSDEV} ..."
 FILES_${PN}-dev = "... ${FILES_SOLIBSDEV} ..."

SOLIBS defines a pattern that matches real shared object libraries. SOLIBSDEV matches the development form (unversioned symlink). These two variables are then used in FILES_${PN} and FILES_${PN}-dev, which puts the real libraries into ${PN} and the unversioned symbolic link into PN-dev. To package unversioned libraries, you need to modify the variables in the recipe as follows:

 SOLIBS = ".so"
 FILES_SOLIBSDEV = ""

The modifications cause .so to be the real library and unsets FILES_SOLIBSDEV so that no libraries get packaged into PN-dev. The changes are required because unless PACKAGES is changed, PN-dev collects files before PN. PN-dev must not collect any of the files you want in PN.

Finally, loadable modules (i.e. essentially unversioned libraries that are linked at runtime using dlopen() instead of at build time) should generally be installed in a private directory. However, if they are installed in ${libdir}, then the modules can be treated as unversioned libraries.