diff --git a/.github/workflows/cmake_install.yml b/.github/workflows/cmake_install.yml index 8b572de1c8..edd3db7713 100644 --- a/.github/workflows/cmake_install.yml +++ b/.github/workflows/cmake_install.yml @@ -178,7 +178,7 @@ jobs: run: ./ci/do_ci.sh cmake.install.test ubuntu_2404_conan_stable: - name: Ubuntu 24.04 conan stable versions cxx17 (static libs - shared libs - opentracing shim) + name: Ubuntu 24.04 conan stable versions cxx17 (static libs - opentracing shim) runs-on: ubuntu-24.04 env: INSTALL_TEST_DIR: '/home/runner/install_test' @@ -207,10 +207,6 @@ jobs: env: BUILD_SHARED_LIBS: 'OFF' run: ./ci/do_ci.sh cmake.install.test - - name: Run Tests (shared libs) - env: - BUILD_SHARED_LIBS: 'ON' - run: ./ci/do_ci.sh cmake.install.test - name: verify pkgconfig packages run: | export PKG_CONFIG_PATH=$INSTALL_TEST_DIR/lib/pkgconfig:$PKG_CONFIG_PATH diff --git a/cmake/opentelemetry-proto.cmake b/cmake/opentelemetry-proto.cmake index 8a04fedee4..e42e1a7965 100644 --- a/cmake/opentelemetry-proto.cmake +++ b/cmake/opentelemetry-proto.cmake @@ -221,6 +221,25 @@ 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} @@ -293,7 +312,8 @@ add_custom_command( unset(OTELCPP_PROTO_TARGET_OPTIONS) if(CMAKE_SYSTEM_NAME MATCHES "Windows|MinGW|WindowsStore") list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC) -elseif(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) +elseif((NOT protobuf_lib_type STREQUAL "STATIC_LIBRARY") + AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)) list(APPEND OTELCPP_PROTO_TARGET_OPTIONS SHARED) else() list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC) @@ -314,13 +334,12 @@ add_library( set_target_version(opentelemetry_proto) target_include_directories( - opentelemetry_proto - PUBLIC "$" - "$") + 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 "") +set_target_properties(opentelemetry_proto PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" + CXX_CLANG_TIDY "") if(NOT Protobuf_INCLUDE_DIRS AND TARGET protobuf::libprotobuf) get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) @@ -339,13 +358,20 @@ if(WITH_OTLP_GRPC) set_target_version(opentelemetry_proto_grpc) # Disable include-what-you-use and clang-tidy on generated code. - set_target_properties(opentelemetry_proto_grpc - PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" CXX_CLANG_TIDY "") + set_target_properties( + opentelemetry_proto_grpc PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" + CXX_CLANG_TIDY "") 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") target_link_libraries(opentelemetry_proto_grpc PUBLIC gRPC::grpc++) endif() @@ -382,7 +408,8 @@ 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 +# 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 diff --git a/cmake/tools.cmake b/cmake/tools.cmake index ffc3732d2b..43ac5156d4 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -99,7 +99,9 @@ function(project_build_tools_get_imported_location OUTPUT_VAR_NAME TARGET_NAME) get_target_property(TARGET_TYPE ${TARGET_NAME} TYPE) if(TARGET_TYPE STREQUAL "INTERFACE_LIBRARY") # For interface libraries, do not attempt to retrieve imported location. - set(${OUTPUT_VAR_NAME} "" PARENT_SCOPE) + set(${OUTPUT_VAR_NAME} + "" + PARENT_SCOPE) return() endif() diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 3ec20517e0..f39ac972ee 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -1,10 +1,20 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 +if(protobuf_lib_type STREQUAL "STATIC_LIBRARY") + set(OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE STATIC) +else() + set(OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE) +endif() + add_library( opentelemetry_otlp_recordable - src/otlp_environment.cc src/otlp_log_recordable.cc src/otlp_recordable.cc - src/otlp_populate_attribute_utils.cc src/otlp_recordable_utils.cc + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} + src/otlp_environment.cc + src/otlp_log_recordable.cc + src/otlp_recordable.cc + src/otlp_populate_attribute_utils.cc + src/otlp_recordable_utils.cc src/otlp_metric_utils.cc) set_target_properties(opentelemetry_otlp_recordable PROPERTIES EXPORT_NAME otlp_recordable) @@ -23,10 +33,20 @@ target_link_libraries(opentelemetry_otlp_recordable if(WITH_OTLP_GRPC) find_package(gRPC REQUIRED) + if(NOT DEFINED grpc_lib_type) + message( + FATAL_ERROR "cmake/opentelemetry-proto.cmake should be included first") + endif() + if(grpc_lib_type STREQUAL "STATIC_LIBRARY" OR protobuf_lib_type STREQUAL + "STATIC_LIBRARY") + set(OPENTELEMETRY_OTLP_GRPC_CLIENT_LIB_TYPE STATIC) + else() + set(OPENTELEMETRY_OTLP_GRPC_CLIENT_LIB_TYPE) + endif() add_library( opentelemetry_exporter_otlp_grpc_client - src/otlp_grpc_client.cc src/otlp_grpc_client_factory.cc - src/otlp_grpc_utils.cc) + ${OPENTELEMETRY_OTLP_GRPC_CLIENT_LIB_TYPE} src/otlp_grpc_client.cc + src/otlp_grpc_client_factory.cc src/otlp_grpc_utils.cc) set_target_properties(opentelemetry_exporter_otlp_grpc_client PROPERTIES EXPORT_NAME otlp_grpc_client) set_target_version(opentelemetry_exporter_otlp_grpc_client) @@ -40,8 +60,9 @@ if(WITH_OTLP_GRPC) opentelemetry_exporter_otlp_grpc_client PUBLIC opentelemetry_sdk opentelemetry_common # gRPC::grpc++ must be linked before opentelemetry_proto_grpc. - opentelemetry_proto_grpc - PRIVATE gRPC::grpc++ opentelemetry_ext) + "$" + PRIVATE "$" gRPC::grpc++ + opentelemetry_ext) get_target_property(GRPC_INCLUDE_DIRECTORY gRPC::grpc++ INTERFACE_INCLUDE_DIRECTORIES) @@ -60,8 +81,8 @@ if(WITH_OTLP_GRPC) add_library( opentelemetry_exporter_otlp_grpc - src/otlp_grpc_exporter.cc src/otlp_grpc_exporter_factory.cc - src/otlp_grpc_exporter_options.cc) + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_grpc_exporter.cc + src/otlp_grpc_exporter_factory.cc src/otlp_grpc_exporter_options.cc) set_target_properties(opentelemetry_exporter_otlp_grpc PROPERTIES EXPORT_NAME otlp_grpc_exporter) @@ -76,7 +97,7 @@ if(WITH_OTLP_GRPC) add_library( opentelemetry_exporter_otlp_grpc_log - src/otlp_grpc_log_record_exporter.cc + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_grpc_log_record_exporter.cc src/otlp_grpc_log_record_exporter_factory.cc src/otlp_grpc_log_record_exporter_options.cc) @@ -94,7 +115,8 @@ if(WITH_OTLP_GRPC) add_library( opentelemetry_exporter_otlp_grpc_metrics - src/otlp_grpc_metric_exporter.cc src/otlp_grpc_metric_exporter_factory.cc + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_grpc_metric_exporter.cc + src/otlp_grpc_metric_exporter_factory.cc src/otlp_grpc_metric_exporter_options.cc) set_target_properties(opentelemetry_exporter_otlp_grpc_metrics @@ -111,8 +133,10 @@ if(WITH_OTLP_GRPC) endif() if(WITH_OTLP_HTTP) - add_library(opentelemetry_exporter_otlp_http_client src/otlp_http.cc - src/otlp_http_client.cc) + add_library( + opentelemetry_exporter_otlp_http_client + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http.cc + src/otlp_http_client.cc) set_target_properties(opentelemetry_exporter_otlp_http_client PROPERTIES EXPORT_NAME otlp_http_client) set_target_version(opentelemetry_exporter_otlp_http_client) @@ -141,8 +165,8 @@ if(WITH_OTLP_HTTP) add_library( opentelemetry_exporter_otlp_http - src/otlp_http_exporter.cc src/otlp_http_exporter_factory.cc - src/otlp_http_exporter_options.cc) + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http_exporter.cc + src/otlp_http_exporter_factory.cc src/otlp_http_exporter_options.cc) set_target_properties(opentelemetry_exporter_otlp_http PROPERTIES EXPORT_NAME otlp_http_exporter) @@ -157,7 +181,7 @@ if(WITH_OTLP_HTTP) add_library( opentelemetry_exporter_otlp_http_log - src/otlp_http_log_record_exporter.cc + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http_log_record_exporter.cc src/otlp_http_log_record_exporter_factory.cc src/otlp_http_log_record_exporter_options.cc) @@ -175,7 +199,8 @@ if(WITH_OTLP_HTTP) add_library( opentelemetry_exporter_otlp_http_metric - src/otlp_http_metric_exporter.cc src/otlp_http_metric_exporter_factory.cc + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http_metric_exporter.cc + src/otlp_http_metric_exporter_factory.cc src/otlp_http_metric_exporter_options.cc) set_target_properties(opentelemetry_exporter_otlp_http_metric @@ -192,7 +217,8 @@ if(WITH_OTLP_HTTP) endif() if(WITH_OTLP_FILE) - add_library(opentelemetry_exporter_otlp_file_client src/otlp_file_client.cc) + add_library(opentelemetry_exporter_otlp_file_client + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_client.cc) set_target_properties(opentelemetry_exporter_otlp_file_client PROPERTIES EXPORT_NAME otlp_file_client) set_target_version(opentelemetry_exporter_otlp_file_client) @@ -216,8 +242,8 @@ if(WITH_OTLP_FILE) add_library( opentelemetry_exporter_otlp_file - src/otlp_file_exporter.cc src/otlp_file_exporter_factory.cc - src/otlp_file_exporter_options.cc) + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_exporter.cc + src/otlp_file_exporter_factory.cc src/otlp_file_exporter_options.cc) set_target_properties(opentelemetry_exporter_otlp_file PROPERTIES EXPORT_NAME otlp_file_exporter) @@ -232,7 +258,7 @@ if(WITH_OTLP_FILE) add_library( opentelemetry_exporter_otlp_file_log - src/otlp_file_log_record_exporter.cc + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_log_record_exporter.cc src/otlp_file_log_record_exporter_factory.cc src/otlp_file_log_record_exporter_options.cc) @@ -250,7 +276,8 @@ if(WITH_OTLP_FILE) add_library( opentelemetry_exporter_otlp_file_metric - src/otlp_file_metric_exporter.cc src/otlp_file_metric_exporter_factory.cc + ${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_metric_exporter.cc + src/otlp_file_metric_exporter_factory.cc src/otlp_file_metric_exporter_options.cc) set_target_properties(opentelemetry_exporter_otlp_file_metric @@ -371,7 +398,7 @@ if(BUILD_TESTING) add_executable(otlp_grpc_exporter_test test/otlp_grpc_exporter_test.cc) target_link_libraries( otlp_grpc_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - ${GMOCK_LIB} opentelemetry_exporter_otlp_grpc gRPC::grpc++) + ${GMOCK_LIB} opentelemetry_exporter_otlp_grpc) gtest_add_tests( TARGET otlp_grpc_exporter_test TEST_PREFIX exporter.otlp.