Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUILD] Support to use different cmake package CONFIG of dependencies. #2263

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ if(NOT WITH_API_ONLY)
endif()

include(cmake/opentelemetry-build-external-component.cmake)
include(cmake/patch-imported-config.cmake)

if(OPENTELEMETRY_INSTALL)
# Export cmake config and support find_packages(opentelemetry-cpp CONFIG)
Expand Down
141 changes: 141 additions & 0 deletions cmake/patch-imported-config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

# Some prebuilt or installed targets may have different CONFIG settings than
# what we use to configure otel-cpp. This file applies patches to the imported
# targets in order to use compatible CONFIG settings for fallback.

# Common dependencies
project_build_tools_patch_default_imported_config(ZLIB::ZLIB)

# protobuf targets
if(Protobuf_FOUND OR PROTOBUF_FOUND)
project_build_tools_patch_default_imported_config(
utf8_range::utf8_range utf8_range::utf8_validity protobuf::libprotobuf-lite
protobuf::libprotobuf protobuf::libprotoc)
endif()

# cares targets
if(TARGET c-ares::cares)
project_build_tools_patch_default_imported_config(c-ares::cares)
endif()

# curl targets
if(TARGET CURL::libcurl)
project_build_tools_patch_default_imported_config(CURL::libcurl)
endif()

# abseil targets
if(WITH_ABSEIL)
project_build_tools_patch_default_imported_config(
absl::bad_variant_access
absl::raw_logging_internal
absl::log_severity
absl::log_internal_check_op
absl::log_internal_nullguard
absl::strings
absl::strings_internal
absl::base
absl::spinlock_wait
absl::int128
absl::throw_delegate
absl::log_internal_message
absl::examine_stack
absl::stacktrace
absl::debugging_internal
absl::symbolize
absl::demangle_internal
absl::malloc_internal
absl::log_internal_format
absl::log_internal_globals
absl::time
absl::civil_time
absl::time_zone
absl::str_format_internal
absl::log_internal_proto
absl::log_internal_log_sink_set
absl::log_globals
absl::hash
absl::city
absl::bad_optional_access
absl::low_level_hash
absl::log_entry
absl::log_sink
absl::synchronization
absl::graphcycles_internal
absl::strerror
absl::log_internal_conditions
absl::cord
absl::cord_internal
absl::crc_cord_state
absl::crc32c
absl::crc_cpu_detect
absl::crc_internal
absl::cordz_functions
absl::exponential_biased
absl::cordz_info
absl::cordz_handle
absl::leak_check
absl::die_if_null
absl::flags
absl::flags_commandlineflag
absl::flags_commandlineflag_internal
absl::flags_config
absl::flags_program_name
absl::flags_internal
absl::flags_marshalling
absl::flags_reflection
absl::flags_private_handle_accessor
absl::raw_hash_set
absl::hashtablez_sampler
absl::log_initialize
absl::status
absl::statusor)
endif()

# gRPC targets
if(TARGET gRPC::grpc++)
project_build_tools_patch_default_imported_config(
gRPC::cares
gRPC::re2
gRPC::ssl
gRPC::crypto
gRPC::zlibstatic
gRPC::address_sorting
gRPC::gpr
gRPC::grpc
gRPC::grpc_unsecure
gRPC::grpc++
gRPC::grpc++_alts
gRPC::grpc++_error_details
gRPC::grpc++_reflection
gRPC::grpc++_unsecure
gRPC::grpc_authorization_provider
gRPC::grpc_plugin_support
gRPC::grpcpp_channelz
gRPC::upb)
endif()

# prometheus targets
if(TARGET prometheus-cpp::core)
project_build_tools_patch_default_imported_config(
prometheus-cpp::core prometheus-cpp::pull prometheus-cpp::push)
endif()

# civetweb targets
if(TARGET civetweb::civetweb)
project_build_tools_patch_default_imported_config(
civetweb::civetweb civetweb::server civetweb::civetweb-cpp)
endif()

