pw_build: Add module configuration support for CMake

Change-Id: I73a8cb3b91fd9793c001cc289074e0d7ef921eb4
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/75643
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Ewout van Bekkum <ewout@google.com>
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
diff --git a/pw_assert/CMakeLists.txt b/pw_assert/CMakeLists.txt
index 9d9a259..c3d6e9a 100644
--- a/pw_assert/CMakeLists.txt
+++ b/pw_assert/CMakeLists.txt
@@ -14,7 +14,10 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_assert_CONFIG)
+
 pw_add_facade(pw_assert
   PUBLIC_DEPS
     pw_preprocessor
+    ${pw_assert_CONFIG}
 )
diff --git a/pw_build/pigweed.cmake b/pw_build/pigweed.cmake
index 1f9b983..0a3175f 100644
--- a/pw_build/pigweed.cmake
+++ b/pw_build/pigweed.cmake
@@ -290,6 +290,43 @@
   set("${FACADE}_BACKEND" "${BACKEND}" CACHE STRING "Backend for ${NAME}" FORCE)
 endfunction(pw_set_backend)
 
+# Set up the default pw_build_DEFAULT_MODULE_CONFIG.
+set("pw_build_DEFAULT_MODULE_CONFIG" pw_build.empty CACHE STRING
+    "Default implementation for all Pigweed module configurations.")
+
+# Declares a module configuration variable for module libraries to depend on.
+# Configs should be set to libraries which can be used to provide defines
+# directly or though included header files.
+#
+# The configs can be selected either through the pw_set_module_config function
+# to set the pw_build_DEFAULT_MODULE_CONFIG used by default for all Pigweed
+# modules or by selecting a specific one for the given NAME'd configuration.
+#
+# Args:
+#
+#   NAME: name to use for the target which can be depended on for the config.
+function(pw_add_module_config NAME)
+  _pw_parse_argv_strict(pw_add_module_config 1 "" "" "")
+
+  # Declare the module configuration variable for this module.
+  set("${NAME}" "${pw_build_DEFAULT_MODULE_CONFIG}"
+      CACHE STRING "Module configuration for ${NAME}")
+endfunction(pw_add_module_config)
+
+# Sets which config library to use for the given module.
+#
+# This can be used to set a specific module configuration or the default
+# module configuration used for all Pigweed modules:
+#
+#   pw_set_module_config(pw_build_DEFAULT_MODULE_CONFIG my_config)
+#   pw_set_module_config(pw_foo_CONFIG my_foo_config)
+function(pw_set_module_config NAME LIBRARY)
+  _pw_parse_argv_strict(pw_set_module_config 2 "" "" "")
+
+  # Update the module configuration variable.
+  set("${NAME}" "${LIBRARY}" CACHE STRING "Config for ${NAME}" FORCE)
+endfunction(pw_set_module_config)
+
 # Declares a unit test. Creates two targets:
 #
 #  * <TEST_NAME> - the test executable
diff --git a/pw_cpu_exception_cortex_m/CMakeLists.txt b/pw_cpu_exception_cortex_m/CMakeLists.txt
index 06f0592..c8d31fb 100644
--- a/pw_cpu_exception_cortex_m/CMakeLists.txt
+++ b/pw_cpu_exception_cortex_m/CMakeLists.txt
@@ -15,6 +15,15 @@
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 include($ENV{PW_ROOT}/pw_protobuf_compiler/proto.cmake)
 
