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()