if(BUILD_TESTING)
project_build_tools_patch_default_imported_config(
GTest::gtest
GTest::gtest_main
GTest::gmock
GTest::gmock_main
GTest::GTest
GTest::Main
benchmark::benchmark
benchmark::benchmark_main)
endif()
80 changes: 80 additions & 0 deletions cmake/tools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,83 @@ function(project_build_tools_get_imported_location OUTPUT_VAR_NAME TARGET_NAME)
PARENT_SCOPE)
endif()
endfunction()

#[[
If we build third party packages with a different CONFIG setting from building
otel-cpp, cmake may not find a suitable file in imported targets (#705, #1359)
when linking. But on some platforms, different CONFIG settings can be used when
these CONFIG settings have the same ABI. For example, on Linux, we can build
gRPC and protobuf with -DCMAKE_BUILD_TYPE=Release, but build otel-cpp with
-DCMAKE_BUILD_TYPE=Debug and link these libraries together.
The properties of imported targets can be found here:
https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets
]]
function(project_build_tools_patch_default_imported_config)
set(PATCH_VARS
IMPORTED_IMPLIB
IMPORTED_LIBNAME
owent marked this conversation as resolved.
Show resolved Hide resolved
IMPORTED_LINK_DEPENDENT_LIBRARIES
IMPORTED_LINK_INTERFACE_LANGUAGES
IMPORTED_LINK_INTERFACE_LIBRARIES
IMPORTED_LINK_INTERFACE_MULTIPLICITY
IMPORTED_LOCATION
IMPORTED_NO_SONAME
IMPORTED_OBJECTS
IMPORTED_SONAME)
foreach(TARGET_NAME ${ARGN})
if(TARGET ${TARGET_NAME})
get_target_property(IS_IMPORTED_TARGET ${TARGET_NAME} IMPORTED)
if(NOT IS_IMPORTED_TARGET)
continue()
endif()

if(CMAKE_VERSION VERSION_LESS "3.19.0")
get_target_property(TARGET_TYPE_NAME ${TARGET_NAME} TYPE)
if(TARGET_TYPE_NAME STREQUAL "INTERFACE_LIBRARY")
continue()
endif()
endif()

get_target_property(DO_NOT_OVERWRITE ${TARGET_NAME} IMPORTED_LOCATION)
if(DO_NOT_OVERWRITE)
continue()
endif()

# MSVC's STL and debug level must match the target, so we can only move
# out IMPORTED_LOCATION_NOCONFIG
if(MSVC)
set(PATCH_IMPORTED_CONFIGURATION "NOCONFIG")
else()
get_target_property(PATCH_IMPORTED_CONFIGURATION ${TARGET_NAME}
IMPORTED_CONFIGURATIONS)
endif()

if(NOT PATCH_IMPORTED_CONFIGURATION)
continue()
endif()

get_target_property(PATCH_TARGET_LOCATION ${TARGET_NAME}
"IMPORTED_LOCATION_${PATCH_IMPORTED_CONFIGURATION}")
if(NOT PATCH_TARGET_LOCATION)
continue()
endif()

foreach(PATCH_IMPORTED_KEY IN LISTS PATCH_VARS)
get_target_property(
PATCH_IMPORTED_VALUE ${TARGET_NAME}
"${PATCH_IMPORTED_KEY}_${PATCH_IMPORTED_CONFIGURATION}")
if(PATCH_IMPORTED_VALUE)
set_target_properties(
${TARGET_NAME} PROPERTIES "${PATCH_IMPORTED_KEY}"
"${PATCH_IMPORTED_VALUE}")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message(
STATUS
"Patch: ${TARGET_NAME} ${PATCH_IMPORTED_KEY} will use ${PATCH_IMPORTED_KEY}_${PATCH_IMPORTED_CONFIGURATION}(\"${PATCH_IMPORTED_VALUE}\") by default."
)
endif()
endif()
endforeach()
endif()
endforeach()
endfunction()