build: Fix `all` target in GN build

Fixes the implicit `all` target in the GN/Ninja build.

Change-Id: Id54be2d9aa4a8efd9991db579a7aae4cc41c90b9
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/173050
Reviewed-by: Wyatt Hepler <hepler@google.com>
Pigweed-Auto-Submit: Armando Montanez <amontanez@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
diff --git a/BUILD.gn b/BUILD.gn
index 6b165e7..3f2f5c3 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -25,6 +25,7 @@
 import("$dir_pw_rpc/config.gni")
 import("$dir_pw_rust/rust.gni")
 import("$dir_pw_third_party/ambiq/ambiq.gni")
+import("$dir_pw_third_party/fuzztest/fuzztest.gni")
 import("$dir_pw_third_party/mcuxpresso/mcuxpresso.gni")
 import("$dir_pw_toolchain/c_optimization.gni")
 import("$dir_pw_toolchain/generate_toolchain.gni")
@@ -50,6 +51,10 @@
 
   # List of application image GN targets specific to the Pigweed target.
   pw_TARGET_APPLICATIONS = []
+
+  # Gates known broken configurations from building. This is what allows the
+  # implicit `all` target to work even though there are known broken targets.
+  pw_BUILD_BROKEN_GROUPS = false
 }
 
 # This toolchain is used to force some dependencies to not be parsed by the
@@ -297,15 +302,16 @@
 
 # TODO: b/244604080 - Inline string tests are too big to fit in the QEMU firmware
 # except under a size-optimized build. For now, only build size-optimized.
-#
-# _build_pigweed_default_at_all_optimization_levels("qemu_gcc") {
-#   toolchain_prefix =
-#       "$dir_pigweed/targets/lm3s6965evb_qemu:lm3s6965evb_qemu_gcc_"
-# }
-# _build_pigweed_default_at_all_optimization_levels("qemu_clang") {
-#   toolchain_prefix =
-#       "$dir_pigweed/targets/lm3s6965evb_qemu:lm3s6965evb_qemu_clang_"
-# }
+if (pw_BUILD_BROKEN_GROUPS) {
+  _build_pigweed_default_at_all_optimization_levels("qemu_gcc") {
+    toolchain_prefix =
+        "$dir_pigweed/targets/lm3s6965evb_qemu:lm3s6965evb_qemu_gcc_"
+  }
+  _build_pigweed_default_at_all_optimization_levels("qemu_clang") {
+    toolchain_prefix =
+        "$dir_pigweed/targets/lm3s6965evb_qemu:lm3s6965evb_qemu_clang_"
+  }
+}
 group("qemu_gcc_size_optimized") {
   deps = [ ":pigweed_default($dir_pigweed/targets/lm3s6965evb_qemu:lm3s6965evb_qemu_gcc_size_optimized)" ]
 }
