This is an automated email from the ASF dual-hosted git repository.
kou 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 c1a8255084 GH-48316: [C++] Use FetchContent for bundled nlohmann-json
(#48320)
c1a8255084 is described below
commit c1a8255084158bfb9799018a306de6ff2bb2185f
Author: Raúl Cumplido <[email protected]>
AuthorDate: Fri Dec 5 15:31:25 2025 +0100
GH-48316: [C++] Use FetchContent for bundled nlohmann-json (#48320)
### 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 simplify
our third party dependency management.
### What changes are included in this PR?
The general change is moving nlohmann-json from `ExternalProject` to
`FetchContent`.
The expectation is that we will be able to clean up installation once
google-cloud-cpp is also migrated.
### Are these changes tested?
Yes, the changes are tested locally and on CI.
### Are there any user-facing changes?
No
Authored-by: Raúl Cumplido <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
cpp/cmake_modules/ThirdpartyToolchain.cmake | 104 ++++++++++++++++++++--------
1 file changed, 74 insertions(+), 30 deletions(-)
diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake
b/cpp/cmake_modules/ThirdpartyToolchain.cmake
index ad90ec6c43..64adc8a060 100644
--- a/cpp/cmake_modules/ThirdpartyToolchain.cmake
+++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake
@@ -3465,38 +3465,73 @@ function(build_crc32c_once)
list(POP_BACK CMAKE_MESSAGE_INDENT)
endfunction()
-macro(build_nlohmann_json)
- message(STATUS "Building nlohmann-json from source")
- # "Build" nlohmann-json
- set(NLOHMANN_JSON_PREFIX
"${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json_ep-install")
- set(NLOHMANN_JSON_INCLUDE_DIR "${NLOHMANN_JSON_PREFIX}/include")
- set(NLOHMANN_JSON_CMAKE_ARGS
- ${EP_COMMON_CMAKE_ARGS} "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
- # google-cloud-cpp requires JSON_MultipleHeaders=ON
- -DJSON_BuildTests=OFF -DJSON_MultipleHeaders=ON)
+function(build_nlohmann_json)
+ list(APPEND CMAKE_MESSAGE_INDENT "nlohmann-json: ")
+ message(STATUS "Building nlohmann-json from source using FetchContent")
+ set(NLOHMANN_JSON_VENDORED
+ TRUE
+ PARENT_SCOPE)
+ set(NLOHMANN_JSON_PREFIX
"${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json_fc-install")
+ set(NLOHMANN_JSON_PREFIX
+ "${NLOHMANN_JSON_PREFIX}"
+ PARENT_SCOPE)
- # We can remove this once we remove -DCMAKE_POLICY_VERSION_MINIMUM=3.5
- # from EP_COMMON_CMAKE_ARGS.
- list(REMOVE_ITEM NLOHMANN_JSON_CMAKE_ARGS -DCMAKE_POLICY_VERSION_MINIMUM=3.5)
+ fetchcontent_declare(nlohmann_json
+ ${FC_DECLARE_COMMON_OPTIONS}
+ URL ${NLOHMANN_JSON_SOURCE_URL}
+ URL_HASH
"SHA256=${ARROW_NLOHMANN_JSON_BUILD_SHA256_CHECKSUM}")
- set(NLOHMANN_JSON_BUILD_BYPRODUCTS
${NLOHMANN_JSON_PREFIX}/include/nlohmann/json.hpp)
+ prepare_fetchcontent()
- externalproject_add(nlohmann_json_ep
- ${EP_COMMON_OPTIONS}
- INSTALL_DIR ${NLOHMANN_JSON_PREFIX}
- URL ${NLOHMANN_JSON_SOURCE_URL}
- URL_HASH
"SHA256=${ARROW_NLOHMANN_JSON_BUILD_SHA256_CHECKSUM}"
- CMAKE_ARGS ${NLOHMANN_JSON_CMAKE_ARGS}
- BUILD_BYPRODUCTS ${NLOHMANN_JSON_BUILD_BYPRODUCTS})
+ # google-cloud-cpp requires JSON_MultipleHeaders=ON
+ set(JSON_BuildTests OFF)
+ set(JSON_MultipleHeaders ON)
+ set(JSON_Install ON)
+ fetchcontent_makeavailable(nlohmann_json)
- # Work around https://gitlab.kitware.com/cmake/cmake/issues/15052
- file(MAKE_DIRECTORY ${NLOHMANN_JSON_INCLUDE_DIR})
+ # google-cloud-cpp requires nlohmann_json to be installed to a known
location.
+ # We have to do this in two steps to avoid double installation of
nlohmann_json
+ # when Arrow is installed.
+ # This custom target ensures nlohmann_json is built before we install.
+ add_custom_target(nlohmann_json_built DEPENDS nlohmann_json::nlohmann_json)
- add_library(nlohmann_json::nlohmann_json INTERFACE IMPORTED)
- target_include_directories(nlohmann_json::nlohmann_json BEFORE
- INTERFACE "${NLOHMANN_JSON_INCLUDE_DIR}")
- add_dependencies(nlohmann_json::nlohmann_json nlohmann_json_ep)
-endmacro()
+ # Disable nlohmann_json's install script after it's built to prevent double
installation.
+ add_custom_command(OUTPUT
"${nlohmann_json_BINARY_DIR}/cmake_install.cmake.saved"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${nlohmann_json_BINARY_DIR}/cmake_install.cmake"
+
"${nlohmann_json_BINARY_DIR}/cmake_install.cmake.saved"
+ COMMAND ${CMAKE_COMMAND} -E echo
+ "# nlohmann-json install disabled to prevent
double installation with Arrow"
+ >
"${nlohmann_json_BINARY_DIR}/cmake_install.cmake"
+ DEPENDS nlohmann_json_built
+ COMMENT "Disabling nlohmann-json install to prevent
double installation"
+ VERBATIM)
+
+ add_custom_target(nlohmann_json_install_disabled ALL
+ DEPENDS
"${nlohmann_json_BINARY_DIR}/cmake_install.cmake.saved")
+
+ # Install nlohmann_json to NLOHMANN_JSON_PREFIX for google-cloud-cpp to find.
+ add_custom_command(OUTPUT "${NLOHMANN_JSON_PREFIX}/.nlohmann_json_installed"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+
"${nlohmann_json_BINARY_DIR}/cmake_install.cmake.saved"
+
"${nlohmann_json_BINARY_DIR}/cmake_install.cmake.tmp"
+ COMMAND ${CMAKE_COMMAND}
+ -DCMAKE_INSTALL_PREFIX=${NLOHMANN_JSON_PREFIX}
+ -DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
+
"${nlohmann_json_BINARY_DIR}/cmake_install.cmake.tmp" ||
+ ${CMAKE_COMMAND} -E true
+ COMMAND ${CMAKE_COMMAND} -E touch
+ "${NLOHMANN_JSON_PREFIX}/.nlohmann_json_installed"
+ DEPENDS nlohmann_json_install_disabled
+ COMMENT "Installing nlohmann-json to
${NLOHMANN_JSON_PREFIX} for google-cloud-cpp"
+ VERBATIM)
+
+ # Make nlohmann_json_fc depend on the install completion marker.
+ add_custom_target(nlohmann_json_fc
+ DEPENDS "${NLOHMANN_JSON_PREFIX}/.nlohmann_json_installed")
+
+ list(POP_BACK CMAKE_MESSAGE_INDENT)
+endfunction()
if(ARROW_WITH_NLOHMANN_JSON)
resolve_dependency(nlohmann_json)
get_target_property(nlohmann_json_INCLUDE_DIR nlohmann_json::nlohmann_json
@@ -3559,7 +3594,11 @@ macro(build_google_cloud_cpp_storage)
add_dependencies(google_cloud_cpp_dependencies zlib_ep)
endif()
add_dependencies(google_cloud_cpp_dependencies crc32c_fc)
- add_dependencies(google_cloud_cpp_dependencies nlohmann_json::nlohmann_json)
+ if(NLOHMANN_JSON_VENDORED)
+ add_dependencies(google_cloud_cpp_dependencies nlohmann_json_fc)
+ else()
+ add_dependencies(google_cloud_cpp_dependencies
nlohmann_json::nlohmann_json)
+ endif()
set(GOOGLE_CLOUD_CPP_STATIC_LIBRARY_STORAGE
"${GOOGLE_CLOUD_CPP_INSTALL_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}google_cloud_cpp_storage${CMAKE_STATIC_LIBRARY_SUFFIX}"
@@ -4052,9 +4091,14 @@ macro(build_opentelemetry)
CONFIGURE_COMMAND ""
INSTALL_COMMAND ""
EXCLUDE_FROM_ALL OFF)
+ if(NLOHMANN_JSON_VENDORED)
+ add_dependencies(opentelemetry_dependencies nlohmann_json_fc)
+ else()
+ add_dependencies(opentelemetry_dependencies nlohmann_json::nlohmann_json)
+ endif()
- add_dependencies(opentelemetry_dependencies nlohmann_json::nlohmann_json
- opentelemetry_proto_ep ${ARROW_PROTOBUF_LIBPROTOBUF})
+ add_dependencies(opentelemetry_dependencies opentelemetry_proto_ep
+ ${ARROW_PROTOBUF_LIBPROTOBUF})
# Ensure vendored protobuf is installed before OpenTelemetry builds
if(PROTOBUF_VENDORED)