0
0
mirror of https://github.com/netdata/netdata.git synced 2024-11-21 15:28:05 +00:00
netdata_netdata/packaging/cmake/Modules/NetdataProtobuf.cmake
Austin S. Hemmelgarn 3025ffe80b
Bump CMake supported versions. (#18102)
* Properly support CMake 3.30.

As of CMake 3.30, calling `FetchContent_Populate` is officially
deprecated, and you get a warning about eventual removal.

We end up calling this function to compensate for the fact that CMake
prior to 3.28 provides no other way to make an external project managed
through FetchContent available without adding it to the `all` target and
thus installing the files from it, which we need to avoid doing for our
vendored libraries.

This changes things to check for CMake 3.28 or newer, and use the
preferred method on those systems. Unfortunately, this is handled in a
different place than the old workaround needed it to be handled in, so
we need checks in multiple places to make this work.

* Bump supported CMake versions to 3.16-3.30.

The last system we supported that shipped 3.13 was Debian 10, which we
no longer support, and 3.30 is the latest version.
2024-07-15 10:52:28 -04:00

200 lines
8.8 KiB
CMake

# Macros and functions for handling of Protobuf
#
# Copyright (c) 2024 Netdata Inc.
# SPDX-License-Identifier: GPL-3.0-or-later
# Prepare a vendored copy of Protobuf for use with Netdata.
function(netdata_bundle_protobuf)
include(FetchContent)
include(NetdataFetchContentExtra)
set(PROTOBUF_TAG f0dc78d7e6e331b8c6bb2d5283e06aa26883ca7c) # v21.12
set(NEED_ABSL False)
if(CMAKE_CXX_STANDARD GREATER_EQUAL 14)
set(PROTOBUF_TAG 4a2aef570deb2bfb8927426558701e8bfc26f2a4) # v25.3
set(NEED_ABSL True)
set(ABSL_TAG 2f9e432cce407ce0ae50676696666f33a77d42ac) # 20240116.1
endif()
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)
set(BUILD_SHARED_LIBS Off)
set(absl_repo https://github.com/abseil/abseil-cpp)
message(STATUS "Preparing bundled Abseil (required by bundled Protobuf)")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28)
FetchContent_Declare(absl
GIT_REPOSITORY ${absl_repo}
GIT_TAG ${ABSL_TAG}
CMAKE_ARGS ${NETDATA_CMAKE_PROPAGATE_TOOLCHAIN_ARGS}
EXCLUDE_FROM_ALL
)
else()
FetchContent_Declare(absl
GIT_REPOSITORY ${absl_repo}
GIT_TAG ${ABSL_TAG}
CMAKE_ARGS ${NETDATA_CMAKE_PROPAGATE_TOOLCHAIN_ARGS}
)
endif()
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)
set(protobuf_repo https://github.com/protocolbuffers/protobuf)
message(STATUS "Preparing bundled Protobuf")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28)
FetchContent_Declare(protobuf
GIT_REPOSITORY ${protobuf_repo}
GIT_TAG ${PROTOBUF_TAG}
CMAKE_ARGS ${NETDATA_CMAKE_PROPAGATE_TOOLCHAIN_ARGS}
EXCLUDE_FROM_ALL
)
else()
FetchContent_Declare(protobuf
GIT_REPOSITORY ${protobuf_repo}
GIT_TAG ${PROTOBUF_TAG}
CMAKE_ARGS ${NETDATA_CMAKE_PROPAGATE_TOOLCHAIN_ARGS}
)
endif()
FetchContent_MakeAvailable_NoInstall(protobuf)
message(STATUS "Finished preparing bundled Protobuf.")
set(ENABLE_BUNDLED_PROTOBUF True PARENT_SCOPE)
endfunction()
# Handle detection of Protobuf
macro(netdata_detect_protobuf)
if(OS_WINDOWS)
set(PROTOBUF_PROTOC_EXECUTABLE "$ENV{PROTOBUF_PROTOC_EXECUTABLE}")
if(NOT PROTOBUF_PROTOC_EXECUTABLE)
set(PROTOBUF_PROTOC_EXECUTABLE "/bin/protoc")
endif()
set(PROTOBUF_CFLAGS_OTHER "")
set(PROTOBUF_INCLUDE_DIRS "")
set(PROTOBUF_LIBRARIES "-lprotobuf")
set(ENABLE_PROTOBUF True)
set(HAVE_PROTOBUF True)
else()
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)
set(Protobuf_PROTOC_EXECUTABLE protobuf::protoc)
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(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
set(PROTOBUF_LIBRARIES protobuf::libprotobuf)
endif()
set(ENABLE_PROTOBUF True)
set(HAVE_PROTOBUF True)
endif()
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 ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS "-I$<JOIN:${_PROTOC_INCLUDE_DIRS},;-I>" --cpp_out=${OUT_DIR} ${ABS_FIL}
DEPENDS ${ABS_FIL} ${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)
if(ENABLE_BUNDLED_PROTOBUF)
target_include_directories(${_target} BEFORE PRIVATE ${PROTOBUF_INCLUDE_DIRS})
else()
target_include_directories(${_target} PRIVATE ${PROTOBUF_INCLUDE_DIRS})
endif()
target_compile_options(${_target} PRIVATE ${PROTOBUF_CFLAGS_OTHER})
target_link_libraries(${_target} PRIVATE ${PROTOBUF_LIBRARIES})
endfunction()