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
 ====================