This is an automated email from the ASF dual-hosted git repository.
leaves12138 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-cpp.git
The following commit(s) were added to refs/heads/main by this push:
new 7f56988 feat(cmake): migrate build utility modules (#4)
7f56988 is described below
commit 7f5698881a9e966841c52806408ef4d05b8bb365
Author: Zhang Jiawei <[email protected]>
AuthorDate: Fri May 22 18:26:04 2026 +0800
feat(cmake): migrate build utility modules (#4)
---
cmake_modules/BuildUtils.cmake | 367 ++++++++++++++++++++++++++++++++
cmake_modules/DefineOptions.cmake | 310 +++++++++++++++++++++++++++
cmake_modules/SetupCxxFlags.cmake | 434 ++++++++++++++++++++++++++++++++++++++
cmake_modules/san-config.cmake | 40 ++++
4 files changed, 1151 insertions(+)
diff --git a/cmake_modules/BuildUtils.cmake b/cmake_modules/BuildUtils.cmake
new file mode 100644
index 0000000..0bc75b6
--- /dev/null
+++ b/cmake_modules/BuildUtils.cmake
@@ -0,0 +1,367 @@
+# 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.
+
+# Borrowed the file from Apache Arrow:
+# https://github.com/apache/arrow/blob/main/cpp/cmake_modules/BuildUtils.cmake
+
+function(add_paimon_lib LIB_NAME)
+ set(options BUILD_SHARED BUILD_STATIC)
+ set(one_value_args SHARED_LINK_FLAGS)
+ set(multi_value_args
+ SOURCES
+ STATIC_LINK_LIBS
+ SHARED_LINK_LIBS
+ EXTRA_INCLUDES
+ PRIVATE_INCLUDES
+ DEPENDENCIES)
+ cmake_parse_arguments(ARG
+ "${options}"
+ "${one_value_args}"
+ "${multi_value_args}"
+ ${ARGN})
+ if(ARG_UNPARSED_ARGUMENTS)
+ message(SEND_ERROR "Error: unrecognized arguments:
${ARG_UNPARSED_ARGUMENTS}")
+ endif()
+
+ # Allow overriding PAIMON_BUILD_SHARED and PAIMON_BUILD_STATIC
+ if(ARG_BUILD_SHARED)
+ set(BUILD_SHARED ${ARG_BUILD_SHARED})
+ else()
+ set(BUILD_SHARED ${PAIMON_BUILD_SHARED})
+ endif()
+ if(ARG_BUILD_STATIC)
+ set(BUILD_STATIC ${ARG_BUILD_STATIC})
+ else()
+ set(BUILD_STATIC ${PAIMON_BUILD_STATIC})
+ endif()
+
+ # Generate a single "objlib" from all C++ modules and link
+ # that "objlib" into each library kind, to avoid compiling twice
+ add_library(${LIB_NAME}_objlib OBJECT ${ARG_SOURCES})
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ target_compile_options(${LIB_NAME}_objlib PRIVATE
-Wno-global-constructors)
+ endif()
+ # Necessary to make static linking into other shared libraries work
properly
+ set_property(TARGET ${LIB_NAME}_objlib PROPERTY POSITION_INDEPENDENT_CODE
1)
+ if(ARG_DEPENDENCIES)
+ # In static-only builds, some dependency names are still declared as
+ # *_shared. Map them to *_static when the shared target is unavailable.
+ set(_paimon_objlib_link_deps)
+ set(_paimon_objlib_deps)
+ foreach(_paimon_dep IN LISTS ARG_DEPENDENCIES)
+ set(_paimon_mapped_dep "${_paimon_dep}")
+ if(NOT TARGET ${_paimon_mapped_dep} AND _paimon_dep MATCHES
"_shared$")
+ string(REGEX REPLACE "_shared$" "_static" _paimon_mapped_dep
+ "${_paimon_dep}")
+ endif()
+ if(TARGET ${_paimon_mapped_dep})
+ get_target_property(_paimon_is_internal_lib
${_paimon_mapped_dep}
+ PAIMON_INTERNAL_LIBRARY)
+ list(APPEND _paimon_objlib_deps ${_paimon_mapped_dep})
+ if(NOT _paimon_is_internal_lib)
+ list(APPEND _paimon_objlib_link_deps ${_paimon_mapped_dep})
+ endif()
+ unset(_paimon_is_internal_lib)
+ endif()
+ unset(_paimon_mapped_dep)
+ endforeach()
+ if(_paimon_objlib_deps)
+ add_dependencies(${LIB_NAME}_objlib ${_paimon_objlib_deps})
+ endif()
+ if(_paimon_objlib_link_deps)
+ target_link_libraries(${LIB_NAME}_objlib PRIVATE
${_paimon_objlib_link_deps})
+ endif()
+ unset(_paimon_objlib_deps)
+ unset(_paimon_objlib_link_deps)
+ unset(_paimon_dep)
+ endif()
+ set(LIB_DEPS $<TARGET_OBJECTS:${LIB_NAME}_objlib>)
+ set(LIB_INCLUDES)
+ set(EXTRA_DEPS)
+
+ if(ARG_EXTRA_INCLUDES)
+ target_include_directories(${LIB_NAME}_objlib SYSTEM PUBLIC
${ARG_EXTRA_INCLUDES})
+ endif()
+ if(ARG_PRIVATE_INCLUDES)
+ target_include_directories(${LIB_NAME}_objlib PRIVATE
${ARG_PRIVATE_INCLUDES})
+ endif()
+
+ set(RUNTIME_INSTALL_DIR bin)
+
+ if(BUILD_SHARED)
+ add_library(${LIB_NAME}_shared SHARED ${LIB_DEPS})
+ if(EXTRA_DEPS)
+ add_dependencies(${LIB_NAME}_shared ${EXTRA_DEPS})
+ endif()
+
+ if(LIB_INCLUDES)
+ target_include_directories(${LIB_NAME}_shared SYSTEM
+ PUBLIC ${ARG_EXTRA_INCLUDES})
+ endif()
+
+ if(ARG_PRIVATE_INCLUDES)
+ target_include_directories(${LIB_NAME}_shared PRIVATE
${ARG_PRIVATE_INCLUDES})
+ endif()
+
+ set_property(TARGET ${LIB_NAME}_shared PROPERTY
PAIMON_INTERNAL_LIBRARY TRUE)
+ set_target_properties(${LIB_NAME}_shared
+ PROPERTIES LIBRARY_OUTPUT_DIRECTORY
+ "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
+ RUNTIME_OUTPUT_DIRECTORY
+ "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
+ PDB_OUTPUT_DIRECTORY
+ "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
+ LINK_FLAGS "${ARG_SHARED_LINK_FLAGS}"
+ OUTPUT_NAME ${LIB_NAME})
+
+ target_link_libraries(${LIB_NAME}_shared
+ LINK_PUBLIC
+ "$<BUILD_INTERFACE:${ARG_SHARED_LINK_LIBS}>"
+
"$<INSTALL_INTERFACE:${ARG_SHARED_INSTALL_INTERFACE_LIBS}>"
+ LINK_PRIVATE
+ "$<BUILD_INTERFACE:${ARG_STATIC_LINK_LIBS}>"
+ ${ARG_SHARED_PRIVATE_LINK_LIBS})
+
+ target_link_libraries(${LIB_NAME}_shared
+ PUBLIC
"$<BUILD_INTERFACE:paimon_sanitizer_flags>")
+
+ target_link_options(${LIB_NAME}_shared
+ PRIVATE
+ -Wl,--exclude-libs,ALL
+ -Wl,-Bsymbolic
+ -Wl,-z,defs
+ -Wl,--gc-sections)
+
+ install(TARGETS ${LIB_NAME}_shared ${INSTALL_IS_OPTIONAL}
+ EXPORT ${LIB_NAME}_targets
+ RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ INCLUDES
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+ endif()
+
+ if(BUILD_STATIC)
+ add_library(${LIB_NAME}_static STATIC ${LIB_DEPS})
+ if(EXTRA_DEPS)
+ add_dependencies(${LIB_NAME}_static ${EXTRA_DEPS})
+ endif()
+
+ if(LIB_INCLUDES)
+ target_include_directories(${LIB_NAME}_static SYSTEM
+ PUBLIC ${ARG_EXTRA_INCLUDES})
+ endif()
+
+ if(ARG_PRIVATE_INCLUDES)
+ target_include_directories(${LIB_NAME}_static PRIVATE
${ARG_PRIVATE_INCLUDES})
+ endif()
+
+ set(LIB_NAME_STATIC ${LIB_NAME})
+
+ set_property(TARGET ${LIB_NAME}_static PROPERTY
PAIMON_INTERNAL_LIBRARY TRUE)
+ set_target_properties(${LIB_NAME}_static
+ PROPERTIES ARCHIVE_OUTPUT_DIRECTORY
+ "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}"
+ OUTPUT_NAME ${LIB_NAME_STATIC})
+
+ if(ARG_STATIC_INSTALL_INTERFACE_LIBS)
+ target_link_libraries(${LIB_NAME}_static
+ LINK_PUBLIC
+
"$<INSTALL_INTERFACE:${ARG_STATIC_INSTALL_INTERFACE_LIBS}>"
+ )
+ endif()
+
+ if(ARG_STATIC_LINK_LIBS)
+ target_link_libraries(${LIB_NAME}_static LINK_PRIVATE
+ "$<BUILD_INTERFACE:${ARG_STATIC_LINK_LIBS}>")
+ endif()
+
+ target_link_libraries(${LIB_NAME}_static
+ PUBLIC
"$<BUILD_INTERFACE:paimon_sanitizer_flags>")
+
+ install(TARGETS ${LIB_NAME}_static ${INSTALL_IS_OPTIONAL}
+ EXPORT ${LIB_NAME}_targets
+ RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ INCLUDES
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+ endif()
+endfunction()
+
+#
+# Testing
+#
+# Add a new test case, with or without an executable that should be built.
+#
+# REL_TEST_NAME is the name of the test. It may be a single component
+# (e.g. monotime-test) or contain additional components (e.g.
+# net/net_util-test). Either way, the last component must be a globally
+# unique name.
+#
+# If given, SOURCES is the list of C++ source files to compile into the test
+# executable. Otherwise, "REL_TEST_NAME.cpp" is used.
+#
+# The unit test is added with a label of "unittest" to support filtering with
+# ctest.
+#
+# Arguments after the test name will be passed to set_tests_properties().
+#
+# \arg ENABLED if passed, add this unit test even if PAIMON_BUILD_TESTS is off
+# \arg PREFIX a string to append to the name of the test executable. For
+# example, if you have src/paimon/foo/bar-test.cpp, then PREFIX "foo" will
create
+# test executable foo-bar-test
+# \arg LABELS the unit test label or labels to assign the unit tests
+# to. By default, unit tests will go in the "unittest" group, but if we have
+# multiple unit tests in some subgroup, you can assign a test to multiple
+# groups use the syntax unittest;GROUP2;GROUP3. Custom targets for the group
+# names must exist
+function(add_test_case REL_TEST_NAME)
+ set(options NO_VALGRIND ENABLED)
+ set(one_value_args PRECOMPILED_HEADER_LIB)
+ set(multi_value_args
+ SOURCES
+ PRECOMPILED_HEADERS
+ STATIC_LINK_LIBS
+ EXTRA_LINK_LIBS
+ EXTRA_INCLUDES
+ EXTRA_DEPENDENCIES
+ LABELS
+ EXTRA_LABELS
+ PREFIX)
+ cmake_parse_arguments(ARG
+ "${options}"
+ "${one_value_args}"
+ "${multi_value_args}"
+ ${ARGN})
+ if(ARG_UNPARSED_ARGUMENTS)
+ message(SEND_ERROR "Error: unrecognized arguments:
${ARG_UNPARSED_ARGUMENTS}")
+ endif()
+
+ if(NO_TESTS AND NOT ARG_ENABLED)
+ return()
+ endif()
+ get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE)
+
+ if(ARG_PREFIX)
+ set(TEST_NAME "${ARG_PREFIX}-${TEST_NAME}")
+ endif()
+
+ if(ARG_SOURCES)
+ set(SOURCES ${ARG_SOURCES})
+ else()
+ set(SOURCES "${REL_TEST_NAME}.cpp")
+ endif()
+
+ # Make sure the executable name contains only hyphens, not underscores
+ string(REPLACE "_" "-" TEST_NAME ${TEST_NAME})
+ set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME}")
+ message(STATUS ${TEST_NAME})
+ add_executable(${TEST_NAME} ${SOURCES})
+
+ if(ARG_STATIC_LINK_LIBS)
+ target_link_libraries(${TEST_NAME} PRIVATE ${ARG_STATIC_LINK_LIBS})
+ else()
+ target_link_libraries(${TEST_NAME} PRIVATE ${PAIMON_TEST_LINK_LIBS})
+ endif()
+
+ if(ARG_EXTRA_LINK_LIBS)
+ target_link_libraries(${TEST_NAME} PRIVATE ${ARG_EXTRA_LINK_LIBS})
+ endif()
+
+ if(ARG_EXTRA_INCLUDES)
+ target_include_directories(${TEST_NAME} SYSTEM PUBLIC
${ARG_EXTRA_INCLUDES})
+ endif()
+
+ if(ARG_EXTRA_DEPENDENCIES)
+ add_dependencies(${TEST_NAME} ${ARG_EXTRA_DEPENDENCIES})
+ endif()
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ target_compile_options(${TEST_NAME} PRIVATE -Wno-global-constructors)
+ endif()
+ target_compile_options(${TEST_NAME} PRIVATE -fno-access-control)
+
+ add_test(${TEST_NAME}
+ ${BUILD_SUPPORT_DIR}/run-test.sh
+ ${CMAKE_BINARY_DIR}
+ test
+ ${TEST_PATH})
+
+ # Add test as dependency of relevant targets
+ foreach(TARGET ${ARG_LABELS})
+ add_dependencies(${TARGET} ${TEST_NAME})
+ endforeach()
+
+ set(LABELS)
+ list(APPEND LABELS "unittest")
+ if(ARG_LABELS)
+ list(APPEND LABELS ${ARG_LABELS})
+ endif()
+ # EXTRA_LABELS don't create their own dependencies, they are only used
+ # to ease running certain test categories.
+ if(ARG_EXTRA_LABELS)
+ list(APPEND LABELS ${ARG_EXTRA_LABELS})
+ endif()
+
+ foreach(LABEL ${ARG_LABELS})
+ # ensure there is a cmake target which exercises tests with this LABEL
+ set(LABEL_TEST_NAME "test-${LABEL}")
+ if(NOT TARGET ${LABEL_TEST_NAME})
+ add_custom_target(${LABEL_TEST_NAME}
+ ctest -L "${LABEL}" --output-on-failure
+ USES_TERMINAL)
+ endif()
+ # ensure the test is (re)built before the LABEL test runs
+ add_dependencies(${LABEL_TEST_NAME} ${TEST_NAME})
+ endforeach()
+
+ set_property(TEST ${TEST_NAME}
+ APPEND
+ PROPERTY LABELS ${LABELS})
+endfunction()
+
+# Adding unit tests part of the "paimon" portion of the test suite
+function(add_paimon_test REL_TEST_NAME)
+ set(options)
+ set(one_value_args PREFIX)
+ set(multi_value_args LABELS PRECOMPILED_HEADERS)
+ cmake_parse_arguments(ARG
+ "${options}"
+ "${one_value_args}"
+ "${multi_value_args}"
+ ${ARGN})
+ if(ARG_PREFIX)
+ set(PREFIX ${ARG_PREFIX})
+ else()
+ set(PREFIX "paimon")
+ endif()
+
+ if(ARG_LABELS)
+ set(LABELS ${ARG_LABELS})
+ else()
+ set(LABELS "paimon-tests")
+ endif()
+
+ add_test_case(${REL_TEST_NAME}
+ PREFIX
+ ${PREFIX}
+ LABELS
+ ${LABELS}
+ ${PCH_ARGS}
+ ${ARG_UNPARSED_ARGUMENTS})
+endfunction()
diff --git a/cmake_modules/DefineOptions.cmake
b/cmake_modules/DefineOptions.cmake
new file mode 100644
index 0000000..4add68f
--- /dev/null
+++ b/cmake_modules/DefineOptions.cmake
@@ -0,0 +1,310 @@
+# 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.
+
+# Borrowed the file from Apache Arrow:
+#
https://github.com/apache/arrow/blob/main/cpp/cmake_modules/DefineOptions.cmake
+
+macro(set_option_category name)
+ set(PAIMON_OPTION_CATEGORY ${name})
+ list(APPEND "PAIMON_OPTION_CATEGORIES" ${name})
+endmacro()
+
+function(check_description_length name description)
+ foreach(description_line ${description})
+ string(LENGTH ${description_line} line_length)
+ if(${line_length} GREATER 80)
+ message(FATAL_ERROR "description for ${name} contained a\n\
+ line ${line_length} characters long!\n\
+ (max is 80). Split it into more lines with semicolons")
+ endif()
+ endforeach()
+endfunction()
+
+function(list_join lst glue out)
+ if("${${lst}}" STREQUAL "")
+ set(${out}
+ ""
+ PARENT_SCOPE)
+ return()
+ endif()
+
+ list(GET ${lst} 0 joined)
+ list(REMOVE_AT ${lst} 0)
+ foreach(item ${${lst}})
+ set(joined "${joined}${glue}${item}")
+ endforeach()
+ set(${out}
+ ${joined}
+ PARENT_SCOPE)
+endfunction()
+
+macro(define_option name description default)
+ check_description_length(${name} ${description})
+ list_join(description "\n" multiline_description)
+
+ option(${name} "${multiline_description}" ${default})
+
+ list(APPEND "PAIMON_${PAIMON_OPTION_CATEGORY}_OPTION_NAMES" ${name})
+ set("${name}_OPTION_DESCRIPTION" ${description})
+ set("${name}_OPTION_DEFAULT" ${default})
+ set("${name}_OPTION_TYPE" "bool")
+endmacro()
+
+macro(define_option_string name description default)
+ check_description_length(${name} ${description})
+ list_join(description "\n" multiline_description)
+
+ set(${name}
+ ${default}
+ CACHE STRING "${multiline_description}")
+
+ list(APPEND "PAIMON_${PAIMON_OPTION_CATEGORY}_OPTION_NAMES" ${name})
+ set("${name}_OPTION_DESCRIPTION" ${description})
+ set("${name}_OPTION_DEFAULT" "\"${default}\"")
+ set("${name}_OPTION_TYPE" "string")
+ set("${name}_OPTION_POSSIBLE_VALUES" ${ARGN})
+
+ list_join("${name}_OPTION_POSSIBLE_VALUES" "|" "${name}_OPTION_ENUM")
+ if(NOT ("${${name}_OPTION_ENUM}" STREQUAL ""))
+ set_property(CACHE ${name} PROPERTY STRINGS
"${name}_OPTION_POSSIBLE_VALUES")
+ endif()
+endmacro()
+
+# Top level cmake dir
+if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+ #----------------------------------------------------------------------
+ set_option_category("Compile and link")
+
+ define_option_string(PAIMON_CXXFLAGS "Compiler flags to append when
compiling Paimon"
+ "")
+
+ define_option(PAIMON_BUILD_STATIC "Build static libraries" ON)
+
+ define_option(PAIMON_BUILD_SHARED "Build shared libraries" ON)
+
+ define_option(PAIMON_USE_CCACHE "Use ccache when compiling (if available)"
ON)
+
+ #----------------------------------------------------------------------
+ set_option_category("Test")
+
+ define_option(PAIMON_BUILD_TESTS "Build the Paimon googletest unit tests"
OFF)
+
+ if(PAIMON_BUILD_SHARED)
+ set(PAIMON_TEST_LINKAGE_DEFAULT "shared")
+ else()
+ set(PAIMON_TEST_LINKAGE_DEFAULT "static")
+ endif()
+
+ #----------------------------------------------------------------------
+ set_option_category("Lint")
+
+ define_option(PAIMON_VERBOSE_LINT
+ "If off, 'quiet' flags will be passed to linting tools" OFF)
+
+ define_option(PAIMON_LINT_GIT_DIFF_MODE
+ "If on, only git-diff files will be passed to linting tools"
ON)
+
+ define_option_string(PAIMON_LINT_GIT_TARGET_COMMIT
+ "target commit/branch for comparison in git diff"
"origin/main")
+
+ define_option(PAIMON_GENERATE_COVERAGE "Build with C++ code coverage
enabled" OFF)
+
+ #----------------------------------------------------------------------
+ set_option_category("Checks")
+
+ define_option(PAIMON_USE_ASAN "Enable Address Sanitizer checks" OFF)
+ define_option(PAIMON_USE_TSAN "Enable Thread Sanitizer checks" OFF)
+ define_option(PAIMON_USE_UBSAN "Enable Undefined Behaviour Sanitizer
checks" OFF)
+
+ #----------------------------------------------------------------------
+ set_option_category("Advanced developer")
+
+ define_option(PAIMON_EXTRA_ERROR_CONTEXT
+ "Compile with extra error context (line numbers, code)" OFF)
+
+ option(PAIMON_BUILD_CONFIG_SUMMARY_JSON
+ "Summarize build configuration in a JSON file" ON)
+
+ #----------------------------------------------------------------------
+ set_option_category("Dependencies")
+
+ define_option_string(PAIMON_DEPENDENCY_SOURCE
+ "Default third-party dependency source"
+ "AUTO"
+ AUTO
+ BUNDLED
+ SYSTEM)
+
+ define_option_string(PAIMON_PACKAGE_PREFIX
+ "Default prefix used to find third-party packages" "")
+
+ define_option(PAIMON_DEPENDENCY_USE_SHARED
+ "Prefer shared libraries for system third-party packages"
OFF)
+
+ define_option_string(Arrow_SOURCE
+ "Dependency source for Apache Arrow; SYSTEM is
unsupported"
+ ""
+ AUTO
+ BUNDLED)
+ define_option_string(zstd_SOURCE
+ "Dependency source for zstd"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(Snappy_SOURCE
+ "Dependency source for Snappy"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(LZ4_SOURCE
+ "Dependency source for LZ4"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(ZLIB_SOURCE
+ "Dependency source for ZLIB"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(RE2_SOURCE
+ "Dependency source for RE2"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(Protobuf_SOURCE
+ "Dependency source for Protobuf"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(ORC_SOURCE
+ "Dependency source for Apache ORC; SYSTEM is
unsupported"
+ ""
+ AUTO
+ BUNDLED)
+ define_option_string(fmt_SOURCE
+ "Dependency source for fmt"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(RapidJSON_SOURCE
+ "Dependency source for RapidJSON"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(TBB_SOURCE
+ "Dependency source for TBB"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(glog_SOURCE
+ "Dependency source for glog"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(Avro_SOURCE
+ "Dependency source for Avro C++"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+ define_option_string(GTest_SOURCE
+ "Dependency source for GoogleTest"
+ ""
+ AUTO
+ BUNDLED
+ SYSTEM)
+endif()
+
+macro(validate_config)
+ foreach(category ${PAIMON_OPTION_CATEGORIES})
+ set(option_names ${PAIMON_${category}_OPTION_NAMES})
+
+ foreach(name ${option_names})
+ set(possible_values ${${name}_OPTION_POSSIBLE_VALUES})
+ set(value "${${name}}")
+ if(possible_values)
+ if(NOT CMAKE_VERSION VERSION_LESS "3.3")
+ if(NOT "${value}" IN_LIST possible_values)
+ message(FATAL_ERROR "Configuration option ${name} got
invalid value '${value}'. "
+ "Allowed values:
${${name}_OPTION_ENUM}.")
+ endif()
+ endif()
+ endif()
+ endforeach()
+
+ endforeach()
+endmacro()
+
+macro(config_summary_message)
+ message(STATUS
"---------------------------------------------------------------------"
+ )
+ message(STATUS "Paimon version:
${PAIMON_VERSION}")
+ message(STATUS)
+ message(STATUS "Build configuration summary:")
+
+ message(STATUS " Generator: ${CMAKE_GENERATOR}")
+ message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
+ message(STATUS " Source directory: ${CMAKE_CURRENT_SOURCE_DIR}")
+ message(STATUS " Install prefix: ${CMAKE_INSTALL_PREFIX}")
+ message(STATUS " Install libdir: ${CMAKE_INSTALL_LIBDIR}")
+
+ if(${CMAKE_EXPORT_COMPILE_COMMANDS})
+ message(STATUS " Compile commands:
${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json"
+ )
+ endif()
+
+ foreach(category ${PAIMON_OPTION_CATEGORIES})
+
+ message(STATUS)
+ message(STATUS "${category} options:")
+ message(STATUS)
+
+ set(option_names ${PAIMON_${category}_OPTION_NAMES})
+
+ foreach(name ${option_names})
+ set(value "${${name}}")
+ if("${value}" STREQUAL "")
+ set(value "\"\"")
+ endif()
+
+ set(description ${${name}_OPTION_DESCRIPTION})
+
+ if(NOT ("${${name}_OPTION_ENUM}" STREQUAL ""))
+ set(summary "=${value} [default=${${name}_OPTION_ENUM}]")
+ else()
+ set(summary "=${value} [default=${${name}_OPTION_DEFAULT}]")
+ endif()
+
+ message(STATUS " ${name}${summary}")
+ foreach(description_line ${description})
+ message(STATUS " ${description_line}")
+ endforeach()
+ endforeach()
+
+ endforeach()
+
+endmacro()
diff --git a/cmake_modules/SetupCxxFlags.cmake
b/cmake_modules/SetupCxxFlags.cmake
new file mode 100644
index 0000000..043c043
--- /dev/null
+++ b/cmake_modules/SetupCxxFlags.cmake
@@ -0,0 +1,434 @@
+# 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.
+
+# Check if the target architecture and compiler supports some special
+# instruction sets that would boost performance.
+include(CheckCXXCompilerFlag)
+# Get cpu architecture
+
+message(STATUS "System processor: ${CMAKE_SYSTEM_PROCESSOR}")
+
+# Support C11
+if(NOT DEFINED CMAKE_C_STANDARD)
+ set(CMAKE_C_STANDARD 11)
+endif()
+
+# This ensures that things like c++11 get passed correctly
+if(NOT DEFINED CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 17)
+endif()
+
+# We require a C++11 compliant compiler
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+# Build with -fPIC so that can static link our libraries into other people's
+# shared libraries
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
+
+set(UNKNOWN_COMPILER_MESSAGE
+ "Unknown compiler: ${CMAKE_CXX_COMPILER_VERSION}
${CMAKE_CXX_COMPILER_VERSION}")
+
+# Defaults BUILD_WARNING_LEVEL to `CHECKIN`, unless CMAKE_BUILD_TYPE is
+# `RELEASE`, then it will default to `PRODUCTION`. The goal of defaulting to
+# `CHECKIN` is to avoid friction with long response time from CI.
+if(NOT BUILD_WARNING_LEVEL)
+ if("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
+ set(BUILD_WARNING_LEVEL PRODUCTION)
+ else()
+ set(BUILD_WARNING_LEVEL CHECKIN)
+ endif()
+endif(NOT BUILD_WARNING_LEVEL)
+string(TOUPPER ${BUILD_WARNING_LEVEL} BUILD_WARNING_LEVEL)
+
+message(STATUS "Paimon build warning level: ${BUILD_WARNING_LEVEL}")
+
+set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Werror")
+
+if("${BUILD_WARNING_LEVEL}" STREQUAL "CHECKIN")
+ # Pre-checkin builds
+ if(MSVC)
+ #
https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warnings-by-compiler-version
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /W3")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /wd4365")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /wd4267")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /wd4838")
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR
CMAKE_CXX_COMPILER_ID STREQUAL
+ "Clang")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wextra")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wdocumentation")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wglobal-constructors")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-missing-braces")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-unused-parameter")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-unknown-warning-option")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}
-Wno-constant-logical-operand")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}
-Wno-deprecated-declarations")
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-conversion")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}
-Wno-deprecated-declarations")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-sign-conversion")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-unused-variable")
+ else()
+ message(FATAL_ERROR "${UNKNOWN_COMPILER_MESSAGE}")
+ endif()
+
+elseif("${BUILD_WARNING_LEVEL}" STREQUAL "EVERYTHING")
+ # Pedantic builds for fixing warnings
+ if(MSVC)
+ string(REPLACE "/W3" "" CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /Wall")
+ #
https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level
+ # /wdnnnn disables a warning where "nnnn" is a warning number
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR
CMAKE_CXX_COMPILER_ID STREQUAL
+ "Clang")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Weverything")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-c++98-compat")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-c++98-compat-pedantic")
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wpedantic")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wextra")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-unused-parameter")
+ else()
+ message(FATAL_ERROR "${UNKNOWN_COMPILER_MESSAGE}")
+ endif()
+
+else()
+ # Production builds (warning are not treated as errors)
+ if(MSVC)
+ #
https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level
+ # TODO: Enable /Wall and disable individual warnings until build
compiles without errors
+ # /wdnnnn disables a warning where "nnnn" is a warning number
+ string(REPLACE "/W3" "" CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /W3")
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
+ OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
+ OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall")
+ else()
+ message(FATAL_ERROR "${UNKNOWN_COMPILER_MESSAGE}")
+ endif()
+
+endif()
+
+if(MSVC)
+ # Disable annoying "performance warning" about int-to-bool conversion
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /wd4800")
+
+ # Disable unchecked iterator warnings, equivalent to
/D_SCL_SECURE_NO_WARNINGS
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /wd4996")
+
+ # Disable "switch statement contains 'default' but no 'case' labels"
warning
+ # (required for protobuf, see
https://github.com/protocolbuffers/protobuf/issues/6885)
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /wd4065")
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "7.0" OR
CMAKE_CXX_COMPILER_VERSION
+ VERSION_GREATER "7.0")
+ # Without this, gcc >= 7 warns related to changes in C++17
+ set(CXX_ONLY_FLAGS
+ "${CXX_ONLY_FLAGS} -Wno-noexcept-type -Wno-stringop-overflow
-Wno-free-nonheap-object"
+ )
+ endif()
+
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.9")
+ # Add colors when paired with ninja
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
+ endif()
+
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0")
+ # Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43407
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-attributes")
+ endif()
+
+ if(CMAKE_UNITY_BUILD)
+ # Work around issue similar to
https://bugs.webkit.org/show_bug.cgi?id=176869
+ set(CXX_ONLY_FLAGS "${CXX_ONLY_FLAGS} -Wno-subobject-linkage")
+ endif()
+
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0"
+ AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0")
+ # When using the C++17 filesystem library (<filesystem>) with GCC 8,
you do need to explicitly link stdc++fs.
+ link_libraries(stdc++fs)
+ endif()
+
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID
STREQUAL
+ "Clang")
+ # Clang options for all builds
+
+ # Using Clang with ccache causes a bunch of spurious warnings that are
+ # purportedly fixed in the next version of ccache. See the following for
details:
+ #
+ # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html
+ #
http://petereisentraut.blogspot.com/2011/09/ccache-and-clang-part-2.html
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Qunused-arguments")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments")
+
+ # Avoid clang error when an unknown warning flag is passed
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-unknown-warning-option")
+ # Add colors when paired with ninja
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
+
+ # Don't complain about optimization passes that were not possible
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-pass-failed")
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-deprecated-declarations")
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ # Depending on the default OSX_DEPLOYMENT_TARGET (< 10.9), libstdc++
may be
+ # the default standard library which does not support C++11. libc++ is
the
+ # default from 10.9 onward.
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -stdlib=libc++")
+ endif()
+endif()
+
+# if build warning flags is set, add to CXX_COMMON_FLAGS
+if(BUILD_WARNING_FLAGS)
+ # Use BUILD_WARNING_FLAGS with BUILD_WARNING_LEVEL=everything to disable
+ # warnings (use with Clang's -Weverything flag to find potential errors)
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} ${BUILD_WARNING_FLAGS}")
+endif(BUILD_WARNING_FLAGS)
+
+# Only enable additional instruction sets if they are supported
+if(PAIMON_CPU_FLAG STREQUAL "x86")
+ if(PAIMON_SIMD_LEVEL STREQUAL "AVX512")
+ if(NOT CXX_SUPPORTS_AVX512)
+ message(FATAL_ERROR "AVX512 required but compiler doesn't support
it.")
+ endif()
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} ${PAIMON_AVX512_FLAG}")
+ add_definitions(-DPAIMON_HAVE_AVX512 -DPAIMON_HAVE_AVX2
-DPAIMON_HAVE_BMI2
+ -DPAIMON_HAVE_SSE4_2)
+ elseif(PAIMON_SIMD_LEVEL STREQUAL "AVX2")
+ if(NOT CXX_SUPPORTS_AVX2)
+ message(FATAL_ERROR "AVX2 required but compiler doesn't support
it.")
+ endif()
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} ${PAIMON_AVX2_FLAG}")
+ add_definitions(-DPAIMON_HAVE_AVX2 -DPAIMON_HAVE_BMI2
-DPAIMON_HAVE_SSE4_2)
+ elseif(PAIMON_SIMD_LEVEL STREQUAL "SSE4_2")
+ if(NOT CXX_SUPPORTS_SSE4_2)
+ message(FATAL_ERROR "SSE4.2 required but compiler doesn't support
it.")
+ endif()
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} ${PAIMON_SSE4_2_FLAG}")
+ add_definitions(-DPAIMON_HAVE_SSE4_2)
+ endif()
+endif()
+
+if(PAIMON_CPU_FLAG STREQUAL "ppc")
+ if(CXX_SUPPORTS_ALTIVEC AND PAIMON_ALTIVEC)
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} ${PAIMON_ALTIVEC_FLAG}")
+ endif()
+endif()
+
+if(PAIMON_CPU_FLAG STREQUAL "armv8")
+ if(NOT CXX_SUPPORTS_ARMV8_ARCH)
+ message(FATAL_ERROR "Unsupported arch flag:
${PAIMON_ARMV8_ARCH_FLAG}.")
+ endif()
+ if(PAIMON_ARMV8_ARCH_FLAG MATCHES "native")
+ message(FATAL_ERROR "native arch not allowed, please specify arch
explicitly.")
+ endif()
+ set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} ${PAIMON_ARMV8_ARCH_FLAG}")
+
+ add_definitions(-DPAIMON_HAVE_NEON)
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION
VERSION_LESS
+ "5.4")
+ message(WARNING "Disable Armv8 CRC and Crypto as compiler doesn't
support them well."
+ )
+ else()
+ if(PAIMON_ARMV8_ARCH_FLAG MATCHES "\\+crypto")
+ add_definitions(-DPAIMON_HAVE_ARMV8_CRYPTO)
+ endif()
+ # armv8.1+ implies crc support
+ if(PAIMON_ARMV8_ARCH_FLAG MATCHES "armv8\\.[1-9]|\\+crc")
+ add_definitions(-DPAIMON_HAVE_ARMV8_CRC)
+ endif()
+ endif()
+endif()
+
+# ----------------------------------------------------------------------
+# Setup Gold linker, if available. Code originally from Apache Kudu
+
+# Interrogates the linker version via the C++ compiler to determine whether
+# we're using the gold linker, and if so, extracts its version.
+#
+# If the gold linker is being used, sets GOLD_VERSION in the parent scope with
+# the extracted version.
+#
+# Any additional arguments are passed verbatim into the C++ compiler
invocation.
+function(GET_GOLD_VERSION)
+ # The gold linker is only for ELF binaries, which macOS doesn't use.
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-Wl,--version" ${ARGN}
+ ERROR_QUIET
+ OUTPUT_VARIABLE LINKER_OUTPUT)
+ # We're expecting LINKER_OUTPUT to look like one of these:
+ # GNU gold (version 2.24) 1.11
+ # GNU gold (GNU Binutils for Ubuntu 2.30) 1.15
+ if(LINKER_OUTPUT MATCHES "GNU gold")
+ string(REGEX MATCH "GNU gold \\([^\\)]*\\) (([0-9]+\\.?)+)" _
"${LINKER_OUTPUT}")
+ if(NOT CMAKE_MATCH_1)
+ message(SEND_ERROR "Could not extract GNU gold version. "
+ "Linker version output: ${LINKER_OUTPUT}")
+ endif()
+ set(GOLD_VERSION
+ "${CMAKE_MATCH_1}"
+ PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Is the compiler hard-wired to use the gold linker?
+if(NOT WIN32 AND NOT APPLE)
+ get_gold_version()
+ if(GOLD_VERSION)
+ set(MUST_USE_GOLD 1)
+ elseif(PAIMON_USE_LD_GOLD)
+ # Can the compiler optionally enable the gold linker?
+ get_gold_version("-fuse-ld=gold")
+
+ # We can't use the gold linker if it's inside devtoolset because the
compiler
+ # won't find it when invoked directly from make/ninja (which is
typically
+ # done outside devtoolset).
+ execute_process(COMMAND which ld.gold
+ OUTPUT_VARIABLE GOLD_LOCATION
+ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+ if("${GOLD_LOCATION}" MATCHES "^/opt/rh/devtoolset")
+ message("Skipping optional gold linker (version ${GOLD_VERSION})
because "
+ "it's in devtoolset")
+ set(GOLD_VERSION)
+ endif()
+ endif()
+
+ if(GOLD_VERSION)
+ # Older versions of the gold linker are vulnerable to a bug [1] which
+ # prevents weak symbols from being overridden properly. This leads to
+ # omitting of dependencies like tcmalloc (used in Kudu, where this
+ # workaround was written originally)
+ #
+ # How we handle this situation depends on other factors:
+ # - If gold is optional, we won't use it.
+ # - If gold is required, we'll either:
+ # - Raise an error in RELEASE builds (we shouldn't release such a
product), or
+ # - Drop tcmalloc in all other builds.
+ #
+ # 1. https://sourceware.org/bugzilla/show_bug.cgi?id=16979.
+ if("${GOLD_VERSION}" VERSION_LESS "1.12")
+ set(PAIMON_BUGGY_GOLD 1)
+ endif()
+ if(MUST_USE_GOLD)
+ message("Using hard-wired gold linker (version ${GOLD_VERSION})")
+ if(PAIMON_BUGGY_GOLD)
+ if("${PAIMON_LINK}" STREQUAL "d" AND "${CMAKE_BUILD_TYPE}"
STREQUAL
+ "RELEASE")
+ message(SEND_ERROR "Configured to use buggy gold with
dynamic linking "
+ "in a RELEASE build")
+ endif()
+ endif()
+ elseif(NOT PAIMON_BUGGY_GOLD)
+ # The Gold linker must be manually enabled.
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
+ message("Using optional gold linker (version ${GOLD_VERSION})")
+ else()
+ message("Optional gold linker is buggy, using ld linker instead")
+ endif()
+ else()
+ message("Using ld linker")
+ endif()
+endif()
+
+# compiler flags for different build types (run 'cmake
-DCMAKE_BUILD_TYPE=<type> .')
+# For all builds:
+# For CMAKE_BUILD_TYPE=Debug
+# -ggdb: Enable gdb debugging
+# For CMAKE_BUILD_TYPE=FastDebug
+# Same as DEBUG, except with some optimizations on.
+# For CMAKE_BUILD_TYPE=Release
+# -O3: Enable all compiler optimizations
+# Debug symbols are stripped for reduced binary size. Add
+# -DPAIMON_CXXFLAGS="-g" to add them
+if(NOT MSVC)
+ if(PAIMON_GGDB_DEBUG)
+ set(PAIMON_DEBUG_SYMBOL_TYPE "gdb")
+ set(C_FLAGS_DEBUG "-g${PAIMON_DEBUG_SYMBOL_TYPE} -O0")
+ set(C_FLAGS_FASTDEBUG "-g${PAIMON_DEBUG_SYMBOL_TYPE} -O1")
+ set(CXX_FLAGS_DEBUG "-g${PAIMON_DEBUG_SYMBOL_TYPE} -O0")
+ set(CXX_FLAGS_FASTDEBUG "-g${PAIMON_DEBUG_SYMBOL_TYPE} -O1")
+ else()
+ set(C_FLAGS_DEBUG "-g -O0")
+ set(C_FLAGS_FASTDEBUG "-g -O1")
+ set(CXX_FLAGS_DEBUG "-g -O0")
+ set(CXX_FLAGS_FASTDEBUG "-g -O1")
+ endif()
+
+ set(C_FLAGS_RELEASE "-O3 -DNDEBUG")
+ set(CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
+endif()
+
+set(C_FLAGS_PROFILE_GEN "${CXX_FLAGS_RELEASE} -fprofile-generate")
+set(C_FLAGS_PROFILE_BUILD "${CXX_FLAGS_RELEASE} -fprofile-use")
+set(CXX_FLAGS_PROFILE_GEN "${CXX_FLAGS_RELEASE} -fprofile-generate")
+set(CXX_FLAGS_PROFILE_BUILD "${CXX_FLAGS_RELEASE} -fprofile-use")
+
+# Set compile flags based on the build type.
+message("Configured for ${CMAKE_BUILD_TYPE} build (set with cmake
-DCMAKE_BUILD_TYPE={release,debug,...})"
+)
+if("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_DEBUG}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_DEBUG}")
+elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RELWITHDEBINFO")
+
+elseif("${CMAKE_BUILD_TYPE}" STREQUAL "FASTDEBUG")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_FASTDEBUG}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_FASTDEBUG}")
+elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_RELEASE}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_RELEASE}")
+elseif("${CMAKE_BUILD_TYPE}" STREQUAL "PROFILE_GEN")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_PROFILE_GEN}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_PROFILE_GEN}")
+elseif("${CMAKE_BUILD_TYPE}" STREQUAL "PROFILE_BUILD")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_PROFILE_BUILD}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_PROFILE_BUILD}")
+else()
+ message(FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}")
+endif()
+
+if("${CMAKE_CXX_FLAGS}" MATCHES "-DNDEBUG")
+ set(PAIMON_DEFINITION_FLAGS "-DNDEBUG")
+else()
+ set(PAIMON_DEFINITION_FLAGS "")
+endif()
+
+message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
+
+# ----------------------------------------------------------------------
+# MSVC-specific linker options
+
+if(MSVC)
+ set(MSVC_LINKER_FLAGS)
+ if(MSVC_LINK_VERBOSE)
+ set(MSVC_LINKER_FLAGS "${MSVC_LINKER_FLAGS} /VERBOSE:LIB")
+ endif()
+ if(NOT PAIMON_USE_STATIC_CRT)
+ set(MSVC_LINKER_FLAGS "${MSVC_LINKER_FLAGS} /NODEFAULTLIB:LIBCMT")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}
${MSVC_LINKER_FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}
${MSVC_LINKER_FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}
${MSVC_LINKER_FLAGS}")
+ endif()
+endif()
diff --git a/cmake_modules/san-config.cmake b/cmake_modules/san-config.cmake
new file mode 100644
index 0000000..bb078c7
--- /dev/null
+++ b/cmake_modules/san-config.cmake
@@ -0,0 +1,40 @@
+# 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.
+
+add_library(paimon_sanitizer_flags INTERFACE)
+
+if(PAIMON_USE_ASAN)
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ target_compile_options(paimon_sanitizer_flags INTERFACE
-fsanitize=address
+
-fno-omit-frame-pointer)
+ target_link_options(paimon_sanitizer_flags INTERFACE
-fsanitize=address)
+ message(STATUS "Address Sanitizer enabled")
+ else()
+ message(WARNING "Address Sanitizer is only supported for GCC and Clang
compilers")
+ endif()
+endif()
+
+if(PAIMON_USE_UBSAN)
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ target_compile_options(paimon_sanitizer_flags INTERFACE
-fsanitize=undefined
+
-fno-omit-frame-pointer)
+ target_link_options(paimon_sanitizer_flags INTERFACE
-fsanitize=undefined)
+ message(STATUS "Undefined Behavior Sanitizer enabled")
+ else()
+ message(WARNING "Undefined Behavior Sanitizer is only supported for
GCC and Clang compilers"
+ )
+ endif()
+endif()