CMake: Check that backend targets are defined

Create a generator expression that fails to evaluate if a backend does
not exist. This avoids confusing compilation errors.

Change-Id: I5475fa53bf604b6cc445d9774b96fd8d5eb66f09
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/44564
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Vic Yang <victoryang@google.com>
diff --git a/pw_build/docs.rst b/pw_build/docs.rst
index c974828..c2fe2f5 100644
--- a/pw_build/docs.rst
+++ b/pw_build/docs.rst
@@ -476,6 +476,18 @@
 * Temporarily override a backend by setting it interactively with ``ccmake`` or
   ``cmake-gui``.
 
+If the backend is set to a build target that does not exist, there will be an
+error message like the following:
+
+.. code-block::
+
+  CMake Error at pw_build/pigweed.cmake:244 (add_custom_target):
+  Error evaluating generator expression:
+
+    $<TARGET_PROPERTY:my_backend_that_does_not_exist,TYPE>
+
+  Target "my_backend_that_does_not_exist" not found.
+
 Toolchain setup
 ---------------
 In CMake, the toolchain is configured by setting CMake variables, as described
diff --git a/pw_build/pigweed.cmake b/pw_build/pigweed.cmake
index a004cd4..37b0212 100644
--- a/pw_build/pigweed.cmake
+++ b/pw_build/pigweed.cmake
@@ -238,6 +238,14 @@
   set("${NAME}_BACKEND" "${arg_DEFAULT_BACKEND}" CACHE STRING
       "Backend for ${NAME}")
 
+  # This target is never used; it simply tests that the specified backend
+  # actually exists in the build. The generator expression will fail to evaluate
+  # if the target is not defined.
+  add_custom_target(_pw_check_that_backend_for_${NAME}_is_defined
+    COMMAND
+      ${CMAKE_COMMAND} -E echo "$<TARGET_PROPERTY:${${NAME}_BACKEND},TYPE>"
+  )
+
   # Define the facade library, which is used by the backend to avoid circular
   # dependencies.
   add_library("${NAME}.facade" INTERFACE)