pw_thread: Add CMake support

Change-Id: If7fca0a7a23d9e1c58690f891d38d7fb38badd5b
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/79725
Reviewed-by: Keir Mierle <keir@google.com>
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Rob Mohr <mohrr@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a6d54f3..547e24b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,6 +67,7 @@
 add_subdirectory(pw_sys_io EXCLUDE_FROM_ALL)
 add_subdirectory(pw_sys_io_stdio EXCLUDE_FROM_ALL)
 add_subdirectory(pw_system EXCLUDE_FROM_ALL)
+add_subdirectory(pw_thread EXCLUDE_FROM_ALL)
 add_subdirectory(pw_thread_freertos EXCLUDE_FROM_ALL)
 add_subdirectory(pw_tokenizer EXCLUDE_FROM_ALL)
 add_subdirectory(pw_trace EXCLUDE_FROM_ALL)
diff --git a/pw_thread/CMakeLists.txt b/pw_thread/CMakeLists.txt
new file mode 100644
index 0000000..1589cb9
--- /dev/null
+++ b/pw_thread/CMakeLists.txt
@@ -0,0 +1,168 @@
+# Copyright 2022 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_config(pw_thread_CONFIG)
+
+pw_add_module_library(pw_thread.config
+  HEADERS
+    public/pw_thread/config.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    ${pw_thread_CONFIG}
+)
+
+pw_add_facade(pw_thread.id
+  HEADERS
+    public/pw_thread/id.h
+  PUBLIC_INCLUDES
+    public
+)
+
+pw_add_facade(pw_thread.sleep
+  HEADERS
+    public/pw_thread/sleep.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_chrono.system_clock
+    pw_preprocessor
+  SOURCES
+    sleep.cc
+)
+
+pw_add_facade(pw_thread.thread
+  HEADERS
+    public/pw_thread/detached_thread.h
+    public/pw_thread/thread.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_thread.thread_core
+    pw_thread.id
+  SOURCES
+    thread.cc
+)
+
+pw_add_module_library(pw_thread.thread_core
+  HEADERS
+    public/pw_thread/thread_core.h
+  PUBLIC_INCLUDES
+    public
+)
+
+pw_add_facade(pw_thread.yield
+  HEADERS
+    public/pw_thread/yield.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_preprocessor
+  SOURCES
+    yield.cc
+)
+
+pw_add_module_library(pw_thread.snapshot
+  HEADERS
+    public/pw_thread/snapshot.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_bytes
+    pw_protobuf
+    pw_status
+    pw_thread.protos.pwpb
+  SOURCES
+    snapshot.cc
+  PRIVATE_DEPS
+    pw_thread.config
+    pw_log
+)
+
+pw_proto_library(pw_thread.protos
+  SOURCES
+    pw_thread_protos/thread.proto
+  PUBLIC_DEPS
+    pw_tokenizer.proto
+)
+
+if(NOT "${pw_thread.id_BACKEND}" STREQUAL "pw_thread.id.NO_BACKEND_SET")
+  pw_add_test(pw_thread.id_facade_test
+    SOURCES
+      id_facade_test.cc
+    DEPS
+      pw_thread.id
+    GROUPS
+      modules
+      pw_thread
+  )
+endif()
+
+if((NOT "${pw_thread.id_BACKEND}" STREQUAL "pw_thread.id.NO_BACKEND_SET") AND
+   (NOT "${pw_thread.sleep_BACKEND}" STREQUAL "pw_thread.sleep.NO_BACKEND_SET"))
+  pw_add_test(pw_thread.sleep_facade_test
+    SOURCES
+      sleep_facade_test.cc
+      sleep_facade_test_c.c
+    DEPS
+      pw_chrono.system_clock
+      pw_thread.id
+      pw_thread.sleep
+    GROUPS
+      modules
+      pw_thread
+  )
+endif()
+
+pw_add_module_library(pw_thread.test_threads
+  HEADERS
+    public/pw_thread/test_threads.h
+  PUBLIC_INCLUDES
+    public
+  PUBLIC_DEPS
+    pw_thread.thread
+)
+
+# To instantiate this facade test based on a selected backend to provide
+# test_threads you can create a pw_add_test target which depends on this
+# target and a target which provides the implementation of
+# test_threads. See pw_thread_stl.thread_backend_test as an example.
+pw_add_module_library(pw_thread.thread_facade_test
+  SOURCES
+    thread_facade_test.cc
+  PRIVATE_DEPS
+    pw_thread.id
+    pw_thread.sleep
+    pw_thread.test_threads
+    pw_thread.thread
+    pw_sync.binary_semaphore
+    pw_unit_test
+)
+
+if((NOT "${pw_thread.id_BACKEND}" STREQUAL "pw_thread.id.NO_BACKEND_SET") AND
+   (NOT "${pw_thread.yield_BACKEND}" STREQUAL "pw_thread.yield.NO_BACKEND_SET"))
+  pw_add_test(pw_thread.yield_facade_test
+    SOURCES
+      yield_facade_test.cc
+      yield_facade_test_c.c
+    DEPS
+      pw_thread.id
+      pw_thread.yield
+    GROUPS
+      modules
+      pw_thread
+  )
+endif()