+pw_add_module_config(pw_cpu_exception_cortex_m_CONFIG)
+
+pw_add_module_library(pw_cpu_exception_cortex_m.config
+  PUBLIC_DEPS
+    ${pw_cpu_exception_cortex_m_CONFIG}
+  HEADERS
+    pw_cpu_exception_cortex_m_private/config.h
+)
+
 pw_add_module_library(pw_cpu_exception_cortex_m.cpu_exception_armv7m
   IMPLEMENTS_FACADES
     pw_cpu_exception.entry
@@ -22,6 +31,7 @@
     pw_preprocessor
   PRIVATE_DEPS
     pw_cpu_exception.handler
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.constants_armv7m
   SOURCES
     entry.cc
@@ -39,6 +49,7 @@
     pw_preprocessor
   PRIVATE_DEPS
     pw_cpu_exception.handler
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.constants_armv8m
   SOURCES
     entry.cc
@@ -53,6 +64,7 @@
   IMPLEMENTS_FACADES
     pw_cpu_exception.support
   PRIVATE_DEPS
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.constants_armv7m
     pw_log
     pw_string
@@ -66,6 +78,7 @@
   IMPLEMENTS_FACADES
     pw_cpu_exception.support
   PRIVATE_DEPS
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.constants_armv8m
     pw_log
     pw_string
@@ -87,6 +100,7 @@
     pw_status
     pw_stream
   PRIVATE_DEPS
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.cpu_state_protos.pwpb
   SOURCES
     proto_dump.cc
@@ -103,6 +117,7 @@
     pw_status
     pw_stream
   PRIVATE_DEPS
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.cpu_state_protos.pwpb
   SOURCES
     proto_dump.cc
@@ -119,6 +134,7 @@
     pw_protobuf
     pw_status
   PRIVATE_DEPS
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.constants_armv7m
     pw_cpu_exception_cortex_m.proto_dump_armv7m
     pw_log
@@ -137,6 +153,7 @@
     pw_protobuf
     pw_status
   PRIVATE_DEPS
+    pw_cpu_exception_cortex_m.config
     pw_cpu_exception_cortex_m.constants_armv8m
     pw_cpu_exception_cortex_m.proto_dump_armv8m
     pw_log
diff --git a/pw_function/CMakeLists.txt b/pw_function/CMakeLists.txt
index 752ae96..2e4d055 100644
--- a/pw_function/CMakeLists.txt
+++ b/pw_function/CMakeLists.txt
@@ -14,10 +14,13 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_function_CONFIG)
+
 pw_auto_add_simple_module(pw_function
   PUBLIC_DEPS
     pw_assert
     pw_preprocessor
+    ${pw_function_CONFIG}
 )
 
 if(Zephyr_FOUND AND CONFIG_PIGWEED_FUNCTION)
diff --git a/pw_kvs/CMakeLists.txt b/pw_kvs/CMakeLists.txt
index cbfa6a0..9b2775f 100644
--- a/pw_kvs/CMakeLists.txt
+++ b/pw_kvs/CMakeLists.txt
@@ -14,6 +14,8 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_kvs_CONFIG)
+
 pw_auto_add_simple_module(pw_kvs
   PUBLIC_DEPS
     pw_containers
@@ -23,6 +25,7 @@
     pw_assert
     pw_bytes
     pw_checksum
+    ${pw_kvs_CONFIG}
     pw_log
     pw_string
 )
diff --git a/pw_log/CMakeLists.txt b/pw_log/CMakeLists.txt
index 4b77940..3aea6a0 100644
--- a/pw_log/CMakeLists.txt
+++ b/pw_log/CMakeLists.txt
@@ -14,7 +14,10 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_log_CONFIG)
+
 pw_add_facade(pw_log
   PUBLIC_DEPS
     pw_preprocessor
+    ${pw_log_CONFIG}
 )
diff --git a/pw_log_basic/CMakeLists.txt b/pw_log_basic/CMakeLists.txt
index 3cf0f74..64724a9 100644
--- a/pw_log_basic/CMakeLists.txt
+++ b/pw_log_basic/CMakeLists.txt
@@ -14,10 +14,13 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_log_basic_CONFIG)
+
 pw_auto_add_simple_module(pw_log_basic
   IMPLEMENTS_FACADE
     pw_log
   PRIVATE_DEPS
     pw_string
     pw_sys_io
+    ${pw_log_basic_CONFIG}
 )
diff --git a/pw_log_tokenized/CMakeLists.txt b/pw_log_tokenized/CMakeLists.txt
index 1c91a64..c0a877b 100644
--- a/pw_log_tokenized/CMakeLists.txt
+++ b/pw_log_tokenized/CMakeLists.txt
@@ -14,9 +14,12 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_log_tokenized_CONFIG)
+
 pw_auto_add_simple_module(pw_log_tokenized
   IMPLEMENTS_FACADE
     pw_log
   PUBLIC_DEPS
     pw_tokenizer
+    ${pw_log_tokenized_CONFIG}
 )