@@ -391,7 +397,7 @@
 group("fuzzers") {
   deps = []
 
-  if (host_os != "win") {
+  if (host_os != "win" && dir_pw_third_party_fuzztest != "") {
     # Coverage-guided fuzzing is only supported on Linux and MacOS using clang.
     # Fuzztest-based fuzzers will run in unit test mode. libFuzzer-based fuzzers
     # will only build.
@@ -415,6 +421,7 @@
 }
 
 group("asan") {
+  # TODO: b/302181521 - asan doesn't work on Windows yet.
   if (host_os != "win") {
     deps = [ ":pw_module_tests.run($dir_pigweed/targets/host:host_clang_asan)" ]
   }
@@ -424,10 +431,14 @@
 # standard library included in the sysroot has a variant built with msan.
 group("msan") {
   # TODO: b/259695498 - msan doesn't work on macOS yet.
-  deps = [ ":pw_module_tests.run($dir_pigweed/targets/host:host_clang_msan)" ]
+  # TODO: b/302181521 - msan doesn't work on Windows yet.
+  if (pw_BUILD_BROKEN_GROUPS) {
+    deps = [ ":pw_module_tests.run($dir_pigweed/targets/host:host_clang_msan)" ]
+  }
 }
 
 group("tsan") {
+  # TODO: b/302181521 - tsan doesn't work on Windows yet.
   if (host_os != "win") {
     deps = [ ":pw_module_tests.run($dir_pigweed/targets/host:host_clang_tsan)" ]
   }
@@ -435,7 +446,8 @@
 
 group("ubsan") {
   # TODO: b/259695498 - ubsan doesn't work on macOS yet.
-  if (host_os != "win" && host_os != "mac") {
+  # TODO: b/302181521 - ubsan doesn't work on Windows yet.
+  if ((host_os != "win" && host_os != "mac") || pw_BUILD_BROKEN_GROUPS) {
     deps =
         [ ":pw_module_tests.run($dir_pigweed/targets/host:host_clang_ubsan)" ]
   }
@@ -443,24 +455,28 @@
 
 group("ubsan_heuristic") {
   # TODO: b/259695498 - ubsan_heuristic doesn't work on macOS yet.
-  if (host_os != "win" && host_os != "mac") {
+  # TODO: b/302181521 - ubsan doesn't work on Windows yet.
+  if ((host_os != "win" && host_os != "mac") || pw_BUILD_BROKEN_GROUPS) {
     deps = [ ":pw_module_tests.run($dir_pigweed/targets/host:host_clang_ubsan_heuristic)" ]
   }
 }
 
 group("runtime_sanitizers") {
-  if (host_os != "win") {
+  if (host_os != "win" || pw_BUILD_BROKEN_GROUPS) {
     deps = [
       ":asan",
       ":tsan",
       ":ubsan",
+    ]
 
+    if (pw_BUILD_BROKEN_GROUPS) {
       # TODO: b/234876100 - msan will not work until the C++ standard library
       # included in the sysroot has a variant built with msan.
-      # ":msan",
+      deps += [ ":msan" ]
 
       # No ubsan_heuristic, which may have false positives.
-    ]
+      deps += [ ":ubsan_heuristic" ]
+    }
   }
 }
 
@@ -561,14 +577,17 @@
   deps = [ ":pigweed_default($_cpp20_tc)" ]
 }
 
-group("build_with_pw_minimal_cpp_stdlib") {
-  _toolchain = "$_internal_toolchains:pw_strict_host_clang_size_optimized_minimal_cpp_stdlib"
+# TODO: b/302175933 - This is currently broken.
+if (pw_BUILD_BROKEN_GROUPS) {
+  group("build_with_pw_minimal_cpp_stdlib") {
+    _toolchain = "$_internal_toolchains:pw_strict_host_clang_size_optimized_minimal_cpp_stdlib"
 
-  # This list of supported modules is incomplete.
-  deps = [
-    "$dir_pw_status($_toolchain)",
-    "$dir_pw_tokenizer($_toolchain)",
-  ]
+    # This list of supported modules is incomplete.
+    deps = [
+      "$dir_pw_status($_toolchain)",
+      "$dir_pw_tokenizer($_toolchain)",
+    ]
+  }
 }
 
 group("host_clang_debug_dynamic_allocation") {
diff --git a/pw_build/gn.rst b/pw_build/gn.rst
index a89320f..be4567f 100644
--- a/pw_build/gn.rst
+++ b/pw_build/gn.rst
@@ -23,15 +23,20 @@
   documentation, recommended tests, and python linting, and static analysis.
 * ``extended_default``: Everything in ``default``, plus some other useful
   configurations that are tested in CQ.
+* ``all``: Attempts to build everything in Pigweed. Note that ``pw package`` may
+  need to be used to enable some branches of the build.
 * ``docs``: Only build Pigweed's documentation.
 * ``stm32f429i``: Only build for the STMicroelectronics STM32F429I-DISC1 board.
 * ``host``: Only build for the host.
 
-Note that the implicit ``all`` target is not actively maintained by Pigweed.
 There are a variety of other groups in the root ``BUILD.gn`` file that may be
 helpful for covering more areas of the build, or for reducing iteration time
 by only building a subset of the default build.
 
+Some currently broken groups are gated behind the ``pw_BUILD_BROKEN_GROUPS``
+build argument. You can set this to ``true`` using ``gn args out`` to try to
+build and debug known broken build configurations.
+
 Build system philosophies
 -------------------------
 While Pigweed's GN build is not hermetic, it strives to adhere to principles of
diff --git a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
index dc62ae3..06d80f1 100755
--- a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
+++ b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
@@ -90,6 +90,14 @@
 #
 # Build presubmit checks
 #
+gn_all = build.GnGenNinja(
+    name='gn_all',
+    path_filter=_BUILD_FILE_FILTER,
+    gn_args=dict(pw_C_OPTIMIZATION_LEVELS=_OPTIMIZATION_LEVELS),
+    ninja_targets=('all',),
+)
+
+
 def gn_clang_build(ctx: PresubmitContext):
     """Checks all compile targets that rely on LLVM tooling."""
     build_targets = [
@@ -1179,6 +1187,7 @@
     cpp_checks.msan,
     docs_build,
     gitmodules.create(gitmodules.Config(allow_submodules=False)),
+    gn_all,
     gn_clang_build,
     gn_combined_build_check,
     module_owners.presubmit_check(),