xref: /aosp_15_r20/external/pigweed/pw_build_info/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build_info:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker=============
4*61c4878aSAndroid Build Coastguard Workerpw_build_info
5*61c4878aSAndroid Build Coastguard Worker=============
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_build_info
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard Workerpw_build_info provides tooling, build integration, and libraries for generating,
10*61c4878aSAndroid Build Coastguard Workerembedding, and parsing build-related information that is embedded into
11*61c4878aSAndroid Build Coastguard Workerbinaries. Simple numeric version numbering doesn't typically express things
12*61c4878aSAndroid Build Coastguard Workerlike where the binary originated, what devices it's compatible with, whether
13*61c4878aSAndroid Build Coastguard Workerlocal changes were present when the binary was built, and more. pw_build_info
14*61c4878aSAndroid Build Coastguard Workersimplifies the process of integrating rich version metadata to answer more
15*61c4878aSAndroid Build Coastguard Workercomplex questions about compiled binaries.
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build_info-gnu-build-ids:
18*61c4878aSAndroid Build Coastguard Worker
19*61c4878aSAndroid Build Coastguard Worker-------------
20*61c4878aSAndroid Build Coastguard WorkerGNU build IDs
21*61c4878aSAndroid Build Coastguard Worker-------------
22*61c4878aSAndroid Build Coastguard WorkerThis module provides C++ and python libraries for reading GNU build IDs
23*61c4878aSAndroid Build Coastguard Workergenerated by the link step of a C++ executable. These build IDs are essentially
24*61c4878aSAndroid Build Coastguard Workerhashes of the final linked binary, meaning two identical binaries will have
25*61c4878aSAndroid Build Coastguard Workeridentical build IDs. This can be used to accurately identify matching
26*61c4878aSAndroid Build Coastguard Workerbinaries.
27*61c4878aSAndroid Build Coastguard Worker
28*61c4878aSAndroid Build Coastguard WorkerLinux executables that depend on the ``build_id`` GN target will automatically
29*61c4878aSAndroid Build Coastguard Workergenerate GNU build IDs. Windows and macOS binaries cannot use this target as
30*61c4878aSAndroid Build Coastguard Workerthe implementation of GNU build IDs depends on the ELF file format.
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard WorkerA separate GN target ``build_id_or_noop`` is available which provides an empty
33*61c4878aSAndroid Build Coastguard Workerbuild ID on platforms where GNU build ID is not available while still providing
34*61c4878aSAndroid Build Coastguard Workera real GNU build ID where supported.
35*61c4878aSAndroid Build Coastguard Worker
36*61c4878aSAndroid Build Coastguard WorkerGetting started
37*61c4878aSAndroid Build Coastguard Worker===============
38*61c4878aSAndroid Build Coastguard WorkerTo generate GNU build IDs as part of your firmware image, you'll need to update
39*61c4878aSAndroid Build Coastguard Workeryour embedded target's linker script.
40*61c4878aSAndroid Build Coastguard Worker
41*61c4878aSAndroid Build Coastguard WorkerUpdating your linker script
42*61c4878aSAndroid Build Coastguard Worker---------------------------
43*61c4878aSAndroid Build Coastguard WorkerIf your project has a custom linker script, you'll need to update it to include
44*61c4878aSAndroid Build Coastguard Workera section to contain the generated build ID. This section should be placed
45*61c4878aSAndroid Build Coastguard Workeralongside the ``.text`` and ``.rodata`` sections, and named
46*61c4878aSAndroid Build Coastguard Worker``.note.gnu.build-id``.
47*61c4878aSAndroid Build Coastguard Worker
48*61c4878aSAndroid Build Coastguard Worker.. code-block:: none
49*61c4878aSAndroid Build Coastguard Worker
50*61c4878aSAndroid Build Coastguard Worker   /* Main executable code. */
51*61c4878aSAndroid Build Coastguard Worker   .code : ALIGN(4)
52*61c4878aSAndroid Build Coastguard Worker   {
53*61c4878aSAndroid Build Coastguard Worker     . = ALIGN(4);
54*61c4878aSAndroid Build Coastguard Worker     /* Application code. */
55*61c4878aSAndroid Build Coastguard Worker     *(.text)
56*61c4878aSAndroid Build Coastguard Worker     *(.text*)
57*61c4878aSAndroid Build Coastguard Worker     KEEP(*(.init))
58*61c4878aSAndroid Build Coastguard Worker     KEEP(*(.fini))
59*61c4878aSAndroid Build Coastguard Worker     ...
60*61c4878aSAndroid Build Coastguard Worker   } >FLASH
61*61c4878aSAndroid Build Coastguard Worker
62*61c4878aSAndroid Build Coastguard Worker   /* GNU build ID section. */
63*61c4878aSAndroid Build Coastguard Worker   .note.gnu.build-id :
64*61c4878aSAndroid Build Coastguard Worker   {
65*61c4878aSAndroid Build Coastguard Worker     . = ALIGN(4);
66*61c4878aSAndroid Build Coastguard Worker     gnu_build_id_begin = .;
67*61c4878aSAndroid Build Coastguard Worker     *(.note.gnu.build-id);
68*61c4878aSAndroid Build Coastguard Worker   } >FLASH
69*61c4878aSAndroid Build Coastguard Worker
70*61c4878aSAndroid Build Coastguard Worker   /* Explicitly initialized global and static data. (.data) */
71*61c4878aSAndroid Build Coastguard Worker   .static_init_ram : ALIGN(4)
72*61c4878aSAndroid Build Coastguard Worker   {
73*61c4878aSAndroid Build Coastguard Worker     *(.data)
74*61c4878aSAndroid Build Coastguard Worker     *(.data*)
75*61c4878aSAndroid Build Coastguard Worker     ...
76*61c4878aSAndroid Build Coastguard Worker   } >RAM AT> FLASH
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard Worker
79*61c4878aSAndroid Build Coastguard WorkerAlternatively, you can copy the following linker snippet into a pre-existing
80*61c4878aSAndroid Build Coastguard Workersection. This makes reading the build ID slower, so whenever possible prefer
81*61c4878aSAndroid Build Coastguard Workercreating a dedicated section for the build ID.
82*61c4878aSAndroid Build Coastguard Worker
83*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: build_id_linker_snippet.ld
84*61c4878aSAndroid Build Coastguard Worker
85*61c4878aSAndroid Build Coastguard WorkerAn example of directly inserting a build ID into an existing section is
86*61c4878aSAndroid Build Coastguard Workerprovided below:
87*61c4878aSAndroid Build Coastguard Worker
88*61c4878aSAndroid Build Coastguard Worker.. code-block:: none
89*61c4878aSAndroid Build Coastguard Worker
90*61c4878aSAndroid Build Coastguard Worker   /* Main executable code. */
91*61c4878aSAndroid Build Coastguard Worker   .code : ALIGN(4)
92*61c4878aSAndroid Build Coastguard Worker   {
93*61c4878aSAndroid Build Coastguard Worker     . = ALIGN(4);
94*61c4878aSAndroid Build Coastguard Worker     /* Application code. */
95*61c4878aSAndroid Build Coastguard Worker     *(.text)
96*61c4878aSAndroid Build Coastguard Worker     *(.text*)
97*61c4878aSAndroid Build Coastguard Worker     KEEP(*(.init))
98*61c4878aSAndroid Build Coastguard Worker     KEEP(*(.fini))
99*61c4878aSAndroid Build Coastguard Worker
100*61c4878aSAndroid Build Coastguard Worker     . = ALIGN(4);
101*61c4878aSAndroid Build Coastguard Worker     gnu_build_id_begin = .;
102*61c4878aSAndroid Build Coastguard Worker     *(.note.gnu.build-id);
103*61c4878aSAndroid Build Coastguard Worker
104*61c4878aSAndroid Build Coastguard Worker     ...
105*61c4878aSAndroid Build Coastguard Worker   } >FLASH
106*61c4878aSAndroid Build Coastguard Worker
107*61c4878aSAndroid Build Coastguard WorkerIf your linker script is auto-generated, you may be able to use the
108*61c4878aSAndroid Build Coastguard Worker``INSERT AFTER`` linker script directive to append the build ID as seen in the
109*61c4878aSAndroid Build Coastguard WorkerLinux host support for pw_build_info's build ID integration:
110*61c4878aSAndroid Build Coastguard Worker
111*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: add_build_id_to_default_linker_script.ld
112*61c4878aSAndroid Build Coastguard Worker
113*61c4878aSAndroid Build Coastguard WorkerGenerating the build ID
114*61c4878aSAndroid Build Coastguard Worker-----------------------
115*61c4878aSAndroid Build Coastguard WorkerWhen you depend on ``"$dir_pw_build_info:build_id``, a GNU build ID will be
116*61c4878aSAndroid Build Coastguard Workergenerated at the final link step of any binaries that depend on that library
117*61c4878aSAndroid Build Coastguard Worker(whether directly or transitively). Those binaries will be able to read the
118*61c4878aSAndroid Build Coastguard Workerbuild ID by calling ``pw::build_info::BuildId()``. Note that the build ID
119*61c4878aSAndroid Build Coastguard Workeris not a string, but raw binary data, so to print it you'll need to convert
120*61c4878aSAndroid Build Coastguard Workerit to hex or base64. It is possible to call ``pw::build_info::LogBuildId()``
121*61c4878aSAndroid Build Coastguard Workerfunction to print it (as hexadecimal).
122*61c4878aSAndroid Build Coastguard Worker
123*61c4878aSAndroid Build Coastguard WorkerPython API reference
124*61c4878aSAndroid Build Coastguard Worker====================
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard Worker.. py:function:: read_build_id_from_section(elf_file: BinaryIO) -> \
127*61c4878aSAndroid Build Coastguard Worker                     bytes | None
128*61c4878aSAndroid Build Coastguard Worker
129*61c4878aSAndroid Build Coastguard Worker  Reads a GNU build ID from an ELF binary by searching for a
130*61c4878aSAndroid Build Coastguard Worker  ``.note.gnu.build-id`` section.
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard Worker.. py:function:: read_build_id_from_symbol(elf_file: BinaryIO) -> \
133*61c4878aSAndroid Build Coastguard Worker                     bytes | None
134*61c4878aSAndroid Build Coastguard Worker
135*61c4878aSAndroid Build Coastguard Worker  Reads a GNU build ID from an ELF binary by searching for a
136*61c4878aSAndroid Build Coastguard Worker  ``gnu_build_id_begin`` symbol. This can be a rather slow operation.
137*61c4878aSAndroid Build Coastguard Worker
138*61c4878aSAndroid Build Coastguard Worker.. py:function:: read_build_id(elf_file: BinaryIO) -> bytes | None
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard Worker  Reads a GNU build ID from an ELF binary, first checking for a GNU build ID
141*61c4878aSAndroid Build Coastguard Worker  section and then falling back to search for a ``gnu_build_id_begin`` symbol.
142*61c4878aSAndroid Build Coastguard Worker
143*61c4878aSAndroid Build Coastguard Worker.. py:function:: find_matching_elf(uuid: bytes, search_dir: Path) -> \
144*61c4878aSAndroid Build Coastguard Worker                     Path | None
145*61c4878aSAndroid Build Coastguard Worker
146*61c4878aSAndroid Build Coastguard Worker  Recursively searches a directory for an ELF file with a matching UUID.
147*61c4878aSAndroid Build Coastguard Worker
148*61c4878aSAndroid Build Coastguard Worker  Warning: This can take on the order of several seconds.
149*61c4878aSAndroid Build Coastguard Worker
150*61c4878aSAndroid Build Coastguard WorkerPython utility
151*61c4878aSAndroid Build Coastguard Worker==============
152*61c4878aSAndroid Build Coastguard WorkerGNU build IDs can be parsed out of ELF files using the ``build_id`` python tool.
153*61c4878aSAndroid Build Coastguard WorkerSimply point the tool to a binary with a GNU build ID and the build ID will be
154*61c4878aSAndroid Build Coastguard Workerprinted out if it is found.
155*61c4878aSAndroid Build Coastguard Worker
156*61c4878aSAndroid Build Coastguard Worker.. code-block:: sh
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard Worker   $ python -m pw_build_info.build_id my_device_image.elf
159*61c4878aSAndroid Build Coastguard Worker   d43cce74f18522052f77a1fa3fb7a25fe33f40dd
160*61c4878aSAndroid Build Coastguard Worker
161*61c4878aSAndroid Build Coastguard Worker---------------
162*61c4878aSAndroid Build Coastguard WorkerGit Commit Info
163*61c4878aSAndroid Build Coastguard Worker---------------
164*61c4878aSAndroid Build Coastguard WorkerIf your project uses ``git`` and builds with ``bazel``, you can use the
165*61c4878aSAndroid Build Coastguard Workerauto-generated ``//pw_build_info:git_build_info`` header to embed which git
166*61c4878aSAndroid Build Coastguard Workercommit your binary was built from. This requires a bit of setup to use.
167*61c4878aSAndroid Build Coastguard Worker
168*61c4878aSAndroid Build Coastguard WorkerBazel Workspace Status Command
169*61c4878aSAndroid Build Coastguard Worker==============================
170*61c4878aSAndroid Build Coastguard WorkerBazel supports running a command to inspect the current workspace status each
171*61c4878aSAndroid Build Coastguard Workerbuild. Add the following to your ``.bazelrc,`` replacing the ``path/to/pigweed``
172*61c4878aSAndroid Build Coastguard Workerportion with where you have pigweed checked out.
173*61c4878aSAndroid Build Coastguard Worker
174*61c4878aSAndroid Build Coastguard Worker.. code-block::
175*61c4878aSAndroid Build Coastguard Worker
176*61c4878aSAndroid Build Coastguard Worker   build --workspace_status_command=path/to/pigweed/pw_build_info/git_workspace_status_command.sh
177*61c4878aSAndroid Build Coastguard Worker
178*61c4878aSAndroid Build Coastguard WorkerUse ``pw_build_info/git_build_info.h`` Header
179*61c4878aSAndroid Build Coastguard Worker=============================================
180*61c4878aSAndroid Build Coastguard WorkerAdd generated header directly to the target where you want to use it.
181*61c4878aSAndroid Build Coastguard Worker
182*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
183*61c4878aSAndroid Build Coastguard Worker
184*61c4878aSAndroid Build Coastguard Worker   cc_binary(
185*61c4878aSAndroid Build Coastguard Worker     name = "main",
186*61c4878aSAndroid Build Coastguard Worker     srcs = [
187*61c4878aSAndroid Build Coastguard Worker       "main.cc",
188*61c4878aSAndroid Build Coastguard Worker       "@pigweed//pw_build_info:git_build_info",
189*61c4878aSAndroid Build Coastguard Worker     ]
190*61c4878aSAndroid Build Coastguard Worker   )
191*61c4878aSAndroid Build Coastguard Worker
192*61c4878aSAndroid Build Coastguard WorkerInclude the header. The following constants are available:
193*61c4878aSAndroid Build Coastguard Worker
194*61c4878aSAndroid Build Coastguard Worker* ``pw::build_info::kGitCommit``: The git commit this binary was built from.
195*61c4878aSAndroid Build Coastguard Worker* ``pw::build_info::kGitTreeDirty``: True if there were any uncommitted changes.
196*61c4878aSAndroid Build Coastguard Worker
197*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker   #include "pw_build_info/git_build_info.h"
200*61c4878aSAndroid Build Coastguard Worker   #include "pw_string/string.h"
201*61c4878aSAndroid Build Coastguard Worker   #include "pw_log/log.h"
202*61c4878aSAndroid Build Coastguard Worker
203*61c4878aSAndroid Build Coastguard Worker   int main() {
204*61c4878aSAndroid Build Coastguard Worker     PW_LOG_INFO("kGitCommit %s", pw::InlineString<40>(pw::build_info::kGitCommit).c_str());
205*61c4878aSAndroid Build Coastguard Worker     PW_LOG_INFO("kGitTreeDirty %d", pw::build_info::kGitTreeDirty);
206*61c4878aSAndroid Build Coastguard Worker     return 0;
207*61c4878aSAndroid Build Coastguard Worker   }
208*61c4878aSAndroid Build Coastguard Worker
209*61c4878aSAndroid Build Coastguard WorkerMore info about `bazel workspace status commands <https://bazel.build/docs/user-manual#workspace-status-command>`__.
210