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