pw_build_info: Fix linux build ID compatibility
Fixes the GN integration for build ID build sysetem integration.
Change-Id: I88446566b53357dae48da1eb1cbb7cdddc5aab8d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/105520
Reviewed-by: Alexei Frolov <frolv@google.com>
Pigweed-Auto-Submit: Armando Montanez <amontanez@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_build_info/BUILD.bazel b/pw_build_info/BUILD.bazel
index ddb0a8b..d7db7fe 100644
--- a/pw_build_info/BUILD.bazel
+++ b/pw_build_info/BUILD.bazel
@@ -15,6 +15,7 @@
load(
"//pw_build:pigweed.bzl",
"pw_cc_library",
+ "pw_cc_test",
)
package(default_visibility = ["//visibility:public"])
@@ -30,8 +31,25 @@
"public/pw_build_info/build_id.h",
],
includes = ["public"],
+ linkopts = [
+ "-Lpw_build_info",
+ "-T$(location add_build_id_to_default_linker_script.ld)",
+ "-Wl,--build-id=sha1",
+ ],
deps = [
+ ":add_build_id_to_default_linker_script.ld",
+ ":build_id_linker_snippet.ld",
"//pw_preprocessor",
"//pw_span",
],
)
+
+pw_cc_test(
+ name = "build_id_test",
+ srcs = ["build_id_test.cc"],
+ deps = [
+ ":build_id",
+ "//pw_span",
+ "//pw_unit_test",
+ ],
+)
diff --git a/pw_build_info/BUILD.gn b/pw_build_info/BUILD.gn
index 3764f53..10560d8 100644
--- a/pw_build_info/BUILD.gn
+++ b/pw_build_info/BUILD.gn
@@ -31,11 +31,11 @@
# default linker script instead of overriding it.
ldflags = [
"-T",
- rebase_path("add_build_id_to_default_script.ld", root_build_dir),
+ rebase_path("add_build_id_to_default_linker_script.ld", root_build_dir),
]
lib_dirs = [ "." ]
- inputs += [ "add_build_id_to_default_script.ld" ]
+ inputs += [ "add_build_id_to_default_linker_script.ld" ]
}
visibility = [ ":*" ]
}
@@ -68,8 +68,21 @@
pw_doc_group("docs") {
sources = [ "docs.rst" ]
- inputs = [ "build_id_linker_snippet.ld" ]
+ inputs = [
+ "add_build_id_to_default_linker_script.ld",
+ "build_id_linker_snippet.ld",
+ ]
}
pw_test_group("tests") {
+ tests = [ ":build_id_test" ]
+}
+
+pw_test("build_id_test") {
+ enable_if = current_os == "linux"
+ deps = [
+ ":build_id",
+ "$dir_pw_span",
+ ]
+ sources = [ "build_id_test.cc" ]
}
diff --git a/pw_build_info/build_id_test.cc b/pw_build_info/build_id_test.cc
new file mode 100644
index 0000000..a3c1c06
--- /dev/null
+++ b/pw_build_info/build_id_test.cc
@@ -0,0 +1,30 @@
+// Copyright 2022 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include "pw_build_info/build_id.h"
+
+#include "gtest/gtest.h"
+#include "pw_span/span.h"
+
+namespace pw::build_info {
+namespace {
+
+TEST(BuildId, BuildIdSize) {
+ span build_id = BuildId();
+ EXPECT_GT(build_id.size(), 0u);
+ EXPECT_LE(build_id.size(), kMaxBuildIdSizeBytes);
+}
+
+} // namespace
+} // namespace pw::build_info
diff --git a/pw_build_info/docs.rst b/pw_build_info/docs.rst
index 18ac9d7..4e1500f 100644
--- a/pw_build_info/docs.rst
+++ b/pw_build_info/docs.rst
@@ -5,7 +5,7 @@
=============
.. warning::
- This module is under construction and may not be ready for use.
+ This module is incomplete, but the build ID integration is ready for use.
pw_build_info provides tooling, build integration, and libraries for generating,
embedding, and parsing build-related information that is embedded into
@@ -16,7 +16,7 @@
complex questions about compiled binaries.
-------------
-GNU Build IDs
+GNU build IDs
-------------
This module provides C++ and python libraries for reading GNU build IDs
generated by the link step of a C++ executable. These build IDs are essentially
@@ -28,20 +28,91 @@
generate GNU build IDs. Windows and macOS binaries cannot use this target as
the implementation of GNU build IDs depends on the ELF file format.
-Embedded targets must first explicitly place the GNU build ID section into a
-non-info section of their linker script that is readable by the firmware. The
-following linker snippet may be copied into a read-only section (just like the
-.rodata or .text sections):
+Getting started
+===============
+To generate GNU build IDs as part of your firmware image, you'll need to update
+your embedded target's linker script.
+
+Updating your linker script
+---------------------------
+If your project has a custom linker scipt, you'll need to update it to include
+a section to contain the generated build ID. This section should be placed
+alongside the ``.text`` and ``.rodata`` sections, and named
+``.note.gnu.build-id``.
+
+.. code-block:: none
+
+ /* Main executable code. */
+ .code : ALIGN(8)
+ {
+ . = ALIGN(8);
+ /* Application code. */
+ *(.text)
+ *(.text*)
+ KEEP(*(.init))
+ KEEP(*(.fini))
+ ...
+ } >FLASH
+
+ /* GNU build ID section. */
+ .note.gnu.build-id :
+ {
+ . = ALIGN(4);
+ gnu_build_id_begin = .;
+ *(.note.gnu.build-id);
+ } >FLASH
+
+ /* Explicitly initialized global and static data. (.data) */
+ .static_init_ram : ALIGN(8)
+ {
+ *(.data)
+ *(.data*)
+ ...
+ } >RAM AT> FLASH
+
+
+Alternatively, you can copy the following linker snippet into a pre-existing
+section. This makes reading the build ID slower, so whenever possibe prefer
+creating a dedicated section for the build ID.
.. literalinclude:: build_id_linker_snippet.ld
-This snippet may be placed directly into an existing section, as it is not
-required to live in its own dedicated section. When opting to create a
-dedicated section for the build ID to reside in, Pigweed recommends naming the
-section ``.note.gnu.build-id`` as it makes it slightly easier for tools to
-parse the build ID out of a binary. After the linker script has been properly
-set up, the ``build_id`` GN target may be used to read the build ID at
-runtime.
+An example of directly inserting a build ID into an existing section is
+provided below:
+
+.. code-block:: none
+
+ /* Main executable code. */
+ .code : ALIGN(8)
+ {
+ . = ALIGN(8);
+ /* Application code. */
+ *(.text)
+ *(.text*)
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ . = ALIGN(4);
+ gnu_build_id_begin = .;
+ *(.note.gnu.build-id);
+
+ ...
+ } >FLASH
+
+If your linker script is auto-generated, you may be able to use the
+``INSERT AFTER`` linker script directive to append the build ID as seen in the
+Linux host support for pw_build_info's build ID integration:
+
+.. literalinclude:: add_build_id_to_default_linker_script.ld
+
+Generating the build ID
+-----------------------
+When you depend on ``"$dir_pw_build_info:build_id``, a GNU build ID will be
+generated at the final link step of any binaries that depend on that library
+(whether directly or transitively). Those binaries will be able to read the
+build ID by calling ``pw::build_info::BuildId()``. Note that the build ID
+is not a string, but raw binary data, so to print it you'll need to convert
+it to hex or base64.
Python API reference
====================