diff --git a/pw_multisink/CMakeLists.txt b/pw_multisink/CMakeLists.txt
index 083c09e..25a01ac 100644
--- a/pw_multisink/CMakeLists.txt
+++ b/pw_multisink/CMakeLists.txt
@@ -14,4 +14,9 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
-pw_auto_add_simple_module(pw_multisink)
+pw_add_module_config(pw_multisink_CONFIG)
+
+pw_auto_add_simple_module(pw_multisink
+  PUBLIC_DEPS
+    ${pw_multisink_CONFIG}
+)
diff --git a/pw_protobuf/CMakeLists.txt b/pw_protobuf/CMakeLists.txt
index 925e1de..8983779 100644
--- a/pw_protobuf/CMakeLists.txt
+++ b/pw_protobuf/CMakeLists.txt
@@ -15,6 +15,15 @@
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 include($ENV{PW_ROOT}/pw_protobuf_compiler/proto.cmake)
 
+pw_add_module_config(pw_protobuf_CONFIG)
+
+pw_add_module_library(pw_protobuf.config
+  PUBLIC_DEPS
+    ${pw_protobuf_CONFIG}
+  HEADERS
+    public/pw_protobuf/config.h
+)
+
 pw_add_module_library(pw_protobuf
   SOURCES
     decoder.cc
@@ -24,6 +33,7 @@
   PUBLIC_DEPS
     pw_assert
     pw_bytes
+    pw_protobuf.config
     pw_result
     pw_status
     pw_stream
diff --git a/pw_status/CMakeLists.txt b/pw_status/CMakeLists.txt
index 2b8194d..d4a7faa 100644
--- a/pw_status/CMakeLists.txt
+++ b/pw_status/CMakeLists.txt
@@ -14,7 +14,12 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
-pw_auto_add_simple_module(pw_status)
+pw_add_module_config(pw_status_CONFIG)
+
+pw_auto_add_simple_module(pw_status
+  PUBLIC_DEPS
+    ${pw_status_CONFIG}
+)
 
 if(Zephyr_FOUND AND CONFIG_PIGWEED_STATUS)
   zephyr_link_libraries(pw_status)
diff --git a/pw_tokenizer/CMakeLists.txt b/pw_tokenizer/CMakeLists.txt
index 78a02c5..bd39805 100644
--- a/pw_tokenizer/CMakeLists.txt
+++ b/pw_tokenizer/CMakeLists.txt
@@ -14,6 +14,15 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_tokenizer_CONFIG)
+
+pw_add_module_library(pw_tokenizer.config
+  PUBLIC_DEPS
+    ${pw_tokenizer_CONFIG}
+  HEADERS
+    public/pw_tokenizer/config.h
+)
+
 pw_add_module_library(pw_tokenizer
   SOURCES
     encode_args.cc
@@ -24,6 +33,7 @@
     pw_polyfill.overrides
     pw_preprocessor
     pw_span
+    pw_tokenizer.config
   PRIVATE_DEPS
     pw_varint
 )
diff --git a/pw_transfer/CMakeLists.txt b/pw_transfer/CMakeLists.txt
index ed31f4f..c15e83f 100644
--- a/pw_transfer/CMakeLists.txt
+++ b/pw_transfer/CMakeLists.txt
@@ -15,6 +15,15 @@
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 include($ENV{PW_ROOT}/pw_protobuf_compiler/proto.cmake)
 
+pw_add_module_config(pw_transfer_CONFIG)
+
+pw_add_module_library(pw_transfer.config
+  PUBLIC_DEPS
+    ${pw_transfer_CONFIG}
+  HEADERS
+    public/pw_transfer/internal/config.h
+)
+
 pw_add_module_library(pw_transfer
   PUBLIC_DEPS
     pw_assert
@@ -55,6 +64,7 @@
     pw_stream
     pw_sync.interrupt_spin_lock
     pw_sync.lock_annotations
+    pw_transfer.config
     pw_work_queue
   PRIVATE_DEPS
     pw_protobuf
diff --git a/pw_unit_test/CMakeLists.txt b/pw_unit_test/CMakeLists.txt
index 983fe30..5adaebe 100644
--- a/pw_unit_test/CMakeLists.txt
+++ b/pw_unit_test/CMakeLists.txt
@@ -14,6 +14,16 @@
 
 include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
 
+pw_add_module_config(pw_unit_test_CONFIG)
+
+pw_add_module_library(pw_unit_test.config
+  PUBLIC_DEPS
+    ${pw_unit_test_CONFIG}
+    pw_polyfill
+  HEADERS
+    public/pw_unit_test/config.h
+)
+
 pw_add_module_library(pw_unit_test
   SOURCES
     framework.cc
@@ -21,6 +31,7 @@
     pw_polyfill
     pw_preprocessor
     pw_string
+    pw_unit_test.config
 )
 
 # pw_unit_test overrides the gtest/gtest.h header.