pw_assert: Extend CMake support

Change-Id: Ia9ed5afce023bcb046205de407b769a042285857
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/96820
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_assert/BUILD.gn b/pw_assert/BUILD.gn
index 5bd10fc..017d435 100644
--- a/pw_assert/BUILD.gn
+++ b/pw_assert/BUILD.gn
@@ -196,7 +196,7 @@
 # provided. However, since this doesn't depend on the backend it re-includes
 # the facade headers.
 pw_test("assert_facade_test") {
-  configs = [ ":public_include_path" ]  # For internal/assert_impl.h
+  configs = [ ":public_include_path" ]  # For internal/check_impl.h
   sources = [
     "assert_facade_test.cc",
     "fake_backend.cc",
@@ -204,8 +204,9 @@
     "pw_assert_test/fake_backend.h",
   ]
   deps = [
-    ":assert",
+    ":pw_assert",
     dir_pw_status,
+    dir_pw_string,
   ]
 
   # TODO(frolv): Fix this test on the QEMU target.
diff --git a/pw_assert/CMakeLists.txt b/pw_assert/CMakeLists.txt
index 5c327ce..766ae9c 100644
--- a/pw_assert/CMakeLists.txt
+++ b/pw_assert/CMakeLists.txt
@@ -16,12 +16,132 @@
 
 pw_add_module_config(pw_assert_CONFIG)
 
-pw_add_facade(pw_assert
+pw_add_module_library(pw_assert
   PUBLIC_DEPS
-    pw_preprocessor
+    pw_assert.check
+    pw_assert.assert
+    pw_assert.config
+)
+
+pw_add_module_library(pw_assert.config
+  HEADERS
+    public/pw_assert/config.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
     ${pw_assert_CONFIG}
 )
-target_include_directories(pw_assert
-  INTERFACE
-    assert_compatibility_public_overrides
+
+# Deprecate this once all users have been migrated off pw_assert_BACKEND to
+# instead set pw_assert.assert_BACKEND and pw_assert.check_BACKEND and use the
+# separate assert and check facades directly.
+if(DEFINED pw_assert_BACKEND)
+  message(DEPRECATION "pw_set_backend(pw_assert ...) (AKA pw_assert_BACKEND) "
+                      "has been deprecated and replaced with the "
+                      "pw_assert.check and pw_assert.assert facades.")
+  pw_set_backend(pw_assert.check "${pw_assert_BACKEND}")
+  pw_set_backend(pw_assert.assert pw_assert.assert_compatibility_backend)
+
+  pw_add_module_library(pw_assert.facade
+    PUBLIC_DEPS
+      pw_assert.check.facade
+  )
+endif()
+
+pw_add_facade(pw_assert.assert
+  HEADERS
+    public/pw_assert/assert.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_assert.config
 )
+
+pw_add_facade(pw_assert.check
+  HEADERS
+    public/pw_assert/check.h
+    public/pw_assert/internal/check_impl.h
+    public/pw_assert/short.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_assert.config
+    pw_preprocessor
+)
+
+# Warning: The assert facade is in a transitional state, and this target is
+# likely to be removed as the pw_assert API is reassessed. (pwbug/246)
+pw_add_module_library(pw_assert.assert_compatibility_backend
+  HEADERS
+    assert_compatibility_public_overrides/pw_assert_backend/assert_backend.h
+  PUBLIC_INCLUDES
+    assert_compatibility_public_overrides
+  PUBLIC_DEPS
+    pw_preprocessor
+)
+
+pw_add_module_library(pw_assert.print_and_abort
+  HEADERS
+    public/pw_assert/internal/print_and_abort.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_assert.config
+)
+
+# This backend to pw_assert's PW_CHECK()/PW_DCHECK() macros prints the assert
+# expression, evaluated expression, file/line number, function, and user message
+# with printf, then aborts. It is intended for use with host builds.
+pw_add_module_library(pw_assert.print_and_abort_check_backend
+  HEADERS
+    print_and_abort_check_public_overrides/pw_assert_backend/check_backend.h
+  PUBLIC_INCLUDES
+    print_and_abort_check_public_overrides
+  PUBLIC_DEPS
+    pw_assert.print_and_abort
+)
+
+# This backend to pw_assert's PW_ASSERT()/PW_DASSERT() macros prints the assert
+# expression, file/line number, and function with printf, then aborts. It is
+# intended for use with host builds.
+pw_add_module_library(pw_assert.print_and_abort_assert_backend
+  HEADERS
+    print_and_abort_assert_public_overrides/pw_assert_backend/assert_backend.h
+  PUBLIC_INCLUDES
+    print_and_abort_assert_public_overrides
+  PUBLIC_DEPS
+    pw_assert.config
+    pw_assert.print_and_abort
+)
+
+pw_add_test(pw_assert.assert_facade_test
+  SOURCES
+    assert_facade_test.cc
+    fake_backend.cc
+    public/pw_assert/internal/check_impl.h
+    pw_assert_test/fake_backend.h
+  DEPS
+    pw_assert
+    pw_status
+    pw_string
+  GROUPS
+    modules
+    pw_assert
+)
+
+if((NOT "${pw_assert.assert_BACKEND}" STREQUAL
+    "pw_assert.assert.NO_BACKEND_SET") AND
+   (NOT "${pw_assert.check_BACKEND}" STREQUAL
+    "pw_assert.check.NO_BACKEND_SET"))
+  pw_add_test(pw_assert.assert_backend_compile_test
+    SOURCES
+      assert_backend_compile_test.cc
+      assert_backend_compile_test_c.c
+    DEPS
+      pw_assert
+      pw_status
+    GROUPS
+      modules
+      pw_assert
+  )
+endif()
diff --git a/pw_assert_basic/BUILD.bazel b/pw_assert_basic/BUILD.bazel
index efc1ede..2ec07f1 100644
--- a/pw_assert_basic/BUILD.bazel
+++ b/pw_assert_basic/BUILD.bazel
@@ -67,9 +67,8 @@
     deps = [
         ":handler_facade",
         ":headers",
-        "//pw_assert:facade",
         "//pw_preprocessor",
-        "//pw_string",
+        "//pw_string:string_builder",
         "//pw_sys_io",
     ],
 )
diff --git a/pw_assert_basic/BUILD.gn b/pw_assert_basic/BUILD.gn
index 09c190f..9ccc410 100644
--- a/pw_assert_basic/BUILD.gn
+++ b/pw_assert_basic/BUILD.gn
@@ -48,26 +48,19 @@
   ]
   public = [
     "public/pw_assert_basic/assert_basic.h",
-    "public/pw_assert_basic/handler.h",
     "public_overrides/pw_assert_backend/check_backend.h",
   ]
+  public_deps = [ ":handler.facade" ]
 }
 
 # The assert backend deps that might cause circular dependencies, since
 # pw_assert is so ubiquitous. These deps are kept separate so they can be
 # depended on from elsewhere.
 pw_source_set("pw_assert_basic.impl") {
-  public_deps = [
-    dir_pw_result,
-    dir_pw_string,
-    dir_pw_sys_io,
-  ]
   deps = [
-    ":pw_assert_basic",
+    ":handler",
+    "$dir_pw_assert:assert_compatibility_backend",
     "$dir_pw_assert:config",
-    "$dir_pw_assert:facade",
-    "$dir_pw_preprocessor",
-    pw_assert_basic_HANDLER_BACKEND,
   ]
   sources = [ "assert_basic.cc" ]
 }
