diff --git a/cmake_modules/DefineOptions.cmake b/cmake_modules/DefineOptions.cmake index 587b50a1..4add68f8 100644 --- a/cmake_modules/DefineOptions.cmake +++ b/cmake_modules/DefineOptions.cmake @@ -156,11 +156,10 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") "Prefer shared libraries for system third-party packages" OFF) define_option_string(Arrow_SOURCE - "Dependency source for Apache Arrow" + "Dependency source for Apache Arrow; SYSTEM is unsupported" "" AUTO - BUNDLED - SYSTEM) + BUNDLED) define_option_string(zstd_SOURCE "Dependency source for zstd" "" @@ -198,11 +197,10 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") BUNDLED SYSTEM) define_option_string(ORC_SOURCE - "Dependency source for Apache ORC" + "Dependency source for Apache ORC; SYSTEM is unsupported" "" AUTO - BUNDLED - SYSTEM) + BUNDLED) define_option_string(fmt_SOURCE "Dependency source for fmt" "" diff --git a/cmake_modules/FindGTestAlt.cmake b/cmake_modules/FindGTestAlt.cmake index 9dd2a2db..a59e8cc0 100644 --- a/cmake_modules/FindGTestAlt.cmake +++ b/cmake_modules/FindGTestAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_GTEST_ROOTS) set(_PAIMON_GTEST_FIND_ARGS HINTS ${_PAIMON_GTEST_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(GTest CONFIG QUIET ${_PAIMON_GTEST_FIND_ARGS}) if(NOT TARGET GTest::gtest @@ -65,8 +66,20 @@ if(NOT TARGET GTest::gtest endif() endif() else() - get_target_property(GTEST_INCLUDE_DIR GTest::gtest INTERFACE_INCLUDE_DIRECTORIES) - set(GTestAlt_FOUND TRUE) + paimon_find_target_headers(GTEST_INCLUDE_DIR + GTest::gtest + NAMES + gtest/gtest.h + ${_PAIMON_GTEST_FIND_ARGS}) + paimon_find_target_headers(GMOCK_INCLUDE_DIR + GTest::gmock + NAMES + gmock/gmock.h + ${_PAIMON_GTEST_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(GTestAlt REQUIRED_VARS GTEST_INCLUDE_DIR + GMOCK_INCLUDE_DIR) endif() if(GTestAlt_FOUND) diff --git a/cmake_modules/FindLZ4Alt.cmake b/cmake_modules/FindLZ4Alt.cmake index fcbbf157..c00d0a2d 100644 --- a/cmake_modules/FindLZ4Alt.cmake +++ b/cmake_modules/FindLZ4Alt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_LZ4_ROOTS) set(_PAIMON_LZ4_FIND_ARGS HINTS ${_PAIMON_LZ4_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(lz4 CONFIG QUIET ${_PAIMON_LZ4_FIND_ARGS}) find_package(LZ4 CONFIG QUIET ${_PAIMON_LZ4_FIND_ARGS}) @@ -30,18 +31,24 @@ foreach(_target IN LISTS _PAIMON_LZ4_TARGETS) endforeach() if(_PAIMON_LZ4_TARGET) - get_target_property(LZ4_INCLUDE_DIR ${_PAIMON_LZ4_TARGET} - INTERFACE_INCLUDE_DIRECTORIES) - if(NOT TARGET lz4) + paimon_find_target_headers(LZ4_INCLUDE_DIR + ${_PAIMON_LZ4_TARGET} + NAMES + lz4.h + ${_PAIMON_LZ4_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(LZ4Alt REQUIRED_VARS LZ4_INCLUDE_DIR) + + if(LZ4Alt_FOUND AND NOT TARGET lz4) add_library(lz4 INTERFACE IMPORTED) - if(LZ4_INCLUDE_DIR) - set_target_properties(lz4 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${LZ4_INCLUDE_DIR}") - endif() + set_target_properties(lz4 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${LZ4_INCLUDE_DIR}") target_link_libraries(lz4 INTERFACE ${_PAIMON_LZ4_TARGET}) endif() - set(LZ4_LIBRARIES ${_PAIMON_LZ4_TARGET}) - set(LZ4Alt_FOUND TRUE) + if(LZ4Alt_FOUND) + set(LZ4_LIBRARIES ${_PAIMON_LZ4_TARGET}) + endif() else() find_package(PkgConfig QUIET) if(PkgConfig_FOUND) diff --git a/cmake_modules/FindPackageUtils.cmake b/cmake_modules/FindPackageUtils.cmake new file mode 100644 index 00000000..2a82a960 --- /dev/null +++ b/cmake_modules/FindPackageUtils.cmake @@ -0,0 +1,91 @@ +# Copyright 2026-present Alibaba Inc. +# +# 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 +# +# 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. + +function(paimon_find_target_headers OUT_VAR TARGET_NAME) + set(options NO_DEFAULT_PATH) + set(one_value_args) + set(multi_value_args NAMES HINTS PATH_SUFFIXES) + cmake_parse_arguments(ARG + "${options}" + "${one_value_args}" + "${multi_value_args}" + ${ARGN}) + + if(NOT TARGET ${TARGET_NAME} OR NOT ARG_NAMES) + set(${OUT_VAR} + "${OUT_VAR}-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + set(_target_include_dirs) + foreach(_property INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + INCLUDE_DIRECTORIES) + get_target_property(_property_value ${TARGET_NAME} ${_property}) + if(_property_value AND NOT _property_value MATCHES "-NOTFOUND$") + list(APPEND _target_include_dirs ${_property_value}) + endif() + endforeach() + + set(_search_dirs) + foreach(_dir IN LISTS _target_include_dirs) + if(_dir MATCHES "^\\$$") + list(APPEND _search_dirs "${CMAKE_MATCH_1}") + elseif(_dir MATCHES "^\\$$") + if(IS_ABSOLUTE "${CMAKE_MATCH_1}") + list(APPEND _search_dirs "${CMAKE_MATCH_1}") + endif() + elseif(NOT _dir MATCHES "^\\$<") + list(APPEND _search_dirs "${_dir}") + endif() + endforeach() + + list(APPEND _search_dirs ${ARG_HINTS}) + if(_search_dirs) + list(REMOVE_DUPLICATES _search_dirs) + endif() + + string(MAKE_C_IDENTIFIER "${TARGET_NAME}_${ARG_NAMES}" _header_var_suffix) + set(_header_dir_var "PAIMON_${_header_var_suffix}_HEADER_DIR") + set(_find_args NAMES ${ARG_NAMES}) + if(_search_dirs) + list(APPEND _find_args HINTS ${_search_dirs}) + endif() + if(ARG_PATH_SUFFIXES) + list(APPEND _find_args PATH_SUFFIXES ${ARG_PATH_SUFFIXES}) + endif() + list(APPEND _find_args NO_DEFAULT_PATH) + + unset(${_header_dir_var} CACHE) + find_path(${_header_dir_var} ${_find_args}) + + if(NOT ${_header_dir_var}) + get_property(_partial_targets GLOBAL PROPERTY PAIMON_PARTIAL_SYSTEM_TARGETS) + list(APPEND _partial_targets "${TARGET_NAME}: ${ARG_NAMES}") + set_property(GLOBAL PROPERTY PAIMON_PARTIAL_SYSTEM_TARGETS "${_partial_targets}") + endif() + + set(${OUT_VAR} + "${${_header_dir_var}}" + PARENT_SCOPE) + + unset(${_header_dir_var} CACHE) + unset(_find_args) + unset(_header_dir_var) + unset(_header_var_suffix) + unset(_partial_targets) + unset(_property_value) + unset(_search_dirs) + unset(_target_include_dirs) +endfunction() diff --git a/cmake_modules/FindProtobufAlt.cmake b/cmake_modules/FindProtobufAlt.cmake index ce8ed6e0..245727e1 100644 --- a/cmake_modules/FindProtobufAlt.cmake +++ b/cmake_modules/FindProtobufAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_PROTOBUF_ROOTS) set(_PAIMON_PROTOBUF_FIND_ARGS HINTS ${_PAIMON_PROTOBUF_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(Protobuf CONFIG QUIET ${_PAIMON_PROTOBUF_FIND_ARGS}) set(_PAIMON_PROTOBUF_LIBRARY_TARGETS protobuf::libprotobuf Protobuf::libprotobuf) @@ -52,29 +53,29 @@ if(_PAIMON_PROTOBUF_LIBRARY_TARGET AND NOT PROTOBUF_COMPILER) endif() if(_PAIMON_PROTOBUF_LIBRARY_TARGET) + paimon_find_target_headers(PROTOBUF_INCLUDE_DIR + ${_PAIMON_PROTOBUF_LIBRARY_TARGET} + NAMES + google/protobuf/message.h + ${_PAIMON_PROTOBUF_FIND_ARGS}) + include(FindPackageHandleStandardArgs) find_package_handle_standard_args( - ProtobufAlt REQUIRED_VARS _PAIMON_PROTOBUF_LIBRARY_TARGET PROTOBUF_COMPILER) + ProtobufAlt REQUIRED_VARS _PAIMON_PROTOBUF_LIBRARY_TARGET PROTOBUF_INCLUDE_DIR + PROTOBUF_COMPILER) if(ProtobufAlt_FOUND) - get_target_property(PROTOBUF_INCLUDE_DIR ${_PAIMON_PROTOBUF_LIBRARY_TARGET} - INTERFACE_INCLUDE_DIRECTORIES) - if(NOT TARGET libprotobuf) add_library(libprotobuf INTERFACE IMPORTED) - if(PROTOBUF_INCLUDE_DIR) - set_target_properties(libprotobuf PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${PROTOBUF_INCLUDE_DIR}") - endif() + set_target_properties(libprotobuf PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${PROTOBUF_INCLUDE_DIR}") target_link_libraries(libprotobuf INTERFACE ${_PAIMON_PROTOBUF_LIBRARY_TARGET}) endif() if(_PAIMON_PROTOC_LIBRARY_TARGET AND NOT TARGET libprotoc) add_library(libprotoc INTERFACE IMPORTED) - if(PROTOBUF_INCLUDE_DIR) - set_target_properties(libprotoc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${PROTOBUF_INCLUDE_DIR}") - endif() + set_target_properties(libprotoc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${PROTOBUF_INCLUDE_DIR}") target_link_libraries(libprotoc INTERFACE ${_PAIMON_PROTOC_LIBRARY_TARGET}) endif() diff --git a/cmake_modules/FindRE2Alt.cmake b/cmake_modules/FindRE2Alt.cmake index e2940ba6..0856ab2a 100644 --- a/cmake_modules/FindRE2Alt.cmake +++ b/cmake_modules/FindRE2Alt.cmake @@ -18,12 +18,22 @@ if(_PAIMON_RE2_ROOTS) set(_PAIMON_RE2_FIND_ARGS HINTS ${_PAIMON_RE2_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(re2 CONFIG QUIET ${_PAIMON_RE2_FIND_ARGS}) if(TARGET re2::re2) - get_target_property(RE2_INCLUDE_DIR re2::re2 INTERFACE_INCLUDE_DIRECTORIES) - set(RE2_LIBRARIES re2::re2) - set(RE2Alt_FOUND TRUE) + paimon_find_target_headers(RE2_INCLUDE_DIR + re2::re2 + NAMES + re2/re2.h + ${_PAIMON_RE2_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(RE2Alt REQUIRED_VARS RE2_INCLUDE_DIR) + + if(RE2Alt_FOUND) + set(RE2_LIBRARIES re2::re2) + endif() else() find_package(PkgConfig QUIET) if(PkgConfig_FOUND) diff --git a/cmake_modules/FindRapidJSONAlt.cmake b/cmake_modules/FindRapidJSONAlt.cmake index c09b5829..f389dba3 100644 --- a/cmake_modules/FindRapidJSONAlt.cmake +++ b/cmake_modules/FindRapidJSONAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_RAPIDJSON_ROOTS) set(_PAIMON_RAPIDJSON_FIND_ARGS HINTS ${_PAIMON_RAPIDJSON_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(RapidJSON CONFIG QUIET ${_PAIMON_RAPIDJSON_FIND_ARGS}) set(_PAIMON_RAPIDJSON_TARGETS RapidJSON RapidJSON::RapidJSON) @@ -29,12 +30,20 @@ foreach(_target IN LISTS _PAIMON_RAPIDJSON_TARGETS) endforeach() if(_PAIMON_RAPIDJSON_TARGET) - if(NOT TARGET RapidJSON) + paimon_find_target_headers(RAPIDJSON_INCLUDE_DIR + ${_PAIMON_RAPIDJSON_TARGET} + NAMES + rapidjson/rapidjson.h + ${_PAIMON_RAPIDJSON_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(RapidJSONAlt REQUIRED_VARS RAPIDJSON_INCLUDE_DIR) + + if(RapidJSONAlt_FOUND AND NOT TARGET RapidJSON) add_library(RapidJSON INTERFACE IMPORTED) + target_include_directories(RapidJSON INTERFACE "${RAPIDJSON_INCLUDE_DIR}") target_link_libraries(RapidJSON INTERFACE ${_PAIMON_RAPIDJSON_TARGET}) endif() - get_target_property(RAPIDJSON_INCLUDE_DIR RapidJSON INTERFACE_INCLUDE_DIRECTORIES) - set(RapidJSONAlt_FOUND TRUE) else() find_path(RAPIDJSON_INCLUDE_DIR NAMES rapidjson/rapidjson.h ${_PAIMON_RAPIDJSON_FIND_ARGS} diff --git a/cmake_modules/FindSnappyAlt.cmake b/cmake_modules/FindSnappyAlt.cmake index 2b8b9d83..bf2a8b0c 100644 --- a/cmake_modules/FindSnappyAlt.cmake +++ b/cmake_modules/FindSnappyAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_SNAPPY_ROOTS) set(_PAIMON_SNAPPY_FIND_ARGS HINTS ${_PAIMON_SNAPPY_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(Snappy CONFIG QUIET ${_PAIMON_SNAPPY_FIND_ARGS}) set(_PAIMON_SNAPPY_TARGETS Snappy::snappy snappy::snappy) @@ -29,18 +30,24 @@ foreach(_target IN LISTS _PAIMON_SNAPPY_TARGETS) endforeach() if(_PAIMON_SNAPPY_TARGET) - get_target_property(SNAPPY_INCLUDE_DIR ${_PAIMON_SNAPPY_TARGET} - INTERFACE_INCLUDE_DIRECTORIES) - if(NOT TARGET snappy) + paimon_find_target_headers(SNAPPY_INCLUDE_DIR + ${_PAIMON_SNAPPY_TARGET} + NAMES + snappy.h + ${_PAIMON_SNAPPY_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(SnappyAlt REQUIRED_VARS SNAPPY_INCLUDE_DIR) + + if(SnappyAlt_FOUND AND NOT TARGET snappy) add_library(snappy INTERFACE IMPORTED) - if(SNAPPY_INCLUDE_DIR) - set_target_properties(snappy PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${SNAPPY_INCLUDE_DIR}") - endif() + set_target_properties(snappy PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${SNAPPY_INCLUDE_DIR}") target_link_libraries(snappy INTERFACE ${_PAIMON_SNAPPY_TARGET}) endif() - set(SNAPPY_LIBRARIES ${_PAIMON_SNAPPY_TARGET}) - set(SnappyAlt_FOUND TRUE) + if(SnappyAlt_FOUND) + set(SNAPPY_LIBRARIES ${_PAIMON_SNAPPY_TARGET}) + endif() else() find_package(PkgConfig QUIET) if(PkgConfig_FOUND) diff --git a/cmake_modules/FindTBBAlt.cmake b/cmake_modules/FindTBBAlt.cmake index d0e17826..b6491e0c 100644 --- a/cmake_modules/FindTBBAlt.cmake +++ b/cmake_modules/FindTBBAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_TBB_ROOTS) set(_PAIMON_TBB_FIND_ARGS HINTS ${_PAIMON_TBB_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(TBB CONFIG QUIET ${_PAIMON_TBB_FIND_ARGS}) set(_PAIMON_TBB_TARGETS TBB::tbb tbb) @@ -29,17 +30,22 @@ foreach(_target IN LISTS _PAIMON_TBB_TARGETS) endforeach() if(_PAIMON_TBB_TARGET) - if(NOT TARGET tbb) + paimon_find_target_headers(TBB_INCLUDE_DIR + ${_PAIMON_TBB_TARGET} + NAMES + tbb/tbb.h + oneapi/tbb/tbb.h + ${_PAIMON_TBB_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(TBBAlt REQUIRED_VARS TBB_INCLUDE_DIR) + + if(TBBAlt_FOUND AND NOT TARGET tbb) add_library(tbb INTERFACE IMPORTED) - get_target_property(TBB_INCLUDE_DIR ${_PAIMON_TBB_TARGET} - INTERFACE_INCLUDE_DIRECTORIES) - if(TBB_INCLUDE_DIR) - set_target_properties(tbb PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${TBB_INCLUDE_DIR}") - endif() + set_target_properties(tbb PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${TBB_INCLUDE_DIR}") target_link_libraries(tbb INTERFACE ${_PAIMON_TBB_TARGET}) endif() - set(TBBAlt_FOUND TRUE) else() find_package(PkgConfig QUIET) if(PkgConfig_FOUND) diff --git a/cmake_modules/FindZLIBAlt.cmake b/cmake_modules/FindZLIBAlt.cmake index 9bb35ecb..6e53d431 100644 --- a/cmake_modules/FindZLIBAlt.cmake +++ b/cmake_modules/FindZLIBAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_ZLIB_ROOTS) set(_PAIMON_ZLIB_FIND_ARGS HINTS ${_PAIMON_ZLIB_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) if(_PAIMON_ZLIB_ROOTS) find_package(ZLIB CONFIG QUIET ${_PAIMON_ZLIB_FIND_ARGS}) else() @@ -25,20 +26,26 @@ else() endif() if(TARGET ZLIB::ZLIB) - if(NOT TARGET zlib) + paimon_find_target_headers(ZLIB_INCLUDE_DIR + ZLIB::ZLIB + NAMES + zlib.h + HINTS + ${ZLIB_INCLUDE_DIRS} + ${_PAIMON_ZLIB_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(ZLIBAlt REQUIRED_VARS ZLIB_INCLUDE_DIR) + + if(ZLIBAlt_FOUND AND NOT TARGET zlib) add_library(zlib INTERFACE IMPORTED) - get_target_property(ZLIB_INCLUDE_DIR ZLIB::ZLIB INTERFACE_INCLUDE_DIRECTORIES) - if(NOT ZLIB_INCLUDE_DIR) - set(ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIRS}) - endif() - if(ZLIB_INCLUDE_DIR) - set_target_properties(zlib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${ZLIB_INCLUDE_DIR}") - endif() + set_target_properties(zlib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${ZLIB_INCLUDE_DIR}") target_link_libraries(zlib INTERFACE ZLIB::ZLIB) endif() - set(ZLIB_LIBRARIES ZLIB::ZLIB) - set(ZLIBAlt_FOUND TRUE) + if(ZLIBAlt_FOUND) + set(ZLIB_LIBRARIES ZLIB::ZLIB) + endif() else() find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${_PAIMON_ZLIB_FIND_ARGS} diff --git a/cmake_modules/FindfmtAlt.cmake b/cmake_modules/FindfmtAlt.cmake index 8229c498..8a05d6f8 100644 --- a/cmake_modules/FindfmtAlt.cmake +++ b/cmake_modules/FindfmtAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_FMT_ROOTS) set(_PAIMON_FMT_FIND_ARGS HINTS ${_PAIMON_FMT_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(fmt CONFIG QUIET ${_PAIMON_FMT_FIND_ARGS}) set(_PAIMON_FMT_TARGETS fmt::fmt fmt::fmt-header-only) @@ -29,18 +30,24 @@ foreach(_target IN LISTS _PAIMON_FMT_TARGETS) endforeach() if(_PAIMON_FMT_TARGET) - if(NOT TARGET fmt) + paimon_find_target_headers(FMT_INCLUDE_DIR + ${_PAIMON_FMT_TARGET} + NAMES + fmt/core.h + ${_PAIMON_FMT_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(fmtAlt REQUIRED_VARS FMT_INCLUDE_DIR) + + if(fmtAlt_FOUND AND NOT TARGET fmt) add_library(fmt INTERFACE IMPORTED) - get_target_property(FMT_INCLUDE_DIR ${_PAIMON_FMT_TARGET} - INTERFACE_INCLUDE_DIRECTORIES) - if(FMT_INCLUDE_DIR) - set_target_properties(fmt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${FMT_INCLUDE_DIR}") - endif() + set_target_properties(fmt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${FMT_INCLUDE_DIR}") target_link_libraries(fmt INTERFACE ${_PAIMON_FMT_TARGET}) endif() - set(FMT_LIBRARIES ${_PAIMON_FMT_TARGET}) - set(fmtAlt_FOUND TRUE) + if(fmtAlt_FOUND) + set(FMT_LIBRARIES ${_PAIMON_FMT_TARGET}) + endif() else() find_package(PkgConfig QUIET) if(PkgConfig_FOUND) diff --git a/cmake_modules/FindglogAlt.cmake b/cmake_modules/FindglogAlt.cmake index 3105451c..ecd08cda 100644 --- a/cmake_modules/FindglogAlt.cmake +++ b/cmake_modules/FindglogAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_GLOG_ROOTS) set(_PAIMON_GLOG_FIND_ARGS HINTS ${_PAIMON_GLOG_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(glog CONFIG QUIET ${_PAIMON_GLOG_FIND_ARGS}) set(_PAIMON_GLOG_TARGETS glog::glog glog) @@ -29,17 +30,21 @@ foreach(_target IN LISTS _PAIMON_GLOG_TARGETS) endforeach() if(_PAIMON_GLOG_TARGET) - if(NOT TARGET glog) + paimon_find_target_headers(GLOG_INCLUDE_DIR + ${_PAIMON_GLOG_TARGET} + NAMES + glog/logging.h + ${_PAIMON_GLOG_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(glogAlt REQUIRED_VARS GLOG_INCLUDE_DIR) + + if(glogAlt_FOUND AND NOT TARGET glog) add_library(glog INTERFACE IMPORTED) - get_target_property(GLOG_INCLUDE_DIR ${_PAIMON_GLOG_TARGET} - INTERFACE_INCLUDE_DIRECTORIES) - if(GLOG_INCLUDE_DIR) - set_target_properties(glog PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${GLOG_INCLUDE_DIR}") - endif() + set_target_properties(glog PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${GLOG_INCLUDE_DIR}") target_link_libraries(glog INTERFACE ${_PAIMON_GLOG_TARGET}) endif() - set(glogAlt_FOUND TRUE) else() find_package(PkgConfig QUIET) if(PkgConfig_FOUND) diff --git a/cmake_modules/FindzstdAlt.cmake b/cmake_modules/FindzstdAlt.cmake index 02afe07e..2fb986a3 100644 --- a/cmake_modules/FindzstdAlt.cmake +++ b/cmake_modules/FindzstdAlt.cmake @@ -18,6 +18,7 @@ if(_PAIMON_ZSTD_ROOTS) set(_PAIMON_ZSTD_FIND_ARGS HINTS ${_PAIMON_ZSTD_ROOTS} NO_DEFAULT_PATH) endif() +include(FindPackageUtils) find_package(zstd CONFIG QUIET ${_PAIMON_ZSTD_FIND_ARGS}) set(_PAIMON_ZSTD_TARGETS) @@ -38,18 +39,24 @@ foreach(_target IN LISTS _PAIMON_ZSTD_TARGETS) endforeach() if(_PAIMON_ZSTD_TARGET) - get_target_property(ZSTD_INCLUDE_DIR ${_PAIMON_ZSTD_TARGET} - INTERFACE_INCLUDE_DIRECTORIES) - if(NOT TARGET zstd) + paimon_find_target_headers(ZSTD_INCLUDE_DIR + ${_PAIMON_ZSTD_TARGET} + NAMES + zstd.h + ${_PAIMON_ZSTD_FIND_ARGS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(zstdAlt REQUIRED_VARS ZSTD_INCLUDE_DIR) + + if(zstdAlt_FOUND AND NOT TARGET zstd) add_library(zstd INTERFACE IMPORTED) - if(ZSTD_INCLUDE_DIR) - set_target_properties(zstd PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${ZSTD_INCLUDE_DIR}") - endif() + set_target_properties(zstd PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${ZSTD_INCLUDE_DIR}") target_link_libraries(zstd INTERFACE ${_PAIMON_ZSTD_TARGET}) endif() - set(ZSTD_LIBRARIES ${_PAIMON_ZSTD_TARGET}) - set(zstdAlt_FOUND TRUE) + if(zstdAlt_FOUND) + set(ZSTD_LIBRARIES ${_PAIMON_ZSTD_TARGET}) + endif() else() find_package(PkgConfig QUIET) if(PkgConfig_FOUND) diff --git a/cmake_modules/ThirdpartyToolchain.cmake b/cmake_modules/ThirdpartyToolchain.cmake index 2be9097b..9ef5e9fb 100644 --- a/cmake_modules/ThirdpartyToolchain.cmake +++ b/cmake_modules/ThirdpartyToolchain.cmake @@ -414,7 +414,7 @@ endfunction() function(paimon_apply_dependency_source_defaults) paimon_get_dependency_source(Arrow _arrow_source) - if(_arrow_source STREQUAL "SYSTEM" OR _arrow_source STREQUAL "BUNDLED") + if(_arrow_source STREQUAL "BUNDLED") foreach(_dependency zstd Snappy @@ -426,17 +426,6 @@ function(paimon_apply_dependency_source_defaults) "follow Arrow_SOURCE to avoid mixed transitive dependencies") endforeach() elseif(_arrow_source STREQUAL "AUTO") - paimon_configure_dependency_root(Arrow "${_arrow_source}" _arrow_resolved_source) - find_package(ArrowAlt QUIET MODULE) - if(ArrowAlt_FOUND) - set(_arrow_dependency_default SYSTEM) - set(_arrow_dependency_reason - "system Arrow found during AUTO dependency precheck") - else() - set(_arrow_dependency_default BUNDLED) - set(_arrow_dependency_reason - "system Arrow not found during AUTO dependency precheck") - endif() foreach(_dependency zstd Snappy @@ -444,32 +433,42 @@ function(paimon_apply_dependency_source_defaults) ZLIB RE2) paimon_set_dependency_source_default( - ${_dependency} ${_arrow_dependency_default} "${_arrow_dependency_reason}") + ${_dependency} BUNDLED + "Arrow_SOURCE=AUTO uses bundled Arrow with project-specific patches") endforeach() endif() if(PAIMON_ENABLE_ORC) paimon_get_dependency_source(ORC _orc_source) - if(_orc_source STREQUAL "SYSTEM" OR _orc_source STREQUAL "BUNDLED") + if(_orc_source STREQUAL "BUNDLED") paimon_set_dependency_source_default( Protobuf ${_orc_source} "follow ORC_SOURCE to avoid mixed transitive dependencies") elseif(_orc_source STREQUAL "AUTO") - paimon_configure_dependency_root(ORC "${_orc_source}" _orc_resolved_source) - find_package(ORCAlt QUIET MODULE) - if(ORCAlt_FOUND) - paimon_set_dependency_source_default( - Protobuf SYSTEM "system ORC found during AUTO dependency precheck") - else() - paimon_set_dependency_source_default( - Protobuf BUNDLED - "system ORC not found during AUTO dependency precheck") - endif() + paimon_set_dependency_source_default( + Protobuf BUNDLED + "ORC_SOURCE=AUTO uses bundled ORC with project-specific patches") endif() endif() endfunction() function(paimon_configure_dependency_root DEPENDENCY_NAME SOURCE_VALUE OUT_SOURCE) + if("${DEPENDENCY_NAME}" STREQUAL "Arrow" OR "${DEPENDENCY_NAME}" STREQUAL "ORC") + if("${SOURCE_VALUE}" STREQUAL "SYSTEM") + message(FATAL_ERROR "${DEPENDENCY_NAME}_SOURCE=SYSTEM is not supported " + "because paimon-cpp requires project-specific " + "${DEPENDENCY_NAME} patches. If this value comes " + "from PAIMON_DEPENDENCY_SOURCE=SYSTEM, set " + "${DEPENDENCY_NAME}_SOURCE=BUNDLED or leave " + "${DEPENDENCY_NAME}_SOURCE=AUTO.") + elseif("${SOURCE_VALUE}" STREQUAL "AUTO") + set(${OUT_SOURCE} + "BUNDLED" + PARENT_SCOPE) + return() + endif() + endif() + set(${OUT_SOURCE} "${SOURCE_VALUE}" PARENT_SCOPE) @@ -635,6 +634,7 @@ macro(resolve_dependency DEPENDENCY_NAME) "${_paimon_requested_source}" "${_paimon_target_name}") elseif(_paimon_resolved_source STREQUAL "AUTO") message(STATUS "Resolving ${DEPENDENCY_NAME} with AUTO source") + set_property(GLOBAL PROPERTY PAIMON_PARTIAL_SYSTEM_TARGETS "") find_package(${_paimon_alt_package_name} QUIET MODULE) if(${_paimon_found_var}) message(STATUS "Using system ${DEPENDENCY_NAME}") @@ -645,6 +645,16 @@ macro(resolve_dependency DEPENDENCY_NAME) ${DEPENDENCY_NAME} "${_paimon_requested_source}" "SYSTEM" "${_paimon_target_name}") else() + get_property(_paimon_partial_system_targets GLOBAL + PROPERTY PAIMON_PARTIAL_SYSTEM_TARGETS) + if(_paimon_partial_system_targets) + list(REMOVE_DUPLICATES _paimon_partial_system_targets) + message(FATAL_ERROR "System ${DEPENDENCY_NAME} was partially found " + "but is missing required development headers: " + "${_paimon_partial_system_targets}. Install " + "the matching development package or set " + "${DEPENDENCY_NAME}_SOURCE=BUNDLED.") + endif() message(STATUS "System ${DEPENDENCY_NAME} not found; using bundled") paimon_build_dependency(${DEPENDENCY_NAME}) set(PAIMON_${DEPENDENCY_NAME}_ACTUAL_SOURCE @@ -665,6 +675,7 @@ macro(resolve_dependency DEPENDENCY_NAME) unset(_paimon_requested_source) unset(_paimon_resolved_source) unset(_paimon_target_name) + unset(_paimon_partial_system_targets) endmacro() function(paimon_warn_if_mixed_arrow_dependencies)