Browse Source

Move bundling of JSON-C to CMake. (#17207)

* Move bundling of JSON-C to CMake.

* Fix JSON-C build option passing.

* Force CMake policy 77 to new behavior for JSON-C build.

This is required to ensure that options we set are propagated correctly
into the sub-project.

* Fix include path selection and handling for bundled JSON-C.

* Fix include ordering again.

* Fixup JSON header compat link handling.
Austin S. Hemmelgarn 11 months ago
parent
commit
0f5b137471

+ 4 - 18
CMakeLists.txt

@@ -271,15 +271,17 @@ if(NOT HAVE_LOG10)
 endif()
 
 #
-# Custom modules
+# Custom Modules
 #
 
+include(NetdataJSONC)
 include(NetdataYAML)
 
 #
 # Checks from custom modules
 #
 
+netdata_detect_jsonc()
 netdata_detect_libyaml()
 
 #
@@ -1511,23 +1513,7 @@ endif()
 # judy
 target_link_libraries(libnetdata PUBLIC judy)
 
-# json-c
-if(ENABLE_BUNDLED_JSONC)
-        add_library(jsonc STATIC IMPORTED)
-        set_property(TARGET jsonc PROPERTY
-                     IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/externaldeps/jsonc/libjson-c.a")
-
-        target_include_directories(libnetdata BEFORE PUBLIC "${CMAKE_SOURCE_DIR}/externaldeps/jsonc")
-        target_link_libraries(libnetdata PUBLIC jsonc)
-else()
-        pkg_check_modules(JSONC REQUIRED json-c)
-        target_include_directories(libnetdata BEFORE PUBLIC ${JSONC_INCLUDE_DIRS})
-        target_compile_definitions(libnetdata PUBLIC ${JSONC_CFLAGS_OTHER})
-        target_link_libraries(libnetdata PUBLIC ${JSONC_LDFLAGS})
-endif()
-
-# message(FATAL_ERROR "jsonc libraries: ${JSONC_LIBRARIES}")
-# message(FATAL_ERROR "jsonc ldflags: ${JSONC_LDFLAGS}")
+netdata_add_jsonc_to_target(libnetdata)
 
 netdata_add_libyaml_to_target(libnetdata)
 

+ 0 - 67
netdata-installer.sh

@@ -556,73 +556,6 @@ fi
 
 trap build_error EXIT
 
-# -----------------------------------------------------------------------------
-build_jsonc() {
-  env_cmd=''
-
-  if [ -z "${DONT_SCRUB_CFLAGS_EVEN_THOUGH_IT_MAY_BREAK_THINGS}" ]; then
-    env_cmd="env CFLAGS='-fPIC -pipe' CXXFLAGS='-fPIC -pipe' LDFLAGS="
-  fi
-
-  cd "${1}" > /dev/null || exit 1
-  run eval "${env_cmd} ${cmake} ${CMAKE_OPTS} -DBUILD_SHARED_LIBS=OFF -DDISABLE_WERROR=On ."
-  run eval "${env_cmd} ${cmake} --build . --parallel ${JOBS} -- ${BUILD_OPTS}"
-  cd - > /dev/null || return 1
-}
-
-copy_jsonc() {
-  target_dir="${PWD}/externaldeps/jsonc"
-
-  run mkdir -p "${target_dir}" "${target_dir}/json-c" || return 1
-
-  run cp "${1}/libjson-c.a" "${target_dir}/libjson-c.a" || return 1
-  # shellcheck disable=SC2086
-  run cp ${1}/*.h "${target_dir}/json-c" || return 1
-}
-
-bundle_jsonc() {
-  # If --build-json-c flag or not json-c on system, then bundle our own json-c
-  if [ -z "${NETDATA_BUILD_JSON_C}" ] && pkg-config json-c; then
-    NETDATA_BUILD_JSON_C=0
-    return 0
-  fi
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::group::Bundling JSON-C."
-
-  progress "Prepare JSON-C"
-
-  JSONC_PACKAGE_VERSION="$(cat packaging/jsonc.version)"
-
-  tmp="$(mktemp -d -t netdata-jsonc-XXXXXX)"
-  JSONC_PACKAGE_BASENAME="json-c-${JSONC_PACKAGE_VERSION}.tar.gz"
-
-  if fetch_and_verify "jsonc" \
-    "https://github.com/json-c/json-c/archive/${JSONC_PACKAGE_BASENAME}" \
-    "${JSONC_PACKAGE_BASENAME}" \
-    "${tmp}" \
-    "${NETDATA_LOCAL_TARBALL_OVERRIDE_JSONC}"; then
-    if run tar --no-same-owner -xf "${tmp}/${JSONC_PACKAGE_BASENAME}" -C "${tmp}" &&
-      build_jsonc "${tmp}/json-c-json-c-${JSONC_PACKAGE_VERSION}" &&
-      copy_jsonc "${tmp}/json-c-json-c-${JSONC_PACKAGE_VERSION}" &&
-      rm -rf "${tmp}"; then
-      run_ok "JSON-C built and prepared."
-      NETDATA_BUILD_JSON_C=1
-    else
-      run_failed "Failed to build JSON-C, Netdata Cloud support will be disabled in this build."
-      NETDATA_BUILD_JSON_C=0
-      ENABLE_CLOUD=0
-    fi
-  else
-    run_failed "Unable to fetch sources for JSON-C, Netdata Cloud support will be disabled in this build."
-    NETDATA_BUILD_JSON_C=0
-    ENABLE_CLOUD=0
-  fi
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
-}
-
-bundle_jsonc
-
 # -----------------------------------------------------------------------------
 
 get_kernel_version() {

+ 102 - 0
packaging/cmake/Modules/NetdataJSONC.cmake

@@ -0,0 +1,102 @@
+# Functions and macros for handling of JSON-C
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Handle bundling of json-c.
+#
+# This pulls it in as a sub-project using FetchContent functionality.
+#
+# This needs to be a function and not a macro for variable scoping
+# reasons. All the things we care about from the sub-project are exposed
+# as targets, which are globally scoped and not function scoped.
+function(netdata_bundle_jsonc)
+        include(FetchContent)
+        include(NetdataFetchContentExtra)
+
+        message(STATUS "Preparing vendored copy of JSON-C")
+
+        if(ENABLE_BUNDLED_JSONC)
+                set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE NEVER)
+        endif()
+
+        set(FETCHCONTENT_FULLY_DISCONNECTED Off)
+
+        # JSON-C supports older versions of CMake than we do, so set
+        # the correct values for the few policies we actually need.
+        set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
+
+        # JSON-C's build system does string comparisons against option
+        # values instead of treating them as booleans, so we need to use
+        # proper strings for option values instead of just setting them
+        # to true or false.
+        set(DISABLE_BSYMBOLIC ON)
+        set(DISABLE_WERROR ON)
+        set(DISABLE_EXTRA_LIBS ON)
+        set(BUILD_SHARED_LIBS OFF)
+        set(BUILD_STATIC_LIBS ON)
+        set(BUILD_APPS OFF)
+
+        FetchContent_Declare(json-c
+                GIT_REPOSITORY https://github.com/json-c/json-c
+                GIT_TAG b4c371fa0cbc4dcbaccc359ce9e957a22988fb34 # json-c-0.17-20230812
+        )
+
+        FetchContent_MakeAvailable_NoInstall(json-c)
+
+        message(STATUS "Finished preparing vendored copy of JSON-C")
+endfunction()
+
+# Handle setup of json-c for the build.
+#
+# This will attempt to find json-c using pkg_check_modules. If it finds
+# a usable copy, that will be used. If not, it will bundle a vendored copy
+# as a sub-project.
+#
+# Irrespective of how json-c is to be included, library names,
+# include directories, and compile definitions will be specified in the
+# NETDATA_JSONC_* variables for later use.
+macro(netdata_detect_jsonc)
+        if(NOT ENABLE_BUNDLED_JSONC)
+                pkg_check_modules(JSONC json-c)
+        endif()
+
+        if(NOT JSONC_FOUND)
+                netdata_bundle_jsonc()
+                set(NETDATA_JSONC_LDFLAGS json-c)
+                set(NETDATA_JSONC_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/include)
+                get_target_property(NETDATA_JSONC_CFLAGS_OTHER json-c INTERFACE_COMPILE_DEFINITIONS)
+
+                if(NETDATA_JSONC_CFLAGS_OTHER STREQUAL NETDATA_JSONC_CFLAGS_OTHER-NOTFOUND)
+                        set(NETDATA_JSONC_CFLAGS_OTHER "")
+                endif()
+
+                add_custom_command(
+                        OUTPUT ${PROJECT_BINARY_DIR}/include/json-c
+                        COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/include
+                        COMMAND ${CMAKE_COMMAND} -E create_symlink ${json-c_BINARY_DIR} ${PROJECT_BINARY_DIR}/include/json-c
+                        COMMENT "Create compatibility symlink for vendored JSON-C headers"
+                        DEPENDS json-c
+                )
+                add_custom_target(
+                        json-c-compat-link
+                        DEPENDS ${PROJECT_BINARY_DIR}/include/json-c
+                )
+        else()
+                set(NETDATA_JSONC_LDFLAGS ${JSONC_LDFLAGS})
+                set(NETDATA_JSONC_CFLAGS_OTHER ${JSONC_CFLAGS_OTHER})
+                set(NETDATA_JSONC_INCLUDE_DIRS ${JSONC_INCLUDE_DIRS})
+                add_custom_target(json-c-compat-link)
+        endif()
+endmacro()
+
+# Add json-c as a public link dependency of the specified target.
+#
+# The specified target must already exist, and the netdata_detect_json-c
+# macro must have already been run at least once for this to work correctly.
+function(netdata_add_jsonc_to_target _target)
+        target_include_directories(${_target} PUBLIC ${NETDATA_JSONC_INCLUDE_DIRS})
+        target_compile_definitions(${_target} PUBLIC ${NETDATA_JSONC_CFLAGS_OTHER})
+        target_link_libraries(${_target} PUBLIC ${NETDATA_JSONC_LDFLAGS})
+        add_dependencies(${_target} json-c-compat-link)
+endfunction()

+ 0 - 1
packaging/jsonc.checksums

@@ -1 +0,0 @@
-ec4eb70e0f6c0d707b9b1ec646cf7c860f4abb3562a90ea6e4d78d177fd95303  json-c-0.14-20200419.tar.gz

+ 0 - 1
packaging/jsonc.version

@@ -1 +0,0 @@
-0.14-20200419