# Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 # # The dependency on opentelemetry-proto can be provided by order # of decreasing priority, options are: # # 1 - Fetch from local source directory defined by the OTELCPP_PROTO_PATH variable # # 2 - Fetch from the opentelemetry-proto git submodule (opentelemetry-cpp/third_party/opentelemetry-proto) # # 3 - Fetch from github using the git tag set in opentelemetry-cpp/third_party_release # set(OPENTELEMETRY_PROTO_SUBMODULE "${opentelemetry-cpp_SOURCE_DIR}/third_party/opentelemetry-proto") if(OTELCPP_PROTO_PATH) if(NOT EXISTS "${OTELCPP_PROTO_PATH}/opentelemetry/proto/common/v1/common.proto") message( FATAL_ERROR "OTELCPP_PROTO_PATH does not point to a opentelemetry-proto repository") endif() message(STATUS "fetching opentelemetry-proto from OTELCPP_PROTO_PATH=${OTELCPP_PROTO_PATH}") FetchContent_Declare( opentelemetry-proto SOURCE_DIR ${OTELCPP_PROTO_PATH} ) set(opentelemetry-proto_PROVIDER "fetch_source") # If the opentelemetry-proto directory is a general directory then we don't have a good way to determine the version. Set it as unknown. set(opentelemetry-proto_VERSION "unknown") elseif(EXISTS ${OPENTELEMETRY_PROTO_SUBMODULE}/.git) message(STATUS "fetching opentelemetry-proto from git submodule") FetchContent_Declare( opentelemetry-proto SOURCE_DIR ${OPENTELEMETRY_PROTO_SUBMODULE} ) set(opentelemetry-proto_PROVIDER "fetch_source") string(REGEX REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" "\\1" opentelemetry-proto_VERSION "${opentelemetry-proto_GIT_TAG}") else() FetchContent_Declare( opentelemetry-proto GIT_REPOSITORY https://github.com/open-telemetry/opentelemetry-proto.git GIT_TAG "${opentelemetry-proto_GIT_TAG}") set(opentelemetry-proto_PROVIDER "fetch_repository") string(REGEX REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" "\\1" opentelemetry-proto_VERSION "${opentelemetry-proto_GIT_TAG}") endif() FetchContent_MakeAvailable(opentelemetry-proto) set(PROTO_PATH "${opentelemetry-proto_SOURCE_DIR}") set(COMMON_PROTO "${PROTO_PATH}/opentelemetry/proto/common/v1/common.proto") set(RESOURCE_PROTO "${PROTO_PATH}/opentelemetry/proto/resource/v1/resource.proto") set(TRACE_PROTO "${PROTO_PATH}/opentelemetry/proto/trace/v1/trace.proto") set(LOGS_PROTO "${PROTO_PATH}/opentelemetry/proto/logs/v1/logs.proto") set(METRICS_PROTO "${PROTO_PATH}/opentelemetry/proto/metrics/v1/metrics.proto") set(PROFILES_PROTO "${PROTO_PATH}/opentelemetry/proto/profiles/v1development/profiles.proto") set(TRACE_SERVICE_PROTO "${PROTO_PATH}/opentelemetry/proto/collector/trace/v1/trace_service.proto") set(LOGS_SERVICE_PROTO "${PROTO_PATH}/opentelemetry/proto/collector/logs/v1/logs_service.proto") set(METRICS_SERVICE_PROTO "${PROTO_PATH}/opentelemetry/proto/collector/metrics/v1/metrics_service.proto" ) set(PROFILES_SERVICE_PROTO "${PROTO_PATH}/opentelemetry/proto/collector/profiles/v1development/profiles_service.proto" ) set(GENERATED_PROTOBUF_PATH "${CMAKE_BINARY_DIR}/generated/third_party/opentelemetry-proto") file(MAKE_DIRECTORY "${GENERATED_PROTOBUF_PATH}") set(COMMON_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/common/v1/common.pb.cc") set(COMMON_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/common/v1/common.pb.h") set(RESOURCE_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/resource/v1/resource.pb.cc") set(RESOURCE_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/resource/v1/resource.pb.h") set(TRACE_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/trace/v1/trace.pb.cc") set(TRACE_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/trace/v1/trace.pb.h") set(LOGS_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/logs/v1/logs.pb.cc") set(LOGS_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/logs/v1/logs.pb.h") set(METRICS_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/metrics/v1/metrics.pb.cc") set(METRICS_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/metrics/v1/metrics.pb.h") set(TRACE_SERVICE_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/trace/v1/trace_service.pb.cc" ) set(TRACE_SERVICE_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/trace/v1/trace_service.pb.h" ) # # Notes about the PROFILES signal: - *.proto files added in opentelemetry-proto # 1.3.0 - C++ code is generated from proto files - The generated code is not # used yet. # set(PROFILES_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/profiles/v1development/profiles.pb.cc" ) set(PROFILES_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/profiles/v1development/profiles.pb.h" ) set(PROFILES_SERVICE_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/profiles/v1development/profiles_service.pb.h" ) set(PROFILES_SERVICE_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/profiles/v1development/profiles_service.pb.cc" ) if(WITH_OTLP_GRPC) set(PROFILES_SERVICE_GRPC_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/profiles/v1development/profiles_service.grpc.pb.h" ) set(PROFILES_SERVICE_GRPC_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/profiles/v1development/profiles_service.grpc.pb.cc" ) endif() if(WITH_OTLP_GRPC) set(TRACE_SERVICE_GRPC_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/trace/v1/trace_service.grpc.pb.cc" ) set(TRACE_SERVICE_GRPC_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/trace/v1/trace_service.grpc.pb.h" ) endif() set(LOGS_SERVICE_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/logs/v1/logs_service.pb.cc" ) set(LOGS_SERVICE_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/logs/v1/logs_service.pb.h" ) if(WITH_OTLP_GRPC) set(LOGS_SERVICE_GRPC_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/logs/v1/logs_service.grpc.pb.cc" ) set(LOGS_SERVICE_GRPC_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/logs/v1/logs_service.grpc.pb.h" ) endif() set(METRICS_SERVICE_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/metrics/v1/metrics_service.pb.cc" ) set(METRICS_SERVICE_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/metrics/v1/metrics_service.pb.h" ) if(WITH_OTLP_GRPC) set(METRICS_SERVICE_GRPC_PB_CPP_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.cc" ) set(METRICS_SERVICE_GRPC_PB_H_FILE "${GENERATED_PROTOBUF_PATH}/opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.h" ) endif() foreach(IMPORT_DIR ${PROTOBUF_IMPORT_DIRS}) list(APPEND PROTOBUF_INCLUDE_FLAGS "-I${IMPORT_DIR}") endforeach() set(PROTOBUF_COMMON_FLAGS "--proto_path=${PROTO_PATH}" "--cpp_out=dllexport_decl=OPENTELEMETRY_PROTO_API:${GENERATED_PROTOBUF_PATH}" ) # --experimental_allow_proto3_optional is available from 3.13 and be stable and # enabled by default from 3.16 if(Protobuf_VERSION AND Protobuf_VERSION VERSION_LESS "3.16") list(APPEND PROTOBUF_COMMON_FLAGS "--experimental_allow_proto3_optional") elseif(PROTOBUF_VERSION AND PROTOBUF_VERSION VERSION_LESS "3.16") list(APPEND PROTOBUF_COMMON_FLAGS "--experimental_allow_proto3_optional") endif() # protobuf uses numerous global variables, which can lead to conflicts when a # user's dynamic libraries, executables, and otel-cpp are all built as dynamic # libraries and linked against a statically built protobuf library. This may # result in crashes. To prevent such conflicts, we also need to build # opentelemetry_exporter_otlp_grpc_client as a static library. if(TARGET protobuf::libprotobuf) get_target_property(protobuf_lib_type protobuf::libprotobuf TYPE) else() set(protobuf_lib_type "SHARED_LIBRARY") target_link_libraries(opentelemetry_proto PUBLIC ${Protobuf_LIBRARIES}) foreach(protobuf_lib_file ${Protobuf_LIBRARIES}) if(protobuf_lib_file MATCHES "(^|[\\\\\\/])[^\\\\\\/]*protobuf[^\\\\\\/]*\\.(a|lib)$") set(protobuf_lib_type "STATIC_LIBRARY") break() endif() endforeach() endif() set(PROTOBUF_GENERATED_FILES ${COMMON_PB_H_FILE} ${COMMON_PB_CPP_FILE} ${RESOURCE_PB_H_FILE} ${RESOURCE_PB_CPP_FILE} ${TRACE_PB_H_FILE} ${TRACE_PB_CPP_FILE} ${LOGS_PB_H_FILE} ${LOGS_PB_CPP_FILE} ${METRICS_PB_H_FILE} ${METRICS_PB_CPP_FILE} ${PROFILES_H_FILE} ${PROFILES_CPP_FILE} ${TRACE_SERVICE_PB_H_FILE} ${TRACE_SERVICE_PB_CPP_FILE} ${LOGS_SERVICE_PB_H_FILE} ${LOGS_SERVICE_PB_CPP_FILE} ${METRICS_SERVICE_PB_H_FILE} ${METRICS_SERVICE_PB_CPP_FILE} ${PROFILES_SERVICE_PB_H_FILE} ${PROFILES_SERVICE_PB_CPP_FILE}) set(PROTOBUF_GENERATE_DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE}) if(WITH_OTLP_GRPC) list(APPEND PROTOBUF_GENERATE_DEPENDS ${gRPC_CPP_PLUGIN_EXECUTABLE}) list(APPEND PROTOBUF_COMMON_FLAGS "--grpc_out=generate_mock_code=true:${GENERATED_PROTOBUF_PATH}" --plugin=protoc-gen-grpc="${gRPC_CPP_PLUGIN_EXECUTABLE}") list( APPEND PROTOBUF_GENERATED_FILES ${TRACE_SERVICE_GRPC_PB_H_FILE} ${TRACE_SERVICE_GRPC_PB_CPP_FILE} ${LOGS_SERVICE_GRPC_PB_H_FILE} ${LOGS_SERVICE_GRPC_PB_CPP_FILE} ${METRICS_SERVICE_GRPC_PB_H_FILE} ${METRICS_SERVICE_GRPC_PB_CPP_FILE} ${PROFILES_SERVICE_GRPC_PB_H_FILE} ${PROFILES_SERVICE_GRPC_PB_CPP_FILE}) endif() set(PROTOBUF_RUN_PROTOC_COMMAND "\"${PROTOBUF_PROTOC_EXECUTABLE}\"") foreach( PROTOBUF_RUN_PROTOC_ARG ${PROTOBUF_COMMON_FLAGS} ${PROTOBUF_INCLUDE_FLAGS} ${COMMON_PROTO} ${RESOURCE_PROTO} ${TRACE_PROTO} ${LOGS_PROTO} ${METRICS_PROTO} ${PROFILES_PROTO} ${TRACE_SERVICE_PROTO} ${LOGS_SERVICE_PROTO} ${METRICS_SERVICE_PROTO} ${PROFILES_SERVICE_PROTO}) set(PROTOBUF_RUN_PROTOC_COMMAND "${PROTOBUF_RUN_PROTOC_COMMAND} \"${PROTOBUF_RUN_PROTOC_ARG}\"") endforeach() add_custom_command( OUTPUT ${PROTOBUF_GENERATED_FILES} COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTOBUF_COMMON_FLAGS} ${PROTOBUF_INCLUDE_FLAGS} ${COMMON_PROTO} ${RESOURCE_PROTO} ${TRACE_PROTO} ${LOGS_PROTO} ${METRICS_PROTO} ${TRACE_SERVICE_PROTO} ${LOGS_SERVICE_PROTO} ${METRICS_SERVICE_PROTO} ${PROFILES_PROTO} ${PROFILES_SERVICE_PROTO} COMMENT "[Run]: ${PROTOBUF_RUN_PROTOC_COMMAND}" DEPENDS ${PROTOBUF_GENERATE_DEPENDS}) unset(OTELCPP_PROTO_TARGET_OPTIONS) if((NOT protobuf_lib_type STREQUAL "STATIC_LIBRARY") AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)) list(APPEND OTELCPP_PROTO_TARGET_OPTIONS SHARED) set(OTELCPP_PROTO_LIB_TYPE "SHARED_LIBRARY") else() list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC) set(OTELCPP_PROTO_LIB_TYPE "STATIC_LIBRARY") endif() set(OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto) add_library( opentelemetry_proto ${OTELCPP_PROTO_TARGET_OPTIONS} ${COMMON_PB_CPP_FILE} ${RESOURCE_PB_CPP_FILE} ${TRACE_PB_CPP_FILE} ${LOGS_PB_CPP_FILE} ${METRICS_PB_CPP_FILE} ${TRACE_SERVICE_PB_CPP_FILE} ${LOGS_SERVICE_PB_CPP_FILE} ${METRICS_SERVICE_PB_CPP_FILE}) set_target_version(opentelemetry_proto) if(OTELCPP_PROTO_LIB_TYPE STREQUAL "SHARED_LIBRARY") project_build_tools_set_shared_library_declaration(OPENTELEMETRY_PROTO_API opentelemetry_proto) else() project_build_tools_set_static_library_declaration(OPENTELEMETRY_PROTO_API opentelemetry_proto) endif() target_include_directories( opentelemetry_proto PUBLIC "$" "$") # Disable include-what-you-use and clang-tidy on generated code. set_target_properties( opentelemetry_proto PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" CXX_CLANG_TIDY "" C_VISIBILITY_PRESET "hidden" CXX_VISIBILITY_PRESET "hidden" VISIBILITY_INLINES_HIDDEN OFF) if(NOT Protobuf_INCLUDE_DIRS AND TARGET protobuf::libprotobuf) get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) endif() if(Protobuf_INCLUDE_DIRS) target_include_directories( opentelemetry_proto BEFORE PUBLIC "$") endif() if(WITH_OTLP_GRPC) add_library( opentelemetry_proto_grpc ${OTELCPP_PROTO_TARGET_OPTIONS} ${TRACE_SERVICE_GRPC_PB_CPP_FILE} ${LOGS_SERVICE_GRPC_PB_CPP_FILE} ${METRICS_SERVICE_GRPC_PB_CPP_FILE}) set_target_version(opentelemetry_proto_grpc) if(OTELCPP_PROTO_LIB_TYPE STREQUAL "SHARED_LIBRARY") if(CMAKE_SYSTEM_NAME MATCHES "Windows|MinGW|WindowsStore") # The codes generated by gRPC plugin do not support dll export/import # declarations. To work around this, we enable WINDOWS_EXPORT_ALL_SYMBOLS # property to export all symbols when building a shared library. # TODO: This can be removed once gRPC plugin supports dll export/import. set_target_properties(opentelemetry_proto_grpc PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() endif() # Disable include-what-you-use and clang-tidy on generated code. # The codes generated by gRPC plugin do not support symbol visibility # declarations for public APIs. To work around this, we set visibility # to default and disable hidden inline visibility. Otherwise, building # a shared library will fail when user changes the default visibility # to hidden (e.g., via -fvisibility=hidden compiler flag). # TODO: C_VISIBILITY_PRESET, CXX_VISIBILITY_PRESET, and # VISIBILITY_INLINES_HIDDEN can be removed once gRPC plugin supports symbol # visibility declarations. set_target_properties( opentelemetry_proto_grpc PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" CXX_CLANG_TIDY "" C_VISIBILITY_PRESET "default" CXX_VISIBILITY_PRESET "default" VISIBILITY_INLINES_HIDDEN OFF) list(APPEND OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto_grpc) target_link_libraries(opentelemetry_proto_grpc PUBLIC opentelemetry_proto) # gRPC uses numerous global variables, which can lead to conflicts when a # user's dynamic libraries, executables, and otel-cpp are all built as dynamic # libraries and linked against a statically built gRPC library. This may # result in crashes. To prevent such conflicts, we also need to build # opentelemetry_exporter_otlp_grpc_client as a static library. get_target_property(grpc_lib_type gRPC::grpc++ TYPE) if(grpc_lib_type STREQUAL "SHARED_LIBRARY" OR OTELCPP_PROTO_LIB_TYPE STREQUAL "SHARED_LIBRARY") target_link_libraries(opentelemetry_proto_grpc PUBLIC gRPC::grpc++) endif() set_target_properties(opentelemetry_proto_grpc PROPERTIES EXPORT_NAME proto_grpc) patch_protobuf_targets(opentelemetry_proto_grpc) get_target_property(GRPC_INCLUDE_DIRECTORY gRPC::grpc++ INTERFACE_INCLUDE_DIRECTORIES) if(GRPC_INCLUDE_DIRECTORY) target_include_directories( opentelemetry_proto_grpc BEFORE PUBLIC "$") endif() endif() set_target_properties(opentelemetry_proto PROPERTIES EXPORT_NAME proto) patch_protobuf_targets(opentelemetry_proto) if(OPENTELEMETRY_INSTALL) install( DIRECTORY ${GENERATED_PROTOBUF_PATH}/opentelemetry DESTINATION include COMPONENT exporters_otlp_common FILES_MATCHING PATTERN "*.h") endif() if(TARGET protobuf::libprotobuf) target_link_libraries(opentelemetry_proto PUBLIC protobuf::libprotobuf) else() # cmake 3.8 or lower target_link_libraries(opentelemetry_proto PUBLIC ${Protobuf_LIBRARIES}) endif() # this is needed on some older grcp versions specifically conan recipe for # grpc/1.54.3 if(WITH_OTLP_GRPC) if(TARGET absl::synchronization) target_link_libraries(opentelemetry_proto_grpc PUBLIC "$") endif() endif() if(BUILD_SHARED_LIBS) foreach(proto_target ${OPENTELEMETRY_PROTO_TARGETS}) set_property(TARGET ${proto_target} PROPERTY POSITION_INDEPENDENT_CODE ON) endforeach() endif()