reproducible-builds.rst 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. .. SPDX-License-Identifier: CC-BY-SA-2.0-UK
  2. *******************
  3. Reproducible Builds
  4. *******************
  5. ================
  6. How we define it
  7. ================
  8. The Yocto Project defines reproducibility as where a given input build
  9. configuration will give the same binary output regardless of when it is built
  10. (now or in 5 years time), regardless of the path on the filesystem the build is
  11. run in, and regardless of the distro and tools on the underlying host system the
  12. build is running on.
  13. ==============
  14. Why it matters
  15. ==============
  16. The project aligns with the `Reproducible Builds project
  17. <https://reproducible-builds.org/>`__, which shares information about why
  18. reproducibility matters. The primary focus of the project is the ability to
  19. detect security issues being introduced. However, from a Yocto Project
  20. perspective, it is also hugely important that our builds are deterministic. When
  21. you build a given input set of metadata, we expect you to get consistent output.
  22. This has always been a key focus but, :ref:`since release 3.1 ("dunfell")
  23. <migration-guides/migration-3.1:reproducible builds now enabled by default>`,
  24. it is now true down to the binary level including timestamps.
  25. For example, at some point in the future life of a product, you find that you
  26. need to rebuild to add a security fix. If this happens, only the components that
  27. have been modified should change at the binary level. This would lead to much
  28. easier and clearer bounds on where validation is needed.
  29. This also gives an additional benefit to the project builds themselves, our
  30. :ref:`overview-manual/concepts:Hash Equivalence` for
  31. :ref:`overview-manual/concepts:Shared State` object reuse works much more
  32. effectively when the binary output remains the same.
  33. .. note::
  34. We strongly advise you to make sure your project builds reproducibly
  35. before finalizing your production images. It would be too late if you
  36. only address this issue when the first updates are required.
  37. ===================
  38. How we implement it
  39. ===================
  40. There are many different aspects to build reproducibility, but some particular
  41. things we do within the build system to ensure reproducibility include:
  42. - Adding mappings to the compiler options to ensure debug filepaths are mapped
  43. to consistent target compatible paths. This is done through the
  44. :term:`DEBUG_PREFIX_MAP` variable which sets the ``-fmacro-prefix-map`` and
  45. ``-fdebug-prefix-map`` compiler options correctly to map to target paths.
  46. - Being explicit about recipe dependencies and their configuration (no floating
  47. configure options or host dependencies creeping in). In particular this means
  48. making sure :term:`PACKAGECONFIG` coverage covers configure options which may
  49. otherwise try and auto-detect host dependencies.
  50. - Using recipe specific sysroots to isolate recipes so they only see their
  51. dependencies. These are visible as ``recipe-sysroot`` and
  52. ``recipe-sysroot-native`` directories within the :term:`WORKDIR` of a given
  53. recipe and are populated only with the dependencies a recipe has.
  54. - Build images from a reduced package set: only packages from recipes the image
  55. depends upon.
  56. - Filtering the tools available from the host's ``PATH`` to only a specific set
  57. of tools, set using the :term:`HOSTTOOLS` variable.
  58. =========================================
  59. Can we prove the project is reproducible?
  60. =========================================
  61. Yes, we can prove it and we regularly test this on the Autobuilder. At the
  62. time of writing (release 3.3, "hardknott"), :term:`OpenEmbedded-Core (OE-Core)`
  63. is 100% reproducible for all its recipes (i.e. world builds) apart from the Go
  64. language and Ruby documentation packages. Unfortunately, the current
  65. implementation of the Go language has fundamental reproducibility problems as
  66. it always depends upon the paths it is built in.
  67. .. note::
  68. Only BitBake and :term:`OpenEmbedded-Core (OE-Core)`, which is the ``meta``
  69. layer in Poky, guarantee complete reproducibility. The moment you add
  70. another layer, this warranty is voided, because of additional configuration
  71. files, ``bbappend`` files, overridden classes, etc.
  72. To run our automated selftest, as we use in our CI on the Autobuilder, you can
  73. run::
  74. oe-selftest -r reproducible.ReproducibleTests.test_reproducible_builds
  75. This defaults to including a ``world`` build so, if other layers are added, it
  76. would also run the tests for recipes in the additional layers. Different build
  77. targets can be defined using the :term:`OEQA_REPRODUCIBLE_TEST_TARGET` variable
  78. in ``local.conf``. For example, running reproducibility tests for only the
  79. ``python3-numpy`` recipe can be done by setting::
  80. OEQA_REPRODUCIBLE_TEST_TARGET = "python3-numpy"
  81. in local.conf before running the ``oe-selftest`` command shown above.
  82. Reproducibility builds the target list twice. The first build will be run using
  83. :ref:`Shared State <overview-manual/concepts:Shared State>` if available, the
  84. second build explicitly disables :ref:`Shared State
  85. <overview-manual/concepts:Shared State>` except for recipes defined in the
  86. :term:`OEQA_REPRODUCIBLE_TEST_SSTATE_TARGETS` variable, and builds on the
  87. specific host the build is running on. This means we can test reproducibility
  88. builds between different host distributions over time on the Autobuilder.
  89. If ``OEQA_DEBUGGING_SAVED_OUTPUT`` is set, any differing packages will be saved
  90. here. The test is also able to run the ``diffoscope`` command on the output to
  91. generate HTML files showing the differences between the packages, to aid
  92. debugging. On the Autobuilder, these appear under
  93. https://autobuilder.yocto.io/pub/repro-fail/ in the form ``oe-reproducible +
  94. <date> + <random ID>``, e.g. ``oe-reproducible-20200202-1lm8o1th``.
  95. The project's current reproducibility status can be seen at
  96. :yocto_home:`/reproducible-build-results/`
  97. You can also check the reproducibility status on the Autobuilder:
  98. :yocto_ab:`/valkyrie/#/builders/reproducible`.
  99. ===================================
  100. How can I test my layer or recipes?
  101. ===================================
  102. With world build
  103. ~~~~~~~~~~~~~~~~
  104. Once again, you can run a ``world`` test using the
  105. :ref:`oe-selftest <ref-manual/release-process:Testing and Quality Assurance>`
  106. command provided above. This functionality is implemented
  107. in :oe_git:`meta/lib/oeqa/selftest/cases/reproducible.py
  108. </openembedded-core/tree/meta/lib/oeqa/selftest/cases/reproducible.py>`.
  109. Subclassing the test
  110. ~~~~~~~~~~~~~~~~~~~~
  111. You could subclass the test and change ``targets`` to a different target.
  112. You may also change ``sstate_targets`` which would allow you to "pre-cache" some
  113. set of recipes before the test, meaning they are excluded from reproducibility
  114. testing. As a practical example, you could set ``sstate_targets`` to
  115. ``core-image-sato``, then setting ``targets`` to ``core-image-sato-sdk`` would
  116. run reproducibility tests only on the targets belonging only to ``core-image-sato-sdk``.
  117. Using :term:`OEQA_REPRODUCIBLE_TEST_* <OEQA_REPRODUCIBLE_TEST_LEAF_TARGETS>` variables
  118. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  119. If you want to test the reproducibility of a set of recipes, you can define
  120. :term:`OEQA_REPRODUCIBLE_TEST_LEAF_TARGETS`, in your local.conf::
  121. OEQA_REPRODUCIBLE_TEST_LEAF_TARGETS = "my-recipe"
  122. This will test the reproducibility of ``my-recipe`` but will use the
  123. :ref:`Shared State <overview-manual/concepts:Shared State>` for most its
  124. dependencies (i.e. the ones explicitly listed in DEPENDS, which may not be all
  125. dependencies, c.f. [depends] varflags, PACKAGE_DEPENDS and other
  126. implementations).
  127. You can have finer control on the test with:
  128. - :term:`OEQA_REPRODUCIBLE_TEST_TARGET`: lists recipes to be built,
  129. - :term:`OEQA_REPRODUCIBLE_TEST_SSTATE_TARGETS`: lists recipes that will
  130. be built using :ref:`Shared State <overview-manual/concepts:Shared State>`.