@@ -86,10 +79,9 @@
   deps = [
     ":handler.facade",
     "$dir_pw_assert:config",
-    "$dir_pw_assert:facade",
     "$dir_pw_preprocessor",
-    "$dir_pw_sys_io:facade",  # Only pull in the facade to avoid circular deps
-    dir_pw_status,
+    "$dir_pw_string:builder",
+    "$dir_pw_sys_io",
   ]
   sources = [ "basic_handler.cc" ]
 }
diff --git a/pw_assert_basic/CMakeLists.txt b/pw_assert_basic/CMakeLists.txt
index ec2121e..0cd61ac 100644
--- a/pw_assert_basic/CMakeLists.txt
+++ b/pw_assert_basic/CMakeLists.txt
@@ -14,11 +14,41 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
-pw_auto_add_simple_module(pw_assert_basic
-  IMPLEMENTS_FACADE
-    pw_assert
-  PRIVATE_DEPS
+pw_add_facade(pw_assert_basic.handler
+  HEADERS
+    public/pw_assert_basic/handler.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
     pw_preprocessor
-    pw_string
+)
+
+# TODO(pwbug/246): This backend implements pw_assert's check backend and the
+# temporary compatibility C ABI (pw_assert_HandleFailure()).
+pw_add_module_library(pw_assert_basic.check_backend
+  HEADERS
+    public_overrides/pw_assert_backend/check_backend.h
+    public/pw_assert_basic/assert_basic.h
+  PUBLIC_INCLUDES
+    public
+    public_overrides
+  PUBLIC_DEPS
+    pw_assert_basic.handler
+  SOURCES
+    assert_basic.cc
+  PRIVATE_DEPS
+    pw_assert_basic.handler
+    pw_assert.config
+    pw_assert.assert_compatibility_backend
+)
+
+pw_add_module_library(pw_assert_basic.basic_handler
+  SOURCES
+    basic_handler.cc
+  PRIVATE_DEPS
+    pw_assert_basic.handler.facade
+    pw_assert.config
+    pw_preprocessor
+    pw_string.string_builder
     pw_sys_io
 )
diff --git a/pw_assert_log/BUILD.gn b/pw_assert_log/BUILD.gn
index 7161c34..a5fa0b8 100644
--- a/pw_assert_log/BUILD.gn
+++ b/pw_assert_log/BUILD.gn
@@ -41,6 +41,7 @@
   public =
       [ "check_backend_public_overrides/pw_assert_backend/check_backend.h" ]
   deps = [
+    "$dir_pw_assert:assert_compatibility_backend",
     "$dir_pw_assert:config",
     "$dir_pw_assert:facade",
     "$dir_pw_preprocessor",
diff --git a/pw_assert_log/CMakeLists.txt b/pw_assert_log/CMakeLists.txt
index 96776e0..dff5b18 100644
--- a/pw_assert_log/CMakeLists.txt
+++ b/pw_assert_log/CMakeLists.txt
@@ -14,11 +14,35 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
-pw_auto_add_simple_module(pw_assert_log
-  IMPLEMENTS_FACADE
-    pw_assert
+# This backend to pw_assert's PW_CHECK()/PW_CRASH() macros via PW_LOG.
+pw_add_module_library(pw_assert_log.check_backend
+  HEADERS
+    check_backend_public_overrides/pw_assert_backend/check_backend.h
+    public/pw_assert_log/check_log.h
+  PUBLIC_INCLUDES
+    check_backend_public_overrides
+    public
   PUBLIC_DEPS
     pw_log
+    pw_preprocessor
+  SOURCES
+    assert_log.cc
   PRIVATE_DEPS
+    pw_assert.config
+    pw_assert.assert_compatibility_backend
+)
+
+# This backend to pw_assert's PW_ASSERT() macros via PW_LOG. It is intended only
+# for use with PW_LOG backends which are constexpr compatible such as
+# pw_log_android.
+pw_add_module_library(pw_assert_log.assert_backend
+  HEADERS
+    assert_backend_public_overrides/pw_assert_backend/assert_backend.h
+    public/pw_assert_log/assert_log.h
+  PUBLIC_INCLUDES
+    assert_backend_public_overrides
+    public
+  PUBLIC_DEPS
+    pw_log
     pw_preprocessor
 )
diff --git a/pw_assert_tokenized/CMakeLists.txt b/pw_assert_tokenized/CMakeLists.txt
new file mode 100644
index 0000000..6c534b7
--- /dev/null
+++ b/pw_assert_tokenized/CMakeLists.txt
@@ -0,0 +1,57 @@
+# Copyright 2020 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($ENV{PW_ROOT}/pw_build/pigweed.cmake)
+
+pw_add_module_library(pw_assert_tokenized.handler
+  HEADERS
+    public/pw_assert_tokenized/handler.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_preprocessor
+  SOURCES
+    log_handler.cc
+  PRIVATE_DEPS
+    pw_assert.config
+    pw_base64
+    pw_bytes
+    pw_log
+    pw_log_tokenized
+)
+
+pw_add_module_library(pw_assert_tokenized.assert_backend
+  HEADERS
+    assert_public_overrides/pw_assert_backend/assert_backend.h
+    public/pw_assert_tokenized/assert_tokenized.h
+  PUBLIC_INCLUDES
+    assert_public_overrides
+    public
+  PUBLIC_DEPS
+    pw_assert_tokenized.handler
+    pw_tokenizer
+)
+
+pw_add_module_library(pw_assert_tokenized.check_backend
+  HEADERS
+    check_public_overrides/pw_assert_backend/check_backend.h
+    public/pw_assert_tokenized/check_tokenized.h
+  PUBLIC_INCLUDES
+    check_public_overrides
+    public
+  PUBLIC_DEPS
+    pw_assert_tokenized.handler
+    pw_log_tokenized
+    pw_tokenizer
+)
diff --git a/pw_toolchain/host_clang/toolchain.cmake b/pw_toolchain/host_clang/toolchain.cmake
index ae34701..6010f36 100644
--- a/pw_toolchain/host_clang/toolchain.cmake
+++ b/pw_toolchain/host_clang/toolchain.cmake
@@ -24,7 +24,8 @@
 # pw_set_backend(pw_unit_test.main pw_unit_test.logging_main)
 
 # Configure backend for assert facade.
-pw_set_backend(pw_assert pw_assert_basic)
+pw_set_backend(pw_assert.check pw_assert.print_and_abort_check_backend)
+pw_set_backend(pw_assert.assert pw_assert.print_and_abort_assert_backend)
 
 # Configure backend for logging facade.
 pw_set_backend(pw_log pw_log_basic)
diff --git a/pw_toolchain/host_gcc/toolchain.cmake b/pw_toolchain/host_gcc/toolchain.cmake
index 4529f69..b30fd67 100644
--- a/pw_toolchain/host_gcc/toolchain.cmake
+++ b/pw_toolchain/host_gcc/toolchain.cmake
@@ -24,7 +24,8 @@
 # pw_set_backend(pw_unit_test.main pw_unit_test.logging_main)
 
 # Configure backend for assert facade.
-pw_set_backend(pw_assert pw_assert_basic)
+pw_set_backend(pw_assert.check pw_assert.print_and_abort_check_backend)
+pw_set_backend(pw_assert.assert pw_assert.print_and_abort_assert_backend)
 
 # Configure backend for logging facade.
 pw_set_backend(pw_log pw_log_basic)