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