Add CMake option to support thread-less configuration

Add `IREE_ENABLE_THREADING` CMake option to support building IREE
without thread library dependencies.

It is needed for the bare-metal build configuration.

This commit will close https://github.com/google/iree/issues/6027
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ecf7c2c..c764b18 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,7 @@
 option(IREE_BUILD_TENSORFLOW_COMPILER "Builds TensorFlow compiler frontend." OFF)
 option(IREE_BUILD_TFLITE_COMPILER "Builds the TFLite compiler frontend." OFF)
 option(IREE_BUILD_XLA_COMPILER "Builds TensorFlow XLA compiler frontend." OFF)
+option(IREE_ENABLE_THREADING "Builds IREE in with thread library support." ON)
 
 set(IREE_HAL_DRIVERS_TO_BUILD "all"
   CACHE STRING "Semicolon-separated list of HAL drivers to build, or \"all\".")
@@ -379,15 +380,17 @@
 include(external_cc_library)
 include(flatbuffer_c_library)
 
-add_subdirectory(third_party/benchmark EXCLUDE_FROM_ALL)
 add_subdirectory(build_tools/third_party/cuda EXCLUDE_FROM_ALL)
 add_subdirectory(build_tools/third_party/flatcc EXCLUDE_FROM_ALL)
 add_subdirectory(build_tools/third_party/vulkan_memory_allocator EXCLUDE_FROM_ALL)
 add_subdirectory(build_tools/third_party/stblib EXCLUDE_FROM_ALL)
 
-add_subdirectory(third_party/cpuinfo EXCLUDE_FROM_ALL)
 add_subdirectory(third_party/googletest EXCLUDE_FROM_ALL)
-add_subdirectory(third_party/abseil-cpp EXCLUDE_FROM_ALL)
+if(${IREE_ENABLE_THREADING})
+  add_subdirectory(third_party/benchmark EXCLUDE_FROM_ALL)
+  add_subdirectory(third_party/cpuinfo EXCLUDE_FROM_ALL)
+  add_subdirectory(third_party/abseil-cpp EXCLUDE_FROM_ALL)
+endif()
 add_subdirectory(third_party/flatcc EXCLUDE_FROM_ALL)
 add_subdirectory(third_party/vulkan_headers EXCLUDE_FROM_ALL)
 
diff --git a/build_tools/cmake/iree_copts.cmake b/build_tools/cmake/iree_copts.cmake
index 78c01c1..20939ff 100644
--- a/build_tools/cmake/iree_copts.cmake
+++ b/build_tools/cmake/iree_copts.cmake
@@ -289,7 +289,7 @@
   string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
 endif()
 
-if(NOT ANDROID)
+if(NOT ANDROID AND ${IREE_ENABLE_THREADING})
   iree_select_compiler_opts(_IREE_PTHREADS_LINKOPTS
     CLANG_OR_GCC
       "-lpthread"
@@ -306,14 +306,31 @@
   )
 endif()
 
+if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Generic")
+# If building for a known OS, link against libdl for dynamic library support.
+# Generic systems may not support dynamic libraries.
+  iree_select_compiler_opts(_IREE_DL_LINKOPTS
+  CLANG_OR_GCC
+    "-ldl"
+  )
+endif()
+
+# TODO(benvanik): remove the ABSL usage here; we aren't abseil.
+If(${IREE_ENABLE_THREADING})
+  iree_select_compiler_opts(_IREE_ABSL_LINKOPTS
+    ALL
+      "${ABSL_DEFAULT_LINKOPTS}"
+  )
+endif()
+
 iree_select_compiler_opts(IREE_DEFAULT_LINKOPTS
   ALL
     # TODO(benvanik): remove the ABSL usage here; we aren't abseil.
-    "${ABSL_DEFAULT_LINKOPTS}"
+    ${_IREE_ABSL_LINKOPTS}
   CLANG_OR_GCC
     # Required by all modern software, effectively:
-    "-ldl"
     "-lm"
+    ${_IREE_DL_LINKOPTS}
     ${_IREE_PTHREADS_LINKOPTS}
     ${_IREE_LOGGING_LINKOPTS}
   MSVC
diff --git a/iree/base/CMakeLists.txt b/iree/base/CMakeLists.txt
index f0f14dc..a85c280 100644
--- a/iree/base/CMakeLists.txt
+++ b/iree/base/CMakeLists.txt
@@ -58,28 +58,28 @@
     iree::base::internal::flags
   PUBLIC
 )
+if(${IREE_ENABLE_THREADING})
+  iree_cc_library(
+    NAME
+      status
+    HDRS
+      "status.h"
+    DEPS
+      iree::base::internal::status_internal
+    PUBLIC
+  )
 
-iree_cc_library(
-  NAME
-    status
-  HDRS
-    "status.h"
-  DEPS
-    iree::base::internal::status_internal
-  PUBLIC
-)
-
-iree_cc_test(
-  NAME
-    status_test
-  SRCS
-    "status_test.cc"
-  DEPS
-    ::status
-    iree::testing::gtest
-    iree::testing::gtest_main
-)
-
+  iree_cc_test(
+    NAME
+      status_test
+    SRCS
+      "status_test.cc"
+    DEPS
+      ::status
+      iree::testing::gtest
+      iree::testing::gtest_main
+  )
+endif()
 iree_cc_test(
   NAME
     string_view_test
diff --git a/iree/base/internal/BUILD b/iree/base/internal/BUILD
index fba2c6a..c06028f 100644
--- a/iree/base/internal/BUILD
+++ b/iree/base/internal/BUILD
@@ -10,6 +10,7 @@
 
 load("//build_tools/bazel:iree_flatcc.bzl", "iree_flatbuffer_c_library")
 load("//build_tools/bazel:run_binary_test.bzl", "run_binary_test")
+load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content")
 load("//iree:lit_test.bzl", "iree_lit_test_suite")
 
 package(
@@ -280,24 +281,6 @@
 )
 
 cc_library(
-    name = "status_internal",
-    srcs = [
-        "status.cc",
-        "statusor.cc",
-    ],
-    hdrs = [
-        "status.h",
-        "statusor.h",
-    ],
-    deps = [
-        "//iree/base",
-        "//iree/base:core_headers",
-        "//iree/base:logging",
-        "@com_google_absl//absl/utility",
-    ],
-)
-
-cc_library(
     name = "synchronization",
     srcs = [
         "synchronization.c",
@@ -341,6 +324,40 @@
     ],
 )
 
+#===------------------------------------------------------------------------===#
+# Utilities with thread dependencies
+#===------------------------------------------------------------------------===#
+
+iree_cmake_extra_content(
+    content = """
+# TODO(#3848): absl has a thread dependency, move this condition after statusor
+# is fixed.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+""",
+    inline = True,
+)
+
+# TODO(#3848): statusor has the abseil dependency.
+cc_library(
+    name = "status_internal",
+    srcs = [
+        "status.cc",
+        "statusor.cc",
+    ],
+    hdrs = [
+        "status.h",
+        "statusor.h",
+    ],
+    deps = [
+        "//iree/base",
+        "//iree/base:core_headers",
+        "//iree/base:logging",
+        "@com_google_absl//absl/utility",
+    ],
+)
+
 cc_library(
     name = "threading",
     srcs = [
diff --git a/iree/base/internal/CMakeLists.txt b/iree/base/internal/CMakeLists.txt
index 1300382..cb8dbab 100644
--- a/iree/base/internal/CMakeLists.txt
+++ b/iree/base/internal/CMakeLists.txt
@@ -296,23 +296,6 @@
 
 iree_cc_library(
   NAME
-    status_internal
-  HDRS
-    "status.h"
-    "statusor.h"
-  SRCS
-    "status.cc"
-    "statusor.cc"
-  DEPS
-    absl::utility
-    iree::base
-    iree::base::core_headers
-    iree::base::logging
-  PUBLIC
-)
-
-iree_cc_library(
-  NAME
     synchronization
   HDRS
     "call_once.h"
@@ -359,6 +342,29 @@
     iree::testing::gtest_main
 )
 
+# TODO(#3848): absl has a thread dependency, move this condition after statusor
+# is fixed.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
+iree_cc_library(
+  NAME
+    status_internal
+  HDRS
+    "status.h"
+    "statusor.h"
+  SRCS
+    "status.cc"
+    "statusor.cc"
+  DEPS
+    absl::utility
+    iree::base
+    iree::base::core_headers
+    iree::base::logging
+  PUBLIC
+)
+
 iree_cc_library(
   NAME
     threading
diff --git a/iree/hal/drivers/CMakeLists.txt b/iree/hal/drivers/CMakeLists.txt
index 5ca8135..afb89ee 100644
--- a/iree/hal/drivers/CMakeLists.txt
+++ b/iree/hal/drivers/CMakeLists.txt
@@ -6,6 +6,11 @@
 
 # Doesn't use bazel_to_cmake because of custom configuration vars
 
+# Driver registration has implicit thread dependency from task executor.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
 set(IREE_HAL_DRIVER_MODULES)
 if(${IREE_HAL_DRIVER_CUDA})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::cuda::registration)
diff --git a/iree/hal/local/BUILD b/iree/hal/local/BUILD
index 5ebd6ac..db652f7 100644
--- a/iree/hal/local/BUILD
+++ b/iree/hal/local/BUILD
@@ -7,28 +7,14 @@
 # Default implementations for HAL types that use the host resources.
 # These are generally just wrappers around host heap memory and host threads.
 
+load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content")
+
 package(
     default_visibility = ["//visibility:public"],
     features = ["layering_check"],
     licenses = ["notice"],  # Apache 2.0
 )
 
-# TODO(benvanik): move into base/? may be useful for other backends or for other
-# parts of the system (like modules handling IO/RPC).
-cc_library(
-    name = "event_pool",
-    srcs = ["event_pool.c"],
-    hdrs = ["event_pool.h"],
-    deps = [
-        "//iree/base",
-        "//iree/base:core_headers",
-        "//iree/base:tracing",
-        "//iree/base/internal",
-        "//iree/base/internal:synchronization",
-        "//iree/base/internal:wait_handle",
-    ],
-)
-
 cc_library(
     name = "executable_library",
     hdrs = ["executable_library.h"],
@@ -119,6 +105,35 @@
     ],
 )
 
+#===------------------------------------------------------------------------===#
+# Thread dependent packages
+#===------------------------------------------------------------------------===#
+
+iree_cmake_extra_content(
+    content = """
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+""",
+    inline = True,
+)
+
+# TODO(benvanik): move into base/? may be useful for other backends or for other
+# parts of the system (like modules handling IO/RPC).
+cc_library(
+    name = "event_pool",
+    srcs = ["event_pool.c"],
+    hdrs = ["event_pool.h"],
+    deps = [
+        "//iree/base",
+        "//iree/base:core_headers",
+        "//iree/base:tracing",
+        "//iree/base/internal",
+        "//iree/base/internal:synchronization",
+        "//iree/base/internal:wait_handle",
+    ],
+)
+
 cc_library(
     name = "task_driver",
     srcs = [
diff --git a/iree/hal/local/CMakeLists.txt b/iree/hal/local/CMakeLists.txt
index a73aab3..3fec374 100644
--- a/iree/hal/local/CMakeLists.txt
+++ b/iree/hal/local/CMakeLists.txt
@@ -12,23 +12,6 @@
 
 iree_cc_library(
   NAME
-    event_pool
-  HDRS
-    "event_pool.h"
-  SRCS
-    "event_pool.c"
-  DEPS
-    iree::base
-    iree::base::core_headers
-    iree::base::internal
-    iree::base::internal::synchronization
-    iree::base::internal::wait_handle
-    iree::base::tracing
-  PUBLIC
-)
-
-iree_cc_library(
-  NAME
     executable_library
   HDRS
     "executable_library.h"
@@ -118,6 +101,27 @@
   PUBLIC
 )
 
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
+iree_cc_library(
+  NAME
+    event_pool
+  HDRS
+    "event_pool.h"
+  SRCS
+    "event_pool.c"
+  DEPS
+    iree::base
+    iree::base::core_headers
+    iree::base::internal
+    iree::base::internal::synchronization
+    iree::base::internal::wait_handle
+    iree::base::tracing
+  PUBLIC
+)
+
 iree_cc_library(
   NAME
     task_driver
diff --git a/iree/modules/strings/BUILD b/iree/modules/strings/BUILD
index 1a3518d..c6c47e2 100644
--- a/iree/modules/strings/BUILD
+++ b/iree/modules/strings/BUILD
@@ -7,6 +7,16 @@
     licenses = ["notice"],  # Apache 2.0
 )
 
+iree_cmake_extra_content(
+    content = """
+# absl and benchmark have thread dependency.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+""",
+    inline = True,
+)
+
 cc_library(
     name = "strings_module",
     srcs = [
diff --git a/iree/modules/strings/CMakeLists.txt b/iree/modules/strings/CMakeLists.txt
index 7293dd2..b9c2324 100644
--- a/iree/modules/strings/CMakeLists.txt
+++ b/iree/modules/strings/CMakeLists.txt
@@ -10,6 +10,11 @@
 
 iree_add_all_subdirs()
 
+# absl and benchmark have thread dependency.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
 iree_cc_library(
   NAME
     strings_module
diff --git a/iree/modules/tensorlist/BUILD b/iree/modules/tensorlist/BUILD
index ae367f1..730911e 100644
--- a/iree/modules/tensorlist/BUILD
+++ b/iree/modules/tensorlist/BUILD
@@ -13,6 +13,17 @@
     licenses = ["notice"],  # Apache 2.0
 )
 
+iree_cmake_extra_content(
+    content = """
+# absl has thread dependency.
+# TODO(#3848): Remove this condition.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+""",
+    inline = True,
+)
+
 cc_library(
     name = "native_module",
     srcs = ["native_module.cc"],
diff --git a/iree/modules/tensorlist/CMakeLists.txt b/iree/modules/tensorlist/CMakeLists.txt
index a7c490d..5438c73 100644
--- a/iree/modules/tensorlist/CMakeLists.txt
+++ b/iree/modules/tensorlist/CMakeLists.txt
@@ -10,6 +10,12 @@
 
 iree_add_all_subdirs()
 
+# absl has thread dependency.
+# TODO(#3848): Remove this condition.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
 iree_cc_library(
   NAME
     native_module
diff --git a/iree/runtime/BUILD b/iree/runtime/BUILD
index 1fbfe4c..7735345 100644
--- a/iree/runtime/BUILD
+++ b/iree/runtime/BUILD
@@ -4,12 +4,26 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content")
+
 package(
     default_visibility = ["//visibility:public"],
     features = ["layering_check"],
     licenses = ["notice"],  # Apache 2.0
 )
 
+iree_cmake_extra_content(
+    content = """
+# Generic (bare-metal) system doesn't have the file system support and can be
+# thread-less.
+# TODO(#6247) Remove the condition when bare-metal related APIs are cleaned-up.
+if(${CMAKE_SYSTEM_NAME} STREQUAL "Generic")
+  return()
+endif()
+""",
+    inline = True,
+)
+
 #===------------------------------------------------------------------------===#
 # Public API
 #===------------------------------------------------------------------------===#
diff --git a/iree/runtime/CMakeLists.txt b/iree/runtime/CMakeLists.txt
index 71f6556..1014708 100644
--- a/iree/runtime/CMakeLists.txt
+++ b/iree/runtime/CMakeLists.txt
@@ -10,6 +10,13 @@
 
 iree_add_all_subdirs()
 
+# Generic (bare-metal) system doesn't have the file system support and can be
+# thread-less.
+# TODO(#6247) Remove the condition when bare-metal related APIs are cleaned-up.
+if(${CMAKE_SYSTEM_NAME} STREQUAL "Generic")
+  return()
+endif()
+
 iree_cc_library(
   NAME
     runtime
diff --git a/iree/task/BUILD b/iree/task/BUILD
index 3cf4c6c..4652cd0 100644
--- a/iree/task/BUILD
+++ b/iree/task/BUILD
@@ -4,12 +4,24 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content")
+
 package(
     default_visibility = ["//visibility:public"],
     features = ["layering_check"],
     licenses = ["notice"],  # Apache 2.0
 )
 
+iree_cmake_extra_content(
+    content = """
+# Task-based executor requires threading support.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+""",
+    inline = True,
+)
+
 cc_library(
     name = "api",
     srcs = ["api.c"],
diff --git a/iree/task/CMakeLists.txt b/iree/task/CMakeLists.txt
index 364b556..39c7184 100644
--- a/iree/task/CMakeLists.txt
+++ b/iree/task/CMakeLists.txt
@@ -10,6 +10,11 @@
 
 iree_add_all_subdirs()
 
+# Task-based executor requires threading support.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
 iree_cc_library(
   NAME
     api
diff --git a/iree/test/BUILD b/iree/test/BUILD
index 236a474..019314f 100644
--- a/iree/test/BUILD
+++ b/iree/test/BUILD
@@ -4,8 +4,20 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content")
+
 package(
     default_visibility = ["//visibility:public"],
     features = ["layering_check"],
     licenses = ["notice"],  # Apache 2.0
 )
+
+iree_cmake_extra_content(
+    content = """
+# TODO(#3848): Test tools has implicit thread dependency from absl.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+""",
+    inline = True,
+)
diff --git a/iree/test/CMakeLists.txt b/iree/test/CMakeLists.txt
index 9f758b5..189818e 100644
--- a/iree/test/CMakeLists.txt
+++ b/iree/test/CMakeLists.txt
@@ -10,4 +10,9 @@
 
 iree_add_all_subdirs()
 
+# TODO(#3848): Test tools has implicit thread dependency from absl.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
 ### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ###
diff --git a/iree/testing/BUILD b/iree/testing/BUILD
index 159edfc..42e2803 100644
--- a/iree/testing/BUILD
+++ b/iree/testing/BUILD
@@ -6,6 +6,8 @@
 
 # Testing utilities for IREE.
 
+load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content")
+
 package(
     default_visibility = ["//visibility:public"],
     features = ["layering_check"],
@@ -38,6 +40,16 @@
     ],
 )
 
+iree_cmake_extra_content(
+    content = """
+# TODO(#3848): gtest library has implicit thread dependency from absl.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+""",
+    inline = True,
+)
+
 cc_library(
     name = "gtest",
     testonly = True,
diff --git a/iree/testing/CMakeLists.txt b/iree/testing/CMakeLists.txt
index 509faeb..12b0c32 100644
--- a/iree/testing/CMakeLists.txt
+++ b/iree/testing/CMakeLists.txt
@@ -37,6 +37,11 @@
   PUBLIC
 )
 
+# TODO(#3848): gtest library has implicit thread dependency from absl.
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
 iree_cc_library(
   NAME
     gtest
diff --git a/iree/tools/CMakeLists.txt b/iree/tools/CMakeLists.txt
index 423c068..a51be21 100644
--- a/iree/tools/CMakeLists.txt
+++ b/iree/tools/CMakeLists.txt
@@ -6,6 +6,11 @@
 
 # Doesn't use bazel_to_cmake because of various special logic throughout.
 
+# Tools has thread dependency from iree::hal::drivers and absl
+if(NOT ${IREE_ENABLE_THREADING})
+  return()
+endif()
+
 add_subdirectory(android)
 add_subdirectory(test)
 add_subdirectory(utils)