prebuilt-libraries.rst 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. .. SPDX-License-Identifier: CC-BY-SA-2.0-UK
  2. Working with Pre-Built Libraries
  3. ********************************
  4. Introduction
  5. ============
  6. Some library vendors do not release source code for their software but do
  7. release pre-built binaries. When shared libraries are built, they should
  8. be versioned (see `this article
  9. <https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html>`__
  10. for some background), but sometimes this is not done.
  11. To summarize, a versioned library must meet two conditions:
  12. #. The filename must have the version appended, for example: ``libfoo.so.1.2.3``.
  13. #. The library must have the ELF tag ``SONAME`` set to the major version
  14. of the library, for example: ``libfoo.so.1``. You can check this by
  15. running ``readelf -d filename | grep SONAME``.
  16. This section shows how to deal with both versioned and unversioned
  17. pre-built libraries.
  18. Versioned Libraries
  19. ===================
  20. In this example we work with pre-built libraries for the FT4222H USB I/O chip.
  21. Libraries are built for several target architecture variants and packaged in
  22. an archive as follows::
  23. ├── build-arm-hisiv300
  24. │   └── libft4222.so.1.4.4.44
  25. ├── build-arm-v5-sf
  26. │   └── libft4222.so.1.4.4.44
  27. ├── build-arm-v6-hf
  28. │   └── libft4222.so.1.4.4.44
  29. ├── build-arm-v7-hf
  30. │   └── libft4222.so.1.4.4.44
  31. ├── build-arm-v8
  32. │   └── libft4222.so.1.4.4.44
  33. ├── build-i386
  34. │   └── libft4222.so.1.4.4.44
  35. ├── build-i486
  36. │   └── libft4222.so.1.4.4.44
  37. ├── build-mips-eglibc-hf
  38. │   └── libft4222.so.1.4.4.44
  39. ├── build-pentium
  40. │   └── libft4222.so.1.4.4.44
  41. ├── build-x86_64
  42. │   └── libft4222.so.1.4.4.44
  43. ├── examples
  44. │   ├── get-version.c
  45. │   ├── i2cm.c
  46. │   ├── spim.c
  47. │   └── spis.c
  48. ├── ftd2xx.h
  49. ├── install4222.sh
  50. ├── libft4222.h
  51. ├── ReadMe.txt
  52. └── WinTypes.h
  53. To write a recipe to use such a library in your system:
  54. - The vendor will probably have a proprietary licence, so set
  55. :term:`LICENSE_FLAGS` in your recipe.
  56. - The vendor provides a tarball containing libraries so set :term:`SRC_URI`
  57. appropriately.
  58. - Set :term:`COMPATIBLE_HOST` so that the recipe cannot be used with an
  59. unsupported architecture. In the following example, we only support the 32
  60. and 64 bit variants of the ``x86`` architecture.
  61. - As the vendor provides versioned libraries, we can use ``oe_soinstall``
  62. from :ref:`ref-classes-utils` to install the shared library and create
  63. symbolic links. If the vendor does not do this, we need to follow the
  64. non-versioned library guidelines in the next section.
  65. - As the vendor likely used :term:`LDFLAGS` different from those in your Yocto
  66. Project build, disable the corresponding checks by adding ``ldflags``
  67. to :term:`INSANE_SKIP`.
  68. - The vendor will typically ship release builds without debugging symbols.
  69. Avoid errors by preventing the packaging task from stripping out the symbols
  70. and adding them to a separate debug package. This is done by setting the
  71. ``INHIBIT_`` flags shown below.
  72. The complete recipe would look like this::
  73. SUMMARY = "FTDI FT4222H Library"
  74. SECTION = "libs"
  75. LICENSE_FLAGS = "ftdi"
  76. LICENSE = "CLOSED"
  77. COMPATIBLE_HOST = "(i.86|x86_64).*-linux"
  78. # Sources available in a .tgz file in .zip archive
  79. # at https://ftdichip.com/wp-content/uploads/2021/01/libft4222-linux-1.4.4.44.zip
  80. # Found on https://ftdichip.com/software-examples/ft4222h-software-examples/
  81. # Since dealing with this particular type of archive is out of topic here,
  82. # we use a local link.
  83. SRC_URI = "file://libft4222-linux-${PV}.tgz"
  84. S = "${WORKDIR}"
  85. ARCH_DIR:x86-64 = "build-x86_64"
  86. ARCH_DIR:i586 = "build-i386"
  87. ARCH_DIR:i686 = "build-i386"
  88. INSANE_SKIP:${PN} = "ldflags"
  89. INHIBIT_PACKAGE_STRIP = "1"
  90. INHIBIT_SYSROOT_STRIP = "1"
  91. INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
  92. do_install () {
  93. install -m 0755 -d ${D}${libdir}
  94. oe_soinstall ${S}/${ARCH_DIR}/libft4222.so.${PV} ${D}${libdir}
  95. install -d ${D}${includedir}
  96. install -m 0755 ${S}/*.h ${D}${includedir}
  97. }
  98. If the precompiled binaries are not statically linked and have dependencies on
  99. other libraries, then by adding those libraries to :term:`DEPENDS`, the linking
  100. can be examined and the appropriate :term:`RDEPENDS` automatically added.
  101. Non-Versioned Libraries
  102. =======================
  103. Some Background
  104. ---------------
  105. Libraries in Linux systems are generally versioned so that it is possible
  106. to have multiple versions of the same library installed, which eases upgrades
  107. and support for older software. For example, suppose that in a versioned
  108. library, an actual library is called ``libfoo.so.1.2``, a symbolic link named
  109. ``libfoo.so.1`` points to ``libfoo.so.1.2``, and a symbolic link named
  110. ``libfoo.so`` points to ``libfoo.so.1.2``. Given these conditions, when you
  111. link a binary against a library, you typically provide the unversioned file
  112. name (i.e. ``-lfoo`` to the linker). However, the linker follows the symbolic
  113. link and actually links against the versioned filename. The unversioned symbolic
  114. link is only used at development time. Consequently, the library is packaged
  115. along with the headers in the development package ``${PN}-dev`` along with the
  116. actual library and versioned symbolic links in ``${PN}``. Because versioned
  117. libraries are far more common than unversioned libraries, the default packaging
  118. rules assume versioned libraries.
  119. Yocto Library Packaging Overview
  120. --------------------------------
  121. It follows that packaging an unversioned library requires a bit of work in the
  122. recipe. By default, ``libfoo.so`` gets packaged into ``${PN}-dev``, which
  123. triggers a QA warning that a non-symlink library is in a ``-dev`` package,
  124. and binaries in the same recipe link to the library in ``${PN}-dev``,
  125. which triggers more QA warnings. To solve this problem, you need to package the
  126. unversioned library into ``${PN}`` where it belongs. The abridged
  127. default :term:`FILES` variables in ``bitbake.conf`` are::
  128. SOLIBS = ".so.*"
  129. SOLIBSDEV = ".so"
  130. FILES:${PN} = "... ${libdir}/lib*${SOLIBS} ..."
  131. FILES_SOLIBSDEV ?= "... ${libdir}/lib*${SOLIBSDEV} ..."
  132. FILES:${PN}-dev = "... ${FILES_SOLIBSDEV} ..."
  133. :term:`SOLIBS` defines a pattern that matches real shared object libraries.
  134. :term:`SOLIBSDEV` matches the development form (unversioned symlink). These two
  135. variables are then used in ``FILES:${PN}`` and ``FILES:${PN}-dev``, which puts
  136. the real libraries into ``${PN}`` and the unversioned symbolic link into ``${PN}-dev``.
  137. To package unversioned libraries, you need to modify the variables in the recipe
  138. as follows::
  139. SOLIBS = ".so"
  140. FILES_SOLIBSDEV = ""
  141. The modifications cause the ``.so`` file to be the real library
  142. and unset :term:`FILES_SOLIBSDEV` so that no libraries get packaged into
  143. ``${PN}-dev``. The changes are required because unless :term:`PACKAGES` is changed,
  144. ``${PN}-dev`` collects files before `${PN}`. ``${PN}-dev`` must not collect any of
  145. the files you want in ``${PN}``.
  146. Finally, loadable modules, essentially unversioned libraries that are linked
  147. at runtime using ``dlopen()`` instead of at build time, should generally be
  148. installed in a private directory. However, if they are installed in ``${libdir}``,
  149. then the modules can be treated as unversioned libraries.
  150. Example
  151. -------
  152. The example below installs an unversioned x86-64 pre-built library named
  153. ``libfoo.so``. The :term:`COMPATIBLE_HOST` variable limits recipes to the
  154. x86-64 architecture while the :term:`INSANE_SKIP`, :term:`INHIBIT_PACKAGE_STRIP`
  155. and :term:`INHIBIT_SYSROOT_STRIP` variables are all set as in the above
  156. versioned library example. The "magic" is setting the :term:`SOLIBS` and
  157. :term:`FILES_SOLIBSDEV` variables as explained above::
  158. SUMMARY = "libfoo sample recipe"
  159. SECTION = "libs"
  160. LICENSE = "CLOSED"
  161. SRC_URI = "file://libfoo.so"
  162. COMPATIBLE_HOST = "x86_64.*-linux"
  163. INSANE_SKIP:${PN} = "ldflags"
  164. INHIBIT_PACKAGE_STRIP = "1"
  165. INHIBIT_SYSROOT_STRIP = "1"
  166. SOLIBS = ".so"
  167. FILES_SOLIBSDEV = ""
  168. do_install () {
  169. install -d ${D}${libdir}
  170. install -m 0755 ${WORKDIR}/libfoo.so ${D}${libdir}
  171. }