summaryrefslogtreecommitdiffstats
path: root/packaging/cmake/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/cmake/Modules')
-rw-r--r--packaging/cmake/Modules/FindGo.cmake39
-rw-r--r--packaging/cmake/Modules/NetdataCompilerFlags.cmake75
-rw-r--r--packaging/cmake/Modules/NetdataDetectSystemd.cmake42
-rw-r--r--packaging/cmake/Modules/NetdataFetchContentExtra.cmake27
-rw-r--r--packaging/cmake/Modules/NetdataGoTools.cmake85
-rw-r--r--packaging/cmake/Modules/NetdataProtobuf.cmake225
-rw-r--r--packaging/cmake/Modules/NetdataYAML.cmake65
7 files changed, 558 insertions, 0 deletions
diff --git a/packaging/cmake/Modules/FindGo.cmake b/packaging/cmake/Modules/FindGo.cmake
new file mode 100644
index 000000000..454a0051e
--- /dev/null
+++ b/packaging/cmake/Modules/FindGo.cmake
@@ -0,0 +1,39 @@
+# Custom CMake module to find the Go toolchain
+#
+# Copyright (c) 2024 Netdata Inc
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This is a relatively orthodox CMake Find Module. It can be used by
+# simply including it and then invoking `find_package(Go)`.
+#
+# Version handling is done by CMake itself via the
+# find_package_handle_standard_args() function, so `find_package(Go 1.21)`
+# will also work correctly.
+
+if(GO_FOUND)
+ return()
+endif()
+
+# Two passes are needed here so that we prefer a copy in `/usr/local/go/bin` over a system copy.
+find_program(GO_EXECUTABLE go PATHS /usr/local/go/bin DOC "Go toolchain" NO_DEFAULT_PATH)
+find_program(GO_EXECUTABLE go DOC "Go toolchain")
+
+if (GO_EXECUTABLE)
+ execute_process(
+ COMMAND ${GO_EXECUTABLE} version
+ OUTPUT_VARIABLE GO_VERSION_STRING
+ RESULT_VARIABLE RESULT
+ )
+ if (RESULT EQUAL 0)
+ string(REGEX MATCH "go([0-9]+\\.[0-9]+(\\.[0-9]+)?)" GO_VERSION_STRING "${GO_VERSION_STRING}")
+ string(REGEX MATCH "([0-9]+\\.[0-9]+(\\.[0-9]+)?)" GO_VERSION_STRING "${GO_VERSION_STRING}")
+ endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ Go
+ REQUIRED_VARS GO_EXECUTABLE
+ VERSION_VAR GO_VERSION_STRING
+)
diff --git a/packaging/cmake/Modules/NetdataCompilerFlags.cmake b/packaging/cmake/Modules/NetdataCompilerFlags.cmake
new file mode 100644
index 000000000..894e244ce
--- /dev/null
+++ b/packaging/cmake/Modules/NetdataCompilerFlags.cmake
@@ -0,0 +1,75 @@
+# Functions to simplify handling of extra compiler flags.
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+include(CheckCCompilerFlag)
+include(CheckCXXCompilerFlag)
+
+# Construct a pre-processor safe name
+#
+# This takes a specified value, and assigns the generated name to the
+# specified target.
+function(make_cpp_safe_name value target)
+ string(REPLACE "-" "_" tmp "${value}")
+ string(REPLACE "=" "_" tmp "${tmp}")
+ set(${target} "${tmp}" PARENT_SCOPE)
+endfunction()
+
+# Conditionally add an extra compiler flag to C and C++ flags.
+#
+# If the language flags already match the `match` argument, skip this flag.
+# Otherwise, check for support for `flag` and if support is found, add it to
+# the language-specific `target` flag group.
+function(add_simple_extra_compiler_flag match flag target)
+ set(CMAKE_REQUIRED_FLAGS "-Werror")
+
+ make_cpp_safe_name("${flag}" flag_name)
+
+ if(NOT ${CMAKE_C_FLAGS} MATCHES ${match})
+ check_c_compiler_flag("${flag}" HAVE_C_${flag_name})
+ if(HAVE_C_${flag_name})
+ set(${target}_C_FLAGS "${${target}_C_FLAGS} ${flag}" PARENT_SCOPE)
+ endif()
+ endif()
+
+ if(NOT ${CMAKE_CXX_FLAGS} MATCHES ${match})
+ check_cxx_compiler_flag("${flag}" HAVE_CXX_${flag_name})
+ if(HAVE_CXX_${flag_name})
+ set(${target}_CXX_FLAGS "${${target}_CXX_FLAGS} ${flag}" PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+# Same as add_simple_extra_compiler_flag, but check for a second flag if the
+# first one is unsupported.
+function(add_double_extra_compiler_flag match flag1 flag2 target)
+ set(CMAKE_REQUIRED_FLAGS "-Werror")
+
+ make_cpp_safe_name("${flag1}" flag1_name)
+ make_cpp_safe_name("${flag2}" flag2_name)
+
+ if(NOT ${CMAKE_C_FLAGS} MATCHES ${match})
+ check_c_compiler_flag("${flag1}" HAVE_C_${flag1_name})
+ if(HAVE_C_${flag1_name})
+ set(${target}_C_FLAGS "${${target}_C_FLAGS} ${flag1}" PARENT_SCOPE)
+ else()
+ check_c_compiler_flag("${flag2}" HAVE_C_${flag2_name})
+ if(HAVE_C_${flag2_name})
+ set(${target}_C_FLAGS "${${target}_C_FLAGS} ${flag2}" PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+
+ if(NOT ${CMAKE_CXX_FLAGS} MATCHES ${match})
+ check_cxx_compiler_flag("${flag1}" HAVE_CXX_${flag1_name})
+ if(HAVE_CXX_${flag1_name})
+ set(${target}_CXX_FLAGS "${${target}_CXX_FLAGS} ${flag1}" PARENT_SCOPE)
+ else()
+ check_cxx_compiler_flag("${flag2}" HAVE_CXX_${flag2_name})
+ if(HAVE_CXX_${flag2_name})
+ set(${target}_CXX_FLAGS "${${target}_CXX_FLAGS} ${flag2}" PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
diff --git a/packaging/cmake/Modules/NetdataDetectSystemd.cmake b/packaging/cmake/Modules/NetdataDetectSystemd.cmake
new file mode 100644
index 000000000..5c0e6e09e
--- /dev/null
+++ b/packaging/cmake/Modules/NetdataDetectSystemd.cmake
@@ -0,0 +1,42 @@
+# CMake Module to handle all the systemd-related checks for Netdata.
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+macro(detect_systemd)
+ find_library(SYSTEMD_LIBRARY NAMES systemd)
+
+ set(ENABLE_DSYSTEMD_DBUS NO)
+ pkg_check_modules(SYSTEMD libsystemd)
+
+ if(SYSTEMD_FOUND)
+ set(CMAKE_REQUIRED_LIBRARIES_BEFORE_SYSTEMD "${CMAKE_REQUIRED_LIBRARIES}")
+ set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};${SYSTEMD_LIBRARIES}")
+
+ check_c_source_compiles("
+ #include <systemd/sd-journal.h>
+
+ int main() {
+ int x = SD_JOURNAL_OS_ROOT;
+ return 0;
+ }" HAVE_SD_JOURNAL_OS_ROOT)
+
+ check_symbol_exists(SD_JOURNAL_OS_ROOT "systemd/sd-journal.h" HAVE_SD_JOURNAL_OS_ROOT)
+ check_symbol_exists(sd_journal_open_files_fd "systemd/sd-journal.h" HAVE_SD_JOURNAL_OPEN_FILES_FD)
+ check_symbol_exists(sd_journal_restart_fields "systemd/sd-journal.h" HAVE_SD_JOURNAL_RESTART_FIELDS)
+ check_symbol_exists(sd_journal_get_seqnum "systemd/sd-journal.h" HAVE_SD_JOURNAL_GET_SEQNUM)
+
+ check_symbol_exists(sd_bus_default_system "systemd/sd-bus.h" HAVE_SD_BUS_DEFAULT_SYSTEM)
+ check_symbol_exists(sd_bus_call_method "systemd/sd-bus.h" HAVE_SD_BUS_CALL_METHOD)
+ check_symbol_exists(sd_bus_message_enter_container "systemd/sd-bus.h" HAVE_SD_BUS_MESSAGE_ENTER_CONTAINER)
+ check_symbol_exists(sd_bus_message_read "systemd/sd-bus.h" HAVE_SD_BUS_MESSAGE_READ)
+ check_symbol_exists(sd_bus_message_exit_container "systemd/sd-bus.h" HAVE_SD_BUS_MESSAGE_EXIT_CONTAINER)
+
+ set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES_BEFORE_SYSTEMD}")
+
+ set(HAVE_SYSTEMD True)
+ if(HAVE_SD_BUS_DEFAULT_SYSTEM AND HAVE_SD_BUS_CALL_METHOD AND HAVE_SD_BUS_MESSAGE_ENTER_CONTAINER AND HAVE_SD_BUS_MESSAGE_READ AND HAVE_SD_BUS_MESSAGE_EXIT_CONTAINER)
+ set(ENABLE_SYSTEMD_DBUS YES)
+ endif()
+ endif()
+endmacro()
diff --git a/packaging/cmake/Modules/NetdataFetchContentExtra.cmake b/packaging/cmake/Modules/NetdataFetchContentExtra.cmake
new file mode 100644
index 000000000..1de1dcef9
--- /dev/null
+++ b/packaging/cmake/Modules/NetdataFetchContentExtra.cmake
@@ -0,0 +1,27 @@
+# Extra tools for working with FetchContent on older CMake
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# FetchContent_MakeAvailable_NoInstall
+#
+# Add a sub-project with FetchContent, but with the EXCLUDE_FROM_ALL
+# argument for the add_subdirectory part.
+#
+# CMake 3.28 and newer provide a way to do this with an extra argument
+# on FetchContent_Declare, but older versions need you to implement
+# the logic yourself. Once we no longer support CMake versions older
+# than 3.28, we can get rid of this macro.
+#
+# Unlike FetchContent_MakeAvailble, this only accepts a single project
+# to make available.
+macro(FetchContent_MakeAvailable_NoInstall name)
+ include(FetchContent)
+
+ FetchContent_GetProperties(${name})
+
+ if(NOT ${name}_POPULATED)
+ FetchContent_Populate(${name})
+ add_subdirectory(${${name}_SOURCE_DIR} ${${name}_BINARY_DIR} EXCLUDE_FROM_ALL)
+ endif()
+endmacro()
diff --git a/packaging/cmake/Modules/NetdataGoTools.cmake b/packaging/cmake/Modules/NetdataGoTools.cmake
new file mode 100644
index 000000000..12785aeb5
--- /dev/null
+++ b/packaging/cmake/Modules/NetdataGoTools.cmake
@@ -0,0 +1,85 @@
+# Macros and functions to assist in working with Go
+#
+# Copyright (c) 2024 Netdata Inc
+#
+# SPDX-License-Identifier: GPL
+
+if(CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
+ set(GO_LDFLAGS "-X main.version=${NETDATA_VERSION}")
+else()
+ set(GO_LDFLAGS "-w -s -X main.version=${NETDATA_VERSION}")
+endif()
+
+# add_go_target: Add a new target that needs to be built using the Go toolchain.
+#
+# Takes four arguments, the target name, the output artifact name, the
+# source tree for the Go module, and the sub-directory of that source tree
+# to pass to `go build`.
+#
+# The target itself will invoke `go build` in the specified source tree,
+# using the `-o` option to produce the final output artifact, and passing
+# the requested sub-directory as the final argument.
+#
+# This will also automatically construct the dependency list for the
+# target by finding all Go source files under the specified source tree
+# and then appending the go.mod and go.sum files from the root of the
+# source tree.
+macro(add_go_target target output build_src build_dir)
+ file(GLOB_RECURSE ${target}_DEPS CONFIGURE_DEPENDS "${build_src}/*.go")
+ list(APPEND ${target}_DEPS
+ "${build_src}/go.mod"
+ "${build_src}/go.sum"
+ )
+
+ add_custom_command(
+ OUTPUT ${output}
+ COMMAND "${CMAKE_COMMAND}" -E env CGO_ENABLED=0 "${GO_EXECUTABLE}" build -buildvcs=false -ldflags "${GO_LDFLAGS}" -o "${CMAKE_BINARY_DIR}/${output}" "./${build_dir}"
+ DEPENDS ${${target}_DEPS}
+ COMMENT "Building Go component ${output}"
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/${build_src}"
+ VERBATIM
+ )
+ add_custom_target(
+ ${target} ALL
+ DEPENDS ${output}
+ )
+endmacro()
+
+# find_min_go_version: Determine the minimum Go version based on go.mod files
+#
+# Takes one argument, specifying a source tree to scan for go.mod files.
+#
+# All files found will be checked for a `go` directive, and the
+# MIN_GO_VERSION variable will be set to the highest version
+# number found among these directives.
+#
+# Only works on UNIX-like systems, because it has to process the go.mod
+# files in ways that CMake can't do on it's own.
+function(find_min_go_version src_tree)
+ message(STATUS "Determining minimum required version of Go for this build")
+
+ file(GLOB_RECURSE go_mod_files ${src_tree}/go.mod)
+
+ set(result 1.0)
+
+ foreach(f IN ITEMS ${go_mod_files})
+ message(VERBOSE "Checking Go version specified in ${f}")
+ execute_process(
+ COMMAND grep -E "^go .*$" ${f}
+ COMMAND cut -f 2 -d " "
+ RESULT_VARIABLE version_check_result
+ OUTPUT_VARIABLE go_mod_version
+ )
+
+ if(version_check_result EQUAL 0)
+ string(REGEX MATCH "([0-9]+\\.[0-9]+(\\.[0-9]+)?)" go_mod_version "${go_mod_version}")
+
+ if(go_mod_version VERSION_GREATER result)
+ set(result "${go_mod_version}")
+ endif()
+ endif()
+ endforeach()
+
+ message(STATUS "Minimum required Go version determined to be ${result}")
+ set(MIN_GO_VERSION "${result}" PARENT_SCOPE)
+endfunction()
diff --git a/packaging/cmake/Modules/NetdataProtobuf.cmake b/packaging/cmake/Modules/NetdataProtobuf.cmake
new file mode 100644
index 000000000..d4ae3aec6
--- /dev/null
+++ b/packaging/cmake/Modules/NetdataProtobuf.cmake
@@ -0,0 +1,225 @@
+# Macros and functions for handling of Protobuf
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+macro(netdata_protobuf_21_tags)
+ set(PROTOBUF_TAG f0dc78d7e6e331b8c6bb2d5283e06aa26883ca7c) # v21.12
+ set(NEED_ABSL False)
+endmacro()
+
+macro(netdata_protobuf_25_tags)
+ set(PROTOBUF_TAG 4a2aef570deb2bfb8927426558701e8bfc26f2a4) # v25.3
+ set(NEED_ABSL True)
+ set(ABSL_TAG 2f9e432cce407ce0ae50676696666f33a77d42ac) # 20240116.1
+endmacro()
+
+# Determine what version of protobuf and abseil to bundle.
+#
+# This is unfortunately very complicated because we support systems
+# older than what Google officially supports for C++.
+macro(netdata_set_bundled_protobuf_tags)
+ netdata_protobuf_21_tags()
+
+ if(NOT USE_CXX_11)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.3.1)
+ netdata_protobuf_25_tags()
+ endif()
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0.0)
+ netdata_protobuf_25_tags()
+ endif()
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL AppleClang)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
+ netdata_protobuf_25_tags()
+ endif()
+ endif()
+ endif()
+endmacro()
+
+# Prepare a vendored copy of Protobuf for use with Netdata.
+function(netdata_bundle_protobuf)
+ include(FetchContent)
+ include(NetdataFetchContentExtra)
+
+ netdata_set_bundled_protobuf_tags()
+
+ set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE NEVER)
+
+ string(REPLACE "-fsanitize=address" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
+ string(REPLACE "-fsanitize=address" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+
+ # ignore debhelper
+ set(FETCHCONTENT_FULLY_DISCONNECTED Off)
+
+ if(NEED_ABSL)
+ set(ABSL_PROPAGATE_CXX_STD On)
+ set(ABSL_ENABLE_INSTALL Off)
+
+ message(STATUS "Preparing bundled Abseil (required by bundled Protobuf)")
+ FetchContent_Declare(absl
+ GIT_REPOSITORY https://github.com/abseil/abseil-cpp
+ GIT_TAG ${ABSL_TAG}
+ )
+ FetchContent_MakeAvailable_NoInstall(absl)
+ message(STATUS "Finished preparing bundled Abseil")
+ endif()
+
+ set(protobuf_INSTALL Off)
+ set(protobuf_BUILD_LIBPROTOC Off)
+ set(protobuf_BUILD_TESTS Off)
+ set(protobuf_BUILD_SHARED_LIBS Off)
+
+ message(STATUS "Preparing bundled Protobuf")
+ FetchContent_Declare(protobuf
+ GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
+ GIT_TAG ${PROTOBUF_TAG}
+ )
+ FetchContent_MakeAvailable_NoInstall(protobuf)
+ message(STATUS "Finished preparing bundled Protobuf.")
+
+ set(BUNDLED_PROTOBUF True PARENT_SCOPE)
+endfunction()
+
+# Handle detection of Protobuf
+macro(netdata_detect_protobuf)
+ if(NOT ENABLE_BUNDLED_PROTOBUF)
+ if (NOT BUILD_SHARED_LIBS)
+ set(Protobuf_USE_STATIC_LIBS On)
+ endif()
+
+ # The FindProtobuf CMake module shipped by upstream CMake is
+ # broken for Protobuf version 22.0 and newer because it does
+ # not correctly pull in the new Abseil dependencies. Protobuf
+ # itself sometimes ships a CMake Package Configuration module
+ # that _does_ work correctly, so use that in preference to the
+ # Find module shipped with CMake.
+ #
+ # The code below works by first attempting to use find_package
+ # in config mode, and then checking for the existence of the
+ # target we actually use that gets defined by the protobuf
+ # CMake Package Configuration Module to determine if that
+ # worked. A bit of extra logic is required in the case of the
+ # config mode working, because some systems ship compatibility
+ # logic for the old FindProtobuf module while others do not.
+ #
+ # Upstream bug reference: https://gitlab.kitware.com/cmake/cmake/-/issues/24321
+ find_package(Protobuf CONFIG)
+
+ if(NOT TARGET protobuf::libprotobuf)
+ message(STATUS "Could not find Protobuf using Config mode, falling back to Module mode")
+ find_package(Protobuf REQUIRED)
+ endif()
+ endif()
+
+ if(TARGET protobuf::libprotobuf)
+ if(NOT Protobuf_PROTOC_EXECUTABLE AND TARGET protobuf::protoc)
+ get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
+ IMPORTED_LOCATION_RELEASE)
+ if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
+ get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
+ IMPORTED_LOCATION_RELWITHDEBINFO)
+ endif()
+ if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
+ get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
+ IMPORTED_LOCATION_MINSIZEREL)
+ endif()
+ if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
+ get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
+ IMPORTED_LOCATION_DEBUG)
+ endif()
+ if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
+ get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
+ IMPORTED_LOCATION_NOCONFIG)
+ endif()
+ if(NOT Protobuf_PROTOC_EXECUTABLE)
+ set(Protobuf_PROTOC_EXECUTABLE protobuf::protoc)
+ endif()
+ endif()
+
+ # It is technically possible that this may still not
+ # be set by this point, so we need to check it and
+ # fail noisily if it isn't because the build won't
+ # work without it.
+ if(NOT Protobuf_PROTOC_EXECUTABLE)
+ message(FATAL_ERROR "Could not determine the location of the protobuf compiler for the detected version of protobuf.")
+ endif()
+
+ set(NETDATA_PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
+ set(NETDATA_PROTOBUF_LIBS protobuf::libprotobuf)
+ get_target_property(NETDATA_PROTOBUF_CFLAGS_OTHER
+ protobuf::libprotobuf
+ INTERFACE_COMPILE_DEFINITIONS)
+ get_target_property(NETDATA_PROTOBUF_INCLUDE_DIRS
+ protobuf::libprotobuf
+ INTERFACE_INCLUDE_DIRECTORIES)
+
+ if(NETDATA_PROTOBUF_CFLAGS_OTHER STREQUAL NETDATA_PROTOBUF_CFLAGS_OTHER-NOTFOUND)
+ set(NETDATA_PROTOBUF_CFLAGS_OTHER "")
+ endif()
+
+ if(NETDATA_PROTOBUF_INCLUDE_DIRS STREQUAL NETDATA_PROTOBUF_INCLUDE_DIRS-NOTFOUND)
+ set(NETDATA_PROTOBUF_INCLUDE_DIRS "")
+ endif()
+ else()
+ set(NETDATA_PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE})
+ set(NETDATA_PROTOBUF_CFLAGS_OTHER ${PROTOBUF_CFLAGS_OTHER})
+ set(NETDATA_PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS})
+ set(NETDATA_PROTOBUF_LIBS ${PROTOBUF_LIBRARIES})
+ endif()
+
+ set(ENABLE_PROTOBUF True)
+ set(HAVE_PROTOBUF True)
+endmacro()
+
+# Helper function to compile protocol definitions into C++ code.
+function(netdata_protoc_generate_cpp INC_DIR OUT_DIR SRCS HDRS)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: protoc_generate_cpp() called without any proto files")
+ return()
+ endif()
+
+ set(${INC_DIR})
+ set(${OUT_DIR})
+ set(${SRCS})
+ set(${HDRS})
+
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(DIR ${ABS_FIL} DIRECTORY)
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+
+ set(GENERATED_PB_CC "${DIR}/${FIL_WE}.pb.cc")
+ list(APPEND ${SRCS} ${GENERATED_PB_CC})
+
+ set(GENERATED_PB_H "${DIR}/${FIL_WE}.pb.h")
+ list(APPEND ${HDRS} ${GENERATED_PB_H})
+
+ list(APPEND _PROTOC_INCLUDE_DIRS ${INC_DIR})
+
+ if(ENABLE_BUNDLED_PROTOBUF)
+ list(APPEND _PROTOC_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/_deps/protobuf-src/src/)
+ endif()
+
+ add_custom_command(OUTPUT ${GENERATED_PB_CC} ${GENERATED_PB_H}
+ COMMAND ${NETDATA_PROTOBUF_PROTOC_EXECUTABLE}
+ ARGS "-I$<JOIN:${_PROTOC_INCLUDE_DIRS},;-I>" --cpp_out=${OUT_DIR} ${ABS_FIL}
+ DEPENDS ${ABS_FIL} ${NETDATA_PROTOBUF_PROTOC_EXECUTABLE}
+ COMMENT "Running C++ protocol buffer compiler on ${FIL}"
+ COMMAND_EXPAND_LISTS)
+ endforeach()
+
+ set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
+ set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES COMPILE_OPTIONS -Wno-deprecated-declarations)
+
+ set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+ set(${HDRS} ${${HDRS}} PARENT_SCOPE)
+endfunction()
+
+# Add protobuf to a specified target.
+function(netdata_add_protobuf _target)
+ target_compile_definitions(${_target} PRIVATE ${NETDATA_PROTOBUF_CFLAGS_OTHER})
+ target_include_directories(${_target} PRIVATE ${NETDATA_PROTOBUF_INCLUDE_DIRS})
+ target_link_libraries(${_target} PRIVATE ${NETDATA_PROTOBUF_LIBS})
+endfunction()
diff --git a/packaging/cmake/Modules/NetdataYAML.cmake b/packaging/cmake/Modules/NetdataYAML.cmake
new file mode 100644
index 000000000..73af55167
--- /dev/null
+++ b/packaging/cmake/Modules/NetdataYAML.cmake
@@ -0,0 +1,65 @@
+# Functions and macros for handling of libYAML
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Handle bundling of libyaml.
+#
+# 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_libyaml)
+ include(FetchContent)
+ include(NetdataFetchContentExtra)
+
+ if(ENABLE_BUNDLED_LIBYAML)
+ set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE NEVER)
+ endif()
+
+ set(FETCHCONTENT_FULLY_DISCONNECTED Off)
+
+ FetchContent_Declare(yaml
+ GIT_REPOSITORY https://github.com/yaml/libyaml
+ GIT_TAG 2c891fc7a770e8ba2fec34fc6b545c672beb37e6 # v0.2.5
+ )
+
+ FetchContent_MakeAvailable_NoInstall(yaml)
+endfunction()
+
+# Handle setup of libyaml for the build.
+#
+# This will attempt to find libyaml 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 libyaml is to be included, library names,
+# include directories, and compile definitions will be specified in the
+# NETDATA_YAML_* variables for later use.
+macro(netdata_detect_libyaml)
+ set(HAVE_LIBYAML True)
+
+ pkg_check_modules(YAML yaml-0.1)
+
+ if(ENABLE_BUNDLED_LIBYAML OR NOT YAML_FOUND)
+ netdata_bundle_libyaml()
+ set(NETDATA_YAML_LDFLAGS yaml)
+ get_target_property(NETDATA_YAML_INCLUDE_DIRS yaml INTERFACE_INCLUDE_DIRECTORIES)
+ get_target_property(NETDATA_YAML_CFLAGS_OTHER yaml INTERFACE_COMPILE_DEFINITIONS)
+ else()
+ set(NETDATA_YAML_LDFLAGS ${YAML_LDFLAGS})
+ set(NETDATA_YAML_CFLAGS_OTHER ${YAML_CFLAGS_OTHER})
+ set(NETDATA_YAML_INCLUDE_DIRS ${YAML_INCLUDE_DIRS})
+ endif()
+endmacro()
+
+# Add libyaml as a public link dependency of the specified target.
+#
+# The specified target must already exist, and the netdata_detect_libyaml
+# macro must have already been run at least once for this to work correctly.
+function(netdata_add_libyaml_to_target _target)
+ target_include_directories(${_target} PUBLIC ${NETDATA_YAML_INCLUDE_DIRS})
+ target_compile_definitions(${_target} PUBLIC ${NETDATA_YAML_CFLAGS_OTHER})
+ target_link_libraries(${_target} PUBLIC ${NETDATA_YAML_LDFLAGS})
+endfunction()