This is an automated email from the ASF dual-hosted git repository.
raulcd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new bc51a762141 GH-48091: [C++] Use FetchContent for bundled c-ares
(#48092)
bc51a762141 is described below
commit bc51a7621419272cb847b1c6da160959c1934cf3
Author: Raúl Cumplido <[email protected]>
AuthorDate: Wed Nov 19 14:11:18 2025 +0100
GH-48091: [C++] Use FetchContent for bundled c-ares (#48092)
### Rationale for this change
As a follow up of requiring a minimum CMake version >= 3.25 we discussed
moving our dependencies from ExternalProject to FetchContent. This can heavily
simplify our third party dependency management. Moving c-ares is the next step
before moving grpc.
### What changes are included in this PR?
The general change is moving from `ExternalProject` to `FetchContent`.
It also add some required integration due to other dependencies, like grpc,
using `ExternalProject`. We not only have to build but also install in order
for those other dependencies to find c-ares. This causes some timing issues
between config, build, install that requires us to create a custom target to
depend on so the other dependencies find abseil.
### Are these changes tested?
Yes, the changes are tested locally and on CI.
### Are there any user-facing changes?
No
* GitHub Issue: #48091
Authored-by: Raúl Cumplido <[email protected]>
Signed-off-by: Raúl Cumplido <[email protected]>
---
cpp/cmake_modules/ThirdpartyToolchain.cmake | 107 ++++++++++++++++++++--------
1 file changed, 76 insertions(+), 31 deletions(-)
diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake
b/cpp/cmake_modules/ThirdpartyToolchain.cmake
index 910f256c81e..835baec87ba 100644
--- a/cpp/cmake_modules/ThirdpartyToolchain.cmake
+++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake
@@ -2950,33 +2950,67 @@ if(ARROW_WITH_UTF8PROC)
resolve_dependency(${utf8proc_resolve_dependency_args})
endif()
-macro(build_cares)
- message(STATUS "Building c-ares from source")
- set(CARES_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/cares_ep-install")
- set(CARES_INCLUDE_DIR "${CARES_PREFIX}/include")
-
- # If you set -DCARES_SHARED=ON then the build system names the library
- # libcares_static.a
- set(CARES_STATIC_LIB
-
"${CARES_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}cares${CMAKE_STATIC_LIBRARY_SUFFIX}"
- )
+function(build_cares)
+ list(APPEND CMAKE_MESSAGE_INDENT "c-ares: ")
+ message(STATUS "Building c-ares from source using FetchContent")
+ set(CARES_VENDORED
+ TRUE
+ PARENT_SCOPE)
+ set(CARES_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/cares_fc-install")
+ set(CARES_PREFIX
+ "${CARES_PREFIX}"
+ PARENT_SCOPE)
- set(CARES_CMAKE_ARGS "${EP_COMMON_CMAKE_ARGS}"
"-DCMAKE_INSTALL_PREFIX=${CARES_PREFIX}"
- -DCARES_SHARED=OFF -DCARES_STATIC=ON)
+ fetchcontent_declare(cares
+ URL ${CARES_SOURCE_URL}
+ URL_HASH "SHA256=${ARROW_CARES_BUILD_SHA256_CHECKSUM}")
- externalproject_add(cares_ep
- ${EP_COMMON_OPTIONS}
- URL ${CARES_SOURCE_URL}
- URL_HASH "SHA256=${ARROW_CARES_BUILD_SHA256_CHECKSUM}"
- CMAKE_ARGS ${CARES_CMAKE_ARGS}
- BUILD_BYPRODUCTS "${CARES_STATIC_LIB}")
+ prepare_fetchcontent()
- file(MAKE_DIRECTORY ${CARES_INCLUDE_DIR})
+ set(CARES_SHARED OFF)
+ set(CARES_STATIC ON)
+ set(CARES_INSTALL ON)
+ set(CARES_BUILD_TOOLS OFF)
+ set(CARES_BUILD_TESTS OFF)
+ fetchcontent_makeavailable(cares)
+
+ # gRPC requires c-ares to be installed to a known location.
+ # We have to do this in two steps to avoid double installation of c-ares
+ # when Arrow is installed.
+ # This custom target ensures c-ares is built before we install
+ add_custom_target(cares_built DEPENDS c-ares::cares)
+
+ # Disable c-ares's install script after it's built to prevent double
installation
+ add_custom_command(OUTPUT "${cares_BINARY_DIR}/cmake_install.cmake.saved"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${cares_BINARY_DIR}/cmake_install.cmake"
+ "${cares_BINARY_DIR}/cmake_install.cmake.saved"
+ COMMAND ${CMAKE_COMMAND} -E echo
+ "# c-ares install disabled to prevent double
installation with Arrow"
+ > "${cares_BINARY_DIR}/cmake_install.cmake"
+ DEPENDS cares_built
+ COMMENT "Disabling c-ares install to prevent double
installation"
+ VERBATIM)
+
+ add_custom_target(cares_install_disabled ALL
+ DEPENDS "${cares_BINARY_DIR}/cmake_install.cmake.saved")
+
+ # Install c-ares to CARES_PREFIX for gRPC to find
+ add_custom_command(OUTPUT "${CARES_PREFIX}/.cares_installed"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${cares_BINARY_DIR}/cmake_install.cmake.saved"
+ "${cares_BINARY_DIR}/cmake_install.cmake.tmp"
+ COMMAND ${CMAKE_COMMAND}
-DCMAKE_INSTALL_PREFIX=${CARES_PREFIX}
+ -DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
+ "${cares_BINARY_DIR}/cmake_install.cmake.tmp" ||
+ ${CMAKE_COMMAND} -E true
+ COMMAND ${CMAKE_COMMAND} -E touch
"${CARES_PREFIX}/.cares_installed"
+ DEPENDS cares_install_disabled
+ COMMENT "Installing c-ares to ${CARES_PREFIX} for gRPC"
+ VERBATIM)
- add_library(c-ares::cares STATIC IMPORTED)
- set_target_properties(c-ares::cares PROPERTIES IMPORTED_LOCATION
"${CARES_STATIC_LIB}")
- target_include_directories(c-ares::cares BEFORE INTERFACE
"${CARES_INCLUDE_DIR}")
- add_dependencies(c-ares::cares cares_ep)
+ # Make cares_fc depend on the install completion marker
+ add_custom_target(cares_fc DEPENDS "${CARES_PREFIX}/.cares_installed")
if(APPLE)
# libresolv must be linked from c-ares version 1.16.1
@@ -2985,10 +3019,11 @@ macro(build_cares)
"${LIBRESOLV_LIBRARY}")
endif()
- set(CARES_VENDORED TRUE)
-
- list(APPEND ARROW_BUNDLED_STATIC_LIBS c-ares::cares)
-endmacro()
+ set(ARROW_BUNDLED_STATIC_LIBS
+ ${ARROW_BUNDLED_STATIC_LIBS} c-ares::cares
+ PARENT_SCOPE)
+ list(POP_BACK CMAKE_MESSAGE_INDENT)
+endfunction()
# ----------------------------------------------------------------------
# Dependencies for Arrow Flight RPC
@@ -3136,7 +3171,9 @@ function(build_absl)
# This is due to upstream absl::cctz issue
# https://github.com/abseil/abseil-cpp/issues/283
find_library(CoreFoundation CoreFoundation)
- set_property(TARGET absl::time
+ # When ABSL_ENABLE_INSTALL is ON, the real target is "time" not "absl_time"
+ # Cannot use set_property on alias targets (absl::time is an alias)
+ set_property(TARGET time
APPEND
PROPERTY INTERFACE_LINK_LIBRARIES ${CoreFoundation})
endif()
@@ -3189,7 +3226,7 @@ macro(build_grpc)
add_dependencies(grpc_dependencies absl_fc)
endif()
if(CARES_VENDORED)
- add_dependencies(grpc_dependencies cares_ep)
+ add_dependencies(grpc_dependencies cares_fc)
endif()
if(GFLAGS_VENDORED)
@@ -3208,8 +3245,16 @@ macro(build_grpc)
get_filename_component(GRPC_PB_ROOT "${GRPC_PROTOBUF_INCLUDE_DIR}" DIRECTORY)
get_target_property(GRPC_Protobuf_PROTOC_LIBRARY ${ARROW_PROTOBUF_LIBPROTOC}
IMPORTED_LOCATION)
- get_target_property(GRPC_CARES_INCLUDE_DIR c-ares::cares
INTERFACE_INCLUDE_DIRECTORIES)
- get_filename_component(GRPC_CARES_ROOT "${GRPC_CARES_INCLUDE_DIR}" DIRECTORY)
+
+ # For FetchContent c-ares, use the install prefix directly
+ if(CARES_VENDORED)
+ set(GRPC_CARES_ROOT "${CARES_PREFIX}")
+ else()
+ get_target_property(GRPC_CARES_INCLUDE_DIR c-ares::cares
+ INTERFACE_INCLUDE_DIRECTORIES)
+ get_filename_component(GRPC_CARES_ROOT "${GRPC_CARES_INCLUDE_DIR}"
DIRECTORY)
+ endif()
+
get_target_property(GRPC_RE2_INCLUDE_DIR re2::re2
INTERFACE_INCLUDE_DIRECTORIES)
get_filename_component(GRPC_RE2_ROOT "${GRPC_RE2_INCLUDE_DIR}" DIRECTORY)