TipsAndTricks/PackagingNonversionedLibrary: Difference between revisions

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


First some background: in general libraries in Linux systems are versioned so that it's possible to have multiple versions of the same library installed, to ease upgrades or support older software.  In versioned libraries the actual library binary is for example 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 then you typically just tell it the unversioned file name (for example, <tt>-lfoo</tt> to the linker) but the linker will follow the symbolic links and actually link against the fully-versioned filename.  The unversioned symbolic link is only used at development time, so in OpenEmbedded (as with all other Linux distros) gets packaged along with the headers in development package <tt>${PN}-dev</tt>.  As versioned libraries are far more common than unversioned libraries, the default packaging rules assume versioned libraries.
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 ${PN}.  As versioned libraries are far more common than unversioned libraries, the default packaging rules assume versioned libraries.


However this means that packaging an unversioned library isn't trivial, as by default libfoo.so will get packaged into PN-dev (triggerring a QA warning that a non-symlink library is in PN-dev), and binaries in the same recipe will link to the library in PN-dev (and trigger more QA warnings).  To solve this the unversioned library needs to be packaged into ${PN} where it belongs, so lets have an abridged look at the default FILES variables in bitbake.conf:
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 PN-dev (triggerring a QA warning that a non-symlink library is in PN-dev), and binaries in the same recipe will link to the library in PN-dev (triggering more QA warnings).  To solve this the unversioned library needs to be packaged into ${PN} where it belongs. These are the (abridged) default FILES variables in bitbake.conf:


  SOLIBS = ".so.*"
  SOLIBS = ".so.*"
Line 11: Line 11:
  FILES_${PN}-dev = "... ${FILES_SOLIBSDEV} ..."
  FILES_${PN}-dev = "... ${FILES_SOLIBSDEV} ..."


SOLIBS defines a pattern that matches real shared object libraries, and SOLIBSDEV matches the development form (unversioned symlinks, typically).  These 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, this needs to be modified as follows in the recipe:
SOLIBS defines a pattern that matches real shared object libraries, and SOLIBSDEV matches the development form (unversioned symlink).  These 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, this needs to be modified as follows in the recipe:


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


This says that <tt>.so</tt> is the real library, and unsets FILES_SOLIBSDEV so that no libraries get packaged into PN-dev.  This is required because PN-dev collects files before PN, so FILES_PN-dev must not collect any of the files.
This says that <tt>.so</tt> is the real library, and unsets FILES_SOLIBSDEV so that no libraries get packaged into PN-dev.  This is required because unless PACKAGES is changed PN-dev collects files before PN, so PN-dev must not collect any of the files we want in PN.
 
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 ${libdir} then they can be treated as unversioned libraries.

Revision as of 19:17, 1 August 2016

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 libfoo.so.1.2, and then there will be a libfoo.so.1 symbolic link to libfoo.so.1.2, and finally a libfoo.so symbolic link to libfoo.so.1.2. When linking a binary against a library you typically tell it the unversioned file name (-lfoo 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 ${PN}-dev, with the actual library and versioned symbolic links in ${PN}. As 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 PN-dev (triggerring a QA warning that a non-symlink library is in PN-dev), and binaries in the same recipe will link to the library in PN-dev (triggering more QA warnings). To solve this the unversioned library needs to be packaged into ${PN} where it belongs. These 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, and SOLIBSDEV matches the development form (unversioned symlink). These 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, this needs to be modified as follows in the recipe:

SOLIBS = ".so"
FILES_SOLIBSDEV = ""

This says that .so is the real library, and unsets FILES_SOLIBSDEV so that no libraries get packaged into PN-dev. This is required because unless PACKAGES is changed PN-dev collects files before PN, so PN-dev must not collect any of the files we want in PN.

Finally loadable modules, 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 they can be treated as unversioned libraries.