xref: /OK3568_Linux_fs/yocto/poky/documentation/test-manual/reproducible-builds.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun*******************
4*4882a593SmuzhiyunReproducible Builds
5*4882a593Smuzhiyun*******************
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun================
8*4882a593SmuzhiyunHow we define it
9*4882a593Smuzhiyun================
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunThe Yocto Project defines reproducibility as where a given input build
12*4882a593Smuzhiyunconfiguration will give the same binary output regardless of when it is built
13*4882a593Smuzhiyun(now or in 5 years time), regardless of the path on the filesystem the build is
14*4882a593Smuzhiyunrun in, and regardless of the distro and tools on the underlying host system the
15*4882a593Smuzhiyunbuild is running on.
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun==============
18*4882a593SmuzhiyunWhy it matters
19*4882a593Smuzhiyun==============
20*4882a593Smuzhiyun
21*4882a593SmuzhiyunThe project aligns with the `Reproducible Builds project
22*4882a593Smuzhiyun<https://reproducible-builds.org/>`_, which shares information about why
23*4882a593Smuzhiyunreproducibility matters. The primary focus of the project is the ability to
24*4882a593Smuzhiyundetect security issues being introduced. However, from a Yocto Project
25*4882a593Smuzhiyunperspective, it is also hugely important that our builds are deterministic. When
26*4882a593Smuzhiyunyou build a given input set of metadata, we expect you to get consistent output.
27*4882a593SmuzhiyunThis has always been a key focus but, :yocto_docs:`since release 3.1 ("dunfell")
28*4882a593Smuzhiyun</ref-manual/migration-3.1.html#reproducible-builds-now-enabled-by-default>`,
29*4882a593Smuzhiyunit is now true down to the binary level including timestamps.
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunFor example, at some point in the future life of a product, you find that you
32*4882a593Smuzhiyunneed to rebuild to add a security fix. If this happens, only the components that
33*4882a593Smuzhiyunhave been modified should change at the binary level. This would lead to much
34*4882a593Smuzhiyuneasier and clearer bounds on where validation is needed.
35*4882a593Smuzhiyun
36*4882a593SmuzhiyunThis also gives an additional benefit to the project builds themselves, our
37*4882a593Smuzhiyun:ref:`overview-manual/concepts:Hash Equivalence` for
38*4882a593Smuzhiyun:ref:`overview-manual/concepts:Shared State` object reuse works much more
39*4882a593Smuzhiyuneffectively when the binary output remains the same.
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun.. note::
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun   We strongly advise you to make sure your project builds reproducibly
44*4882a593Smuzhiyun   before finalizing your production images. It would be too late if you
45*4882a593Smuzhiyun   only address this issue when the first updates are required.
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun===================
48*4882a593SmuzhiyunHow we implement it
49*4882a593Smuzhiyun===================
50*4882a593Smuzhiyun
51*4882a593SmuzhiyunThere are many different aspects to build reproducibility, but some particular
52*4882a593Smuzhiyunthings we do within the build system to ensure reproducibility include:
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun-  Adding mappings to the compiler options to ensure debug filepaths are mapped
55*4882a593Smuzhiyun   to consistent target compatible paths. This is done through the
56*4882a593Smuzhiyun   :term:`DEBUG_PREFIX_MAP` variable which sets the ``-fmacro-prefix-map`` and
57*4882a593Smuzhiyun   ``-fdebug-prefix-map`` compiler options correctly to map to target paths.
58*4882a593Smuzhiyun-  Being explicit about recipe dependencies and their configuration (no floating
59*4882a593Smuzhiyun   configure options or host dependencies creeping in). In particular this means
60*4882a593Smuzhiyun   making sure :term:`PACKAGECONFIG` coverage covers configure options which may
61*4882a593Smuzhiyun   otherwise try and auto-detect host dependencies.
62*4882a593Smuzhiyun-  Using recipe specific sysroots to isolate recipes so they only see their
63*4882a593Smuzhiyun   dependencies. These are visible as ``recipe-sysroot`` and
64*4882a593Smuzhiyun   ``recipe-sysroot-native`` directories within the :term:`WORKDIR` of a given
65*4882a593Smuzhiyun   recipe and are populated only with the dependencies a recipe has.
66*4882a593Smuzhiyun-  Build images from a reduced package set: only packages from recipes the image
67*4882a593Smuzhiyun   depends upon.
68*4882a593Smuzhiyun-  Filtering the tools available from the host's ``PATH`` to only a specific set
69*4882a593Smuzhiyun   of tools, set using the :term:`HOSTTOOLS` variable.
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun.. note::
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun   Because of an open bug in GCC, using ``DISTRO_FEATURES:append = " lto"`` or
74*4882a593Smuzhiyun   adding ``-flto`` (Link Time Optimization) to ``CFLAGS`` makes the resulting
75*4882a593Smuzhiyun   binary non-reproducible, in that it depends on the full absolute build path
76*4882a593Smuzhiyun   to ``recipe-sysroot-native``, so installing the Yocto Project in a different
77*4882a593Smuzhiyun   directory results in a different binary.
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun   This issue is addressed by
80*4882a593Smuzhiyun   :yocto_bugs:`bug 14481 -  Programs built with -flto are not reproducible</show_bug.cgi?id=14481>`.
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun=========================================
83*4882a593SmuzhiyunCan we prove the project is reproducible?
84*4882a593Smuzhiyun=========================================
85*4882a593Smuzhiyun
86*4882a593SmuzhiyunYes, we can prove it and we regularly test this on the Autobuilder. At the
87*4882a593Smuzhiyuntime of writing (release 3.3, "hardknott"), :term:`OpenEmbedded-Core (OE-Core)`
88*4882a593Smuzhiyunis 100% reproducible for all its recipes (i.e. world builds) apart from the Go
89*4882a593Smuzhiyunlanguage and Ruby documentation packages. Unfortunately, the current
90*4882a593Smuzhiyunimplementation of the Go language has fundamental reproducibility problems as
91*4882a593Smuzhiyunit always depends upon the paths it is built in.
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun.. note::
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun   Only BitBake and :term:`OpenEmbedded-Core (OE-Core)`, which is the ``meta``
96*4882a593Smuzhiyun   layer in Poky, guarantee complete reproducibility. The moment you add
97*4882a593Smuzhiyun   another layer, this warranty is voided, because of additional configuration
98*4882a593Smuzhiyun   files, ``bbappend`` files, overridden classes, etc.
99*4882a593Smuzhiyun
100*4882a593SmuzhiyunTo run our automated selftest, as we use in our CI on the Autobuilder, you can
101*4882a593Smuzhiyunrun::
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun   oe-selftest -r reproducible.ReproducibleTests.test_reproducible_builds
104*4882a593Smuzhiyun
105*4882a593SmuzhiyunThis defaults to including a ``world`` build so, if other layers are added, it would
106*4882a593Smuzhiyunalso run the tests for recipes in the additional layers. The first build will be
107*4882a593Smuzhiyunrun using :ref:`Shared State <overview-manual/concepts:Shared State>` if
108*4882a593Smuzhiyunavailable, the second build explicitly disables
109*4882a593Smuzhiyun:ref:`Shared State <overview-manual/concepts:Shared State>` and builds on the
110*4882a593Smuzhiyunspecific host the build is running on. This means we can test reproducibility
111*4882a593Smuzhiyunbuilds between different host distributions over time on the Autobuilder.
112*4882a593Smuzhiyun
113*4882a593SmuzhiyunIf ``OEQA_DEBUGGING_SAVED_OUTPUT`` is set, any differing packages will be saved
114*4882a593Smuzhiyunhere. The test is also able to run the ``diffoscope`` command on the output to
115*4882a593Smuzhiyungenerate HTML files showing the differences between the packages, to aid
116*4882a593Smuzhiyundebugging. On the Autobuilder, these appear under
117*4882a593Smuzhiyunhttps://autobuilder.yocto.io/pub/repro-fail/ in the form ``oe-reproducible +
118*4882a593Smuzhiyun<date> + <random ID>``, e.g. ``oe-reproducible-20200202-1lm8o1th``.
119*4882a593Smuzhiyun
120*4882a593SmuzhiyunThe project's current reproducibility status can be seen at
121*4882a593Smuzhiyun:yocto_home:`/reproducible-build-results/`
122*4882a593Smuzhiyun
123*4882a593SmuzhiyunYou can also check the reproducibility status on supported host distributions:
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun-  CentOS: :yocto_ab:`/typhoon/#/builders/reproducible-centos`
126*4882a593Smuzhiyun-  Debian: :yocto_ab:`/typhoon/#/builders/reproducible-debian`
127*4882a593Smuzhiyun-  Fedora: :yocto_ab:`/typhoon/#/builders/reproducible-fedora`
128*4882a593Smuzhiyun-  Ubuntu: :yocto_ab:`/typhoon/#/builders/reproducible-ubuntu`
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun===============================
131*4882a593SmuzhiyunCan I test my layer or recipes?
132*4882a593Smuzhiyun===============================
133*4882a593Smuzhiyun
134*4882a593SmuzhiyunOnce again, you can run a ``world`` test using the
135*4882a593Smuzhiyun:ref:`oe-selftest <ref-manual/release-process:Testing and Quality Assurance>`
136*4882a593Smuzhiyuncommand provided above. This functionality is implemented
137*4882a593Smuzhiyunin :oe_git:`meta/lib/oeqa/selftest/cases/reproducible.py
138*4882a593Smuzhiyun</openembedded-core/tree/meta/lib/oeqa/selftest/cases/reproducible.py>`.
139*4882a593Smuzhiyun
140*4882a593SmuzhiyunYou could subclass the test and change ``targets`` to a different target.
141*4882a593Smuzhiyun
142*4882a593SmuzhiyunYou may also change ``sstate_targets`` which would allow you to "pre-cache" some
143*4882a593Smuzhiyunset of recipes before the test, meaning they are excluded from reproducibility
144*4882a593Smuzhiyuntesting. As a practical example, you could set ``sstate_targets`` to
145*4882a593Smuzhiyun``core-image-sato``, then setting ``targets`` to ``core-image-sato-sdk`` would
146*4882a593Smuzhiyunrun reproducibility tests only on the targets belonging only to ``core-image-sato-sdk``.
147