ORC-1994: [C++] Improve CMake by extracting OrcSanitizers.cmake

### What changes were proposed in this pull request?

Extract a separate OrcSanitizers.cmake file to manage sanitizer config.

### Why are the changes needed?

This is part of a larger effort to refactor CMake management.

### How was this patch tested?

Passing CI.

### Was this patch authored or co-authored using generative AI tooling?

Generated-by: Cursor, Version: 1.0.0 (Universal)

Closes #2381 from wgtmac/ORC-1994.

Authored-by: Gang Wu <ustcwg@gmail.com>
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
diff --git a/.github/workflows/sanitizer_test.yml b/.github/workflows/sanitizer_test.yml
index 3ee3aae..ca1efa5 100644
--- a/.github/workflows/sanitizer_test.yml
+++ b/.github/workflows/sanitizer_test.yml
@@ -57,7 +57,7 @@
         CXX: ${{ matrix.cxx }}
       run: |
         mkdir -p build && cd build
-        cmake .. -DCMAKE_BUILD_TYPE=Debug -DENABLE_ASAN=ON -DENABLE_UBSAN=ON -DBUILD_ENABLE_AVX512=ON -DBUILD_CPP_ENABLE_METRICS=ON -DBUILD_JAVA=OFF
+        cmake .. -DCMAKE_BUILD_TYPE=Debug -DORC_ENABLE_ASAN=ON -DORC_ENABLE_UBSAN=ON -DBUILD_ENABLE_AVX512=ON -DBUILD_CPP_ENABLE_METRICS=ON -DBUILD_JAVA=OFF
         cmake --build . --verbose
     - name: Run Tests
       working-directory: build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6c5575d..5931e35 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -81,10 +81,6 @@
     "Enable build with AVX512 at compile time"
     OFF)
 
-option(ENABLE_ASAN
-    "Enable Address Sanitizer"
-    OFF)
-
 option(ORC_PACKAGE_KIND
     "Arbitrary string that identifies the kind of package"
     "")
@@ -93,10 +89,6 @@
     "Enable Clang tools"
     OFF)
 
-option(ENABLE_UBSAN
-    "Enable Undefined Behavior Sanitizer"
-    OFF)
-
 # Make sure that a build type is selected
 if (NOT CMAKE_BUILD_TYPE)
   message(STATUS "No build type selected, default to ReleaseWithDebugInfo")
@@ -168,35 +160,8 @@
   set (WARN_FLAGS "${WARN_FLAGS} -wd4521") # multiple copy constructors specified
   set (WARN_FLAGS "${WARN_FLAGS} -wd4146") # unary minus operator applied to unsigned type, result still unsigned
 endif ()
-# Configure Address Sanitizer if enabled
-if (ENABLE_ASAN)
-  if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
-    message(STATUS "Address Sanitizer enabled")
-  else()
-    message(WARNING "Address Sanitizer is only supported for GCC and Clang compilers")
-  endif()
-endif()
-
-# Configure Undefined Behavior Sanitizer if enabled
-if (ENABLE_UBSAN)
-  if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize=alignment,vptr -fno-sanitize-recover=all")
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize=alignment,vptr -fno-sanitize-recover=all")
-    message(STATUS "Undefined Behavior Sanitizer enabled")
-  else()
-    message(WARNING "Undefined Behavior Sanitizer is only supported for GCC and Clang compilers")
-  endif()
-endif()
-
-if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-  if (ENABLE_ASAN OR ENABLE_UBSAN)
-    set(CMAKE_THREAD_LIBS_INIT "-lpthread")
-    set(THREADS_PREFER_PTHREAD_FLAG ON)
-    message(STATUS "Forcing pthread linking for GCC with sanitizers")
-  endif()
-endif()
+# Include sanitizer configuration
+INCLUDE(OrcSanitizers)
 
 enable_testing()
 
diff --git a/cmake_modules/OrcSanitizers.cmake b/cmake_modules/OrcSanitizers.cmake
new file mode 100644
index 0000000..555d691
--- /dev/null
+++ b/cmake_modules/OrcSanitizers.cmake
@@ -0,0 +1,144 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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
+#
+#   http://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.
+
+# =============================================================================
+# Sanitizer Options
+# =============================================================================
+
+option(ORC_ENABLE_ASAN "Enable Address Sanitizer" OFF)
+
+option(ORC_ENABLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
+
+# =============================================================================
+# Sanitizer Support Detection
+# =============================================================================
+
+function(orc_check_sanitizer_support)
+  set(ORC_SANITIZERS_SUPPORTED
+      FALSE
+      PARENT_SCOPE)
+
+  if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+    set(ORC_SANITIZERS_SUPPORTED
+        TRUE
+        PARENT_SCOPE)
+    message(DEBUG "Sanitizers supported with ${CMAKE_CXX_COMPILER_ID} compiler")
+  else()
+    message(DEBUG
+            "Sanitizers not supported with ${CMAKE_CXX_COMPILER_ID} compiler")
+  endif()
+endfunction()
+
+# =============================================================================
+# Address Sanitizer Configuration
+# =============================================================================
+
+function(orc_configure_asan)
+  if(NOT ORC_ENABLE_ASAN)
+    return()
+  endif()
+
+  orc_check_sanitizer_support()
+  if(NOT ORC_SANITIZERS_SUPPORTED)
+    message(
+      WARNING "Address Sanitizer is only supported for GCC and Clang compilers")
+    return()
+  endif()
+
+  set(CMAKE_CXX_FLAGS
+      "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer"
+      PARENT_SCOPE)
+  set(CMAKE_C_FLAGS
+      "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer"
+      PARENT_SCOPE)
+
+  message(STATUS "Address Sanitizer enabled")
+endfunction()
+
+# =============================================================================
+# Undefined Behavior Sanitizer Configuration
+# =============================================================================
+
+function(orc_configure_ubsan)
+  if(NOT ORC_ENABLE_UBSAN)
+    return()
+  endif()
+
+  orc_check_sanitizer_support()
+  if(NOT ORC_SANITIZERS_SUPPORTED)
+    message(
+      WARNING
+        "Undefined Behavior Sanitizer is only supported for GCC and Clang compilers"
+    )
+    return()
+  endif()
+
+  set(CMAKE_CXX_FLAGS
+      "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize=alignment,vptr -fno-sanitize-recover=all"
+      PARENT_SCOPE)
+  set(CMAKE_C_FLAGS
+      "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize=alignment,vptr -fno-sanitize-recover=all"
+      PARENT_SCOPE)
+
+  message(STATUS "Undefined Behavior Sanitizer enabled")
+endfunction()
+
+# =============================================================================
+# GCC-Specific Threading Configuration
+# =============================================================================
+
+function(orc_configure_gcc_sanitizer_threading)
+  if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+    return()
+  endif()
+
+  if(NOT (ORC_ENABLE_ASAN OR ORC_ENABLE_UBSAN))
+    return()
+  endif()
+
+  # GCC sanitizers require explicit pthread linking
+  set(CMAKE_THREAD_LIBS_INIT
+      "-lpthread"
+      PARENT_SCOPE)
+  set(THREADS_PREFER_PTHREAD_FLAG
+      ON
+      PARENT_SCOPE)
+
+  message(STATUS "Forcing pthread linking for GCC with sanitizers")
+endfunction()
+
+# =============================================================================
+# Combined Sanitizer Setup
+# =============================================================================
+
+function(orc_setup_sanitizers)
+  orc_configure_asan()
+  orc_configure_ubsan()
+  orc_configure_gcc_sanitizer_threading()
+
+  if(ORC_ENABLE_ASAN OR ORC_ENABLE_UBSAN)
+    message(STATUS "Sanitizer configuration:")
+    message(STATUS "  Address Sanitizer: ${ORC_ENABLE_ASAN}")
+    message(STATUS "  Undefined Behavior Sanitizer: ${ORC_ENABLE_UBSAN}")
+  endif()
+endfunction()
+
+# =============================================================================
+# Module Initialization
+# =============================================================================
+
+orc_setup_sanitizers()