diff --git a/CMakeLists.txt b/CMakeLists.txt index 9290be531ac8cc..4f4ea75ca5d0c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ project(netdata HOMEPAGE_URL "https://www.netdata.cloud" LANGUAGES C CXX) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/packaging/cmake/Modules") +include(CMakeDependentOption) find_package(PkgConfig REQUIRED) @@ -122,6 +123,8 @@ option(ENABLE_EXPORTER_MONGODB "enable mongodb exporter" True) option(ENABLE_BUNDLED_JSONC "enable bundled json-c" False) option(ENABLE_BUNDLED_YAML "enable bundled yaml" False) option(ENABLE_BUNDLED_PROTOBUF "enable bundled protobuf" False) +cmake_dependent_option(ENABLE_BUNDLED_ABSEIL "enable bundled abseil" OFF + "NOT ENABLE_BUNDLED_PROTOBUF" ON) option(ENABLE_LOGS_MANAGEMENT_TESTS "enable logs management tests" True) diff --git a/packaging/cmake/Modules/NetdataAbseil.cmake b/packaging/cmake/Modules/NetdataAbseil.cmake new file mode 100644 index 00000000000000..52043dda741cb1 --- /dev/null +++ b/packaging/cmake/Modules/NetdataAbseil.cmake @@ -0,0 +1,126 @@ +# Macros and functions for handling of Abseil +# +# To use: +# - Include the NetdataAbseil module +# - Call netdata_detect_abseil() with a list of the Abseil components you need. +# - Call netdata_add_abseil_to_target() with the name of the target that needs to link against Abseil. +# +# Copyright (c) 2024 Netdata Inc. +# SPDX-License-Identifier: GPL-3.0-or-later + +# Prepare a vendored copy of Abseil for use with Netdata +function(netdata_bundle_abseil) + include(FetchContent) + include(NetdataFetchContentExtra) + + 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) + + set(ABSL_PROPAGATE_CXX_STD On) + set(ABSL_ENABLE_INSTALL Off) + + message(STATUS "Preparing bundled Abseil") + FetchContent_Declare(absl + GIT_REPOSITORY https://github.com/abseil/abseil-cpp + GIT_TAG 2f9e432cce407ce0ae50676696666f33a77d42ac # 20240116.1 + ) + FetchContent_MakeAvailable_NoInstall(absl) + message(STATUS "Finished preparing bundled Abseil") + set(BUNDLED_ABSEIL PARENT_SCOPE) +endfunction() + +# Look for a system copy of Abseil, and if we can’t find it bundle a copy. +# +# _components is a list of Abseil component libraries to look for, +# without the `absl_` prefix. All of them must be found to use a system copy. +# +# If called multiple times with different lists of components, the +# end result will be as if it was called once with the union of the sets +# of components. +function(netdata_detect_abseil _components) + set(_components_found "${ENABLE_BUNDLED_ABSEIL}") + set(_cflags_other "${NETDATA_ABSEIL_CFLAGS_OTHER}") + set(_include_dirs "${NETDATA_ABSEIL_INCLUDE_DIRS}") + set(_libs "${NETDATA_ABSEIL_LIBS}") + set(_bundled "${BUNDLED_ABSEIL}") + + if(NOT BUNDLED_ABSEIL) + if(NOT ENABLE_BUNDLED_ABSEIL) + foreach(_c LISTS _components) + set(_component_name "absl_${_c}") + pkg_check_modules("${_component_name}") + + if(${_component_name}_FOUND) + list(APPEND _cflags_other "${${_component_name}_CFLAGS_OTHER}") + list(APPEND _include_dirs "${${_component_name}_INCLUDE_DIRS}") + list(APPEND _libs "${${_component_name}_LIBRARIES}") + else() + set(_components_found FALSE) + break() + endif() + endforeach() + endif() + + if(NOT _components_found) + set(_cflags_other "${NETDATA_ABSEIL_CFLAGS_OTHER}") + set(_include_dirs "${NETDATA_ABSEIL_INCLUDE_DIRS}") + set(_libs "${NETDATA_ABSEIL_LIBS}") + set(_bundled TRUE) + message(WARNING "Could not find all required Abseil components, vendoring it instead") + netdata_bundle_abseil() + endif() + endif() + + if(BUNDLED_ABSEIL) + foreach(_c LISTS _components) + set(_target "absl::${_c}") + + if(NOT TARGET ${_target}) + message(FATAL_ERROR "Abseil component ${_c} was not provided by the vendored copy of Abseil.") + endif() + + get_target_property(${_c}_cflags_other ${_target} INTERFACE_COMPILE_DEFINITIONS) + + if(NOT ${_c}_cflags_other STREQUAL ${_c}_cflags_other-NOTFOUND) + list(APPEND _cflags_other "${${_c}_cflags_other}") + endif() + + get_target_property(${_c}_include_dirs ${_target} INTERFACE_INCLUDE_DIRECTORIES) + + if(NOT ${_c}_include_dirs STREQUAL ${_c}_include_dirs-NOTFOUND) + list(APPEND _include_dirs "${${_c}_include_dirs}") + endif() + + list(APPEND _libs ${_target}) + endforeach() + endif() + + foreach(_var ITEMS _cflags_other _include_dirs _libs) + list(REMOVE_ITEM ${_var} "") + list(REMOVE_DUPLICATES ${_var}) + endforeach() + + set(NETDATA_ABSEIL_CFLAGS_OTHER "${_cflags_other}" PARENT_SCOPE) + set(NETDATA_ABSEIL_INCLUDE_DIRS "${_include_dirs}" PARENT_SCOPE) + set(NETDATA_ABSEIL_LIBS "${_libs}" PARENT_SCOPE) + set(HAVE_ABSEIL TRUE PARENT_SCOPE) + set(BUNDLED_ABSEIL "${_bundled}" PARENT_SCOPE) +endfunction() + +# Add Abseil to a specified target +# +# The _scope argument is optional, if not specified Abseil will be added as a PRIVATE dependency. +function(netdata_add_abseil_to_target _target _scope) + if(NOT _scope) + set(_scope PRIVATE) + endif() + + target_compile_definitions(${_target} ${_scope} ${NETDATA_ABSEIL_CFLAGS_OTHER}) + target_include_directories(${_target} ${_scope} ${NETDATA_ABSEIL_INCLUDE_DIRS}) + target_link_libraries(${_target} ${_scope} ${NETDATA_ABSEIL_LIBS}) +endfunction() diff --git a/packaging/cmake/Modules/NetdataProtobuf.cmake b/packaging/cmake/Modules/NetdataProtobuf.cmake index d4ae3aec610291..0ec43cfee7171f 100644 --- a/packaging/cmake/Modules/NetdataProtobuf.cmake +++ b/packaging/cmake/Modules/NetdataProtobuf.cmake @@ -3,6 +3,8 @@ # Copyright (c) 2024 Netdata Inc. # SPDX-License-Identifier: GPL-3.0-or-later +include(NetdataAbseil) + macro(netdata_protobuf_21_tags) set(PROTOBUF_TAG f0dc78d7e6e331b8c6bb2d5283e06aa26883ca7c) # v21.12 set(NEED_ABSL False) @@ -11,7 +13,6 @@ 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. @@ -54,16 +55,12 @@ function(netdata_bundle_protobuf) 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") + if(HAVE_ABSEIL AND NOT BUNDLED_ABSEIL) + message(FATAL_ERROR "Using a system copy of Abseil is not supported if vendoring Protobuf") + endif() + + netdata_bundle_abseil() + set(BUNDLED_ABSEIL PARENT_SCOPE) endif() set(protobuf_INSTALL Off)