GN build: Add application images group and docs

This change adds a top-level build group for application images, as well
as documentation for the upstream GN build layout.

Change-Id: Ib559a9747e9758648cd97b5192126028a01526f2
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/13520
Commit-Queue: Alexei Frolov <frolv@google.com>
Reviewed-by: Armando Montanez <amontanez@google.com>
Reviewed-by: Rob Oliver <rgoliver@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 745b9c4..30ba175 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -30,6 +30,9 @@
   #   size_optimized
   #   speed_optimized
   pw_optimization_level = "debug"
+
+  # List of application image GN targets specific to the Pigweed target.
+  pw_TARGET_APPLICATIONS = []
 }
 
 # Enumerate all of the different targets that upstream Pigweed will build by
@@ -88,6 +91,7 @@
     if (pw_docgen_BUILD_DOCS) {
       deps += [ "$dir_pigweed/docs" ]
     } else {
+      deps += [ ":apps" ]
       if (pw_unit_test_AUTOMATIC_RUNNER == "") {
         # Without a test runner defined, build the tests but don't run them.
         deps += [ ":pw_module_tests" ]
@@ -106,6 +110,14 @@
 
 # Prevent the default toolchain from parsing any other BUILD.gn files.
 if (current_toolchain != default_toolchain) {
+  group("apps") {
+    # Application images built for all targets.
+    deps = []
+
+    # Add target-specific images.
+    deps += pw_TARGET_APPLICATIONS
+  }
+
   group("host_tools") {
     deps = [
       "$dir_pw_target_runner/go:simple_client",
@@ -113,13 +125,6 @@
     ]
   }
 
-  group("pw_facades") {
-    deps = [
-      "$dir_pw_cpu_exception",
-      "$dir_pw_sys_io",
-    ]
-  }
-
   # All Pigweed modules that can be built using gn. This is not built by default.
   group("pw_modules") {
     deps = [
@@ -128,6 +133,7 @@
       "$dir_pw_base64",
       "$dir_pw_bytes",
       "$dir_pw_checksum",
+      "$dir_pw_cpu_exception",
       "$dir_pw_polyfill",
       "$dir_pw_preprocessor",
       "$dir_pw_protobuf",
@@ -136,6 +142,7 @@
       "$dir_pw_status",
       "$dir_pw_stream",
       "$dir_pw_string",
+      "$dir_pw_sys_io",
       "$dir_pw_trace",
       "$dir_pw_unit_test",
       "$dir_pw_varint",
diff --git a/docs/BUILD.gn b/docs/BUILD.gn
index 0560e15..88b2c99 100644
--- a/docs/BUILD.gn
+++ b/docs/BUILD.gn
@@ -50,6 +50,7 @@
     "../CODE_OF_CONDUCT.md",
     "../CONTRIBUTING.md",
     "../README.md",
+    "build_system.rst",
     "index.rst",
     "module_guides.rst",
     "targets.rst",
diff --git a/docs/build_system.rst b/docs/build_system.rst
new file mode 100644
index 0000000..a9d465c
--- /dev/null
+++ b/docs/build_system.rst
@@ -0,0 +1,173 @@
+.. _chapter-build-system:
+
+============
+Build system
+============
+
+Pigweed's primary build system is `GN`_, which is used for all upstream
+development. Some other common build systems are supported for integration into
+existing project, which are described in :ref:`chapter-pw-build`. We recommend
+using GN where possible.
+
+.. _GN: https://gn.googlesource.com/gn/
+
+This document describes Pigweed's upstream build structure.
+
+.. note::
+  A quick note on terminology: the word "target" is overloaded within GN (and
+  Pigweed)---it can refer to either a GN build target, such as a ``source_set``
+  or ``executable``, or to an output platform (e.g. a specific board, device, or
+  system).
+
+  To avoid confusing the two, we refer to the former as "GN targets" and the
+  latter as "Pigweed targets".
+
+.gn
+===
+The entrypoint to the GN build is the ``.gn`` file, which defines the project's
+root directory (henceforth ``//``). In Pigweed, its only purpose is to point GN
+to the location of the BUILDCONFIG file.
+
+BUILDCONFIG.gn
+==============
+``//BUILDCONFIG.gn`` configures the GN build by defining global configuration
+options. Most of Pigweed's configuration is left to individual build targets,
+so the BUILDCONFIG file is relatively empty. It sets Pigweed's default
+toolchain, which GN requires before evaluating any BUILD files.
+
+//BUILD.gn
+==========
+The root ``BUILD.gn`` file defines all of the libraries, images, tests, and
+binaries built within Pigweed. These are split across a few logical groups,
+which are described below. In order to build a GN target, it *must* be listed in
+one of the groups in this file.
+
+``//BUILD.gn`` is also responsible for enumerating each of the Pigweed targets
+that Pigweed supports. These targets are defined as toolchains providing their
+custom configuration options. ``/BUILD.gn`` instantiates a version of its GN
+target groups for each of these toolchains.
+
+.. warning::
+  Pigweed's default toolchain is never used, so it is set to a dummy toolchain
+  which doesn't define any tools. ``//BUILD.gn`` contains conditions which check
+  that the current toolchain is not the default before declaring any GN target
+  dependencies to prevent the default toolchain from evaluating any other BUILD
+  files. All GN targets added to the build must be placed in one of these
+  conditional scopes.
+
+Groups
+------
+
+apps
+^^^^
+This group defines the application images built in Pigweed. It lists all of the
+common images built across all Pigweed targets, such as modules' example
+executables. Each Pigweed target can additionally provide its own specific
+images through the ``pw_TARGET_APPLICATIONS`` build arg, which is included by
+this group.
+
+host_tools
+^^^^^^^^^^
+This group defines host-side tooling binaries built for Pigweed.
+
+pw_modules
+^^^^^^^^^^
+This group lists the main libraries for all of Pigweed's modules.
+
+pw_module_tests
+^^^^^^^^^^^^^^^
+All modules' unit tests are collected here, so that they can all be run at once.
+
+pigweed_default
+^^^^^^^^^^^^^^^
+This group defines everything built in a Pigweed build invocation by collecting
+the above groups and conditionally adding them, based on the Pigweed target
+configuration. Generally, new dependencies should not be added here; instead use
+one of the groups listed above.
+
+The ``pigweed_default`` group is instantiated for each of the Pigweed target
+toolchains.
+
+Pigweed target instantiations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+These groups wrap ``pigweed_default`` with a specific target toolchain. They are
+named after the Pigweed target, e.g. ``host_clang``, ``stm32f429i``, etc.
+
+Pigweed targets
+===============
+Each Pigweed target is defined as a GN toolchain which provides its own build
+tool and output binary configs, and custom overrides for Pigweed's build
+configuration arguments. For more information on Pigweed's target system, as
+well as each of the supported targets, refer to :ref:`chapter-targets`.
+
+Usage examples
+==============
+
+Building a custom executable
+----------------------------
+
+1. Define your executable GN target using the ``pw_executable`` template.
+
+   .. code::
+
+     # //foo/BUILD.gn
+     pw_executable("foo") {
+       sources = [ "main.cc" ]
+       deps = [ ":libfoo" ]
+     }
+
+2. In the root ``BUILD.gn`` file, add the executable's GN target to the ``apps``
+   group.
+
+   .. code::
+
+     # //BUILD.gn
+     group("apps") {
+       deps = [
+         # ...
+         "//foo",  # Shorthand for //foo:foo
+       ]
+     }
+
+3. Run the ninja build to compile your executable. The apps group is built by
+   default, so there's no need to provide a target. The executable will be
+   compiled for every supported Pigweed target.
+
+   .. code::
+
+     ninja -C out
+
+   Alternatively, build your executable by itself by specifying its path to
+   Ninja. When building a GN target manually, the Pigweed target for which it
+   is built must be specified on the Ninja command line.
+
+   For example, to build for the Pigweed target ``host_gcc_debug``:
+
+   .. code::
+
+     ninja -C out host_gcc_debug/obj/foo/bin/foo
+
+   .. note::
+
+     The path passed to Ninja is a filesystem path within the ``out`` directory,
+     rather than a GN path. This path can be found by running ``gn outputs``.
+
+4. Retrieve your compiled binary from the out directory. It is located at the
+   path
+
+   .. code::
+
+     out/<pw_target>/obj/<gn_path>/{bin,test}/<executable>
+
+   where ``pw_target`` is the Pigweed target for which the binary was built,
+   ``gn_path`` is the GN path to the BUILD.gn file defining the executable,
+   and ``executable`` is the executable's GN target name (potentially with an
+   extension). Note that the executable is located within a ``bin`` subdirectory
+   in the module (or ``test`` for unit tests defined with ``pw_test``).
+
+   For example, the ``foo`` executable defined above and compiled for the
+   Pigweed target stm32f429i_disc1_debug is found at:
+
+   .. code::
+
+     out/stm32f429i_disc1_debug/obj/foo/bin/foo
diff --git a/docs/index.rst b/docs/index.rst
index d8b5e12..804f86a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -15,5 +15,6 @@
   docs/embedded_cpp_guide
   docs/style_guide
   targets
+  build_system
   docs/module_structure
   module_guides
diff --git a/docs/module_structure.rst b/docs/module_structure.rst
index 5a5858e..2f51ef0 100644
--- a/docs/module_structure.rst
+++ b/docs/module_structure.rst
@@ -248,8 +248,6 @@
 7. Add new module to main GN build
 
     - in ``/BUILD.gn`` to ``group("pw_modules")`` using folder alias variable
-    - General modules and backends of facades go in ``pw_modules``, facades go
-      in ``pw_facades``
 
 8. Add test target for new module in ``/BUILD.gn`` to
    ``pw_test_group("pw_module_tests")``
diff --git a/pw_build/docs.rst b/pw_build/docs.rst
index af965f4..50a80bc 100644
--- a/pw_build/docs.rst
+++ b/pw_build/docs.rst
@@ -2,7 +2,7 @@
 
 .. highlight:: sh
 
-.. _chapter-build:
+.. _chapter-pw-build:
 
 --------
 pw_build