Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ build configuration.
| | opentelemetry-cpp::trace |
| | opentelemetry-cpp::metrics |
| | opentelemetry-cpp::logs |
| | opentelemetry-cpp::configuration_core (EXPERIMENTAL: Programmatic configuration) |
| **configuration** | opentelemetry-cpp::configuration (EXPERIMENTAL: YAML configuration) |
| **ext_common** | opentelemetry-cpp::ext |
| **ext_http_curl** | opentelemetry-cpp::http_client_curl |
| **ext_dll** | opentelemetry-cpp::opentelemetry_cpp |
Expand Down
17 changes: 12 additions & 5 deletions ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -493,27 +493,34 @@ elif [[ "$1" == "cmake.install.test" ]]; then
"ext_http_curl"
"exporters_in_memory"
"exporters_ostream"
"exporters_ostream_builder"
"exporters_otlp_common"
"exporters_otlp_file"
"exporters_otlp_file_builder"
"exporters_otlp_grpc"
"exporters_otlp_grpc_builder"
"exporters_otlp_http"
"exporters_otlp_http_builder"
"exporters_prometheus"
"exporters_prometheus_builder"
"exporters_elasticsearch"
"exporters_zipkin"
"resource_detectors"
)
EXPECTED_COMPONENTS_STRING=$(IFS=\;; echo "${EXPECTED_COMPONENTS[*]}")

DEPRECATED_COMPONENTS=(
"exporters_ostream_builder"
"exporters_otlp_builder_utils"
"exporters_otlp_file_builder"
"exporters_otlp_grpc_builder"
"exporters_otlp_http_builder"
"exporters_prometheus_builder"
)
DEPRECATED_COMPONENTS_STRING=$(IFS=\;; echo "${DEPRECATED_COMPONENTS[*]}")

mkdir -p "${BUILD_DIR}/install_test"
cd "${BUILD_DIR}/install_test"
cmake "${CMAKE_OPTIONS[@]}" \
"-DCMAKE_PREFIX_PATH=${INSTALL_TEST_DIR}" \
"-DINSTALL_TEST_CMAKE_OPTIONS=${CMAKE_OPTIONS_STRING}" \
"-DINSTALL_TEST_COMPONENTS=${EXPECTED_COMPONENTS_STRING}" \
"-DINSTALL_TEST_DEPRECATED_COMPONENTS=${DEPRECATED_COMPONENTS_STRING}" \
-S "${SRC_DIR}/install/test/cmake"
ctest --output-on-failure
exit 0
Expand Down
30 changes: 27 additions & 3 deletions cmake/find-package-support-functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@
include("${CMAKE_CURRENT_LIST_DIR}/component-definitions.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/thirdparty-dependency-definitions.cmake")

#-------------------------------------------------------------------------
# Function to resolve deprecated component names to their aliases.
# Components without an alias are removed from the list
#-------------------------------------------------------------------------
function(resolve_deprecated_components requested_components_inout)
set(_result ${${requested_components_inout}})
foreach(_COMPONENT IN LISTS ${requested_components_inout})
if(${_COMPONENT} IN_LIST OTEL_DEPRECATED_COMPONENTS_LIST)
set(_replacement_var "COMPONENT_${_COMPONENT}_REPLACEMENT")
if(DEFINED ${_replacement_var})
message(DEPRECATION "opentelemetry-cpp: component `${_COMPONENT}` is deprecated, use `${${_replacement_var}}` instead.")
list(REMOVE_ITEM _result ${_COMPONENT})
list(APPEND _result ${${_replacement_var}})
else()
message(DEPRECATION "opentelemetry-cpp: component `${_COMPONENT}` is deprecated with no replacement.")
list(REMOVE_ITEM _result ${_COMPONENT})
endif()
endif()
endforeach()
list(REMOVE_DUPLICATES _result)
set(${requested_components_inout} "${_result}" PARENT_SCOPE)
endfunction()

#-------------------------------------------------------------------------
# Function to get installed components.
#-------------------------------------------------------------------------
Expand Down Expand Up @@ -33,7 +56,6 @@ function(get_dependent_components component_in dependent_components_out)
set(${dependent_components_out} ${result} PARENT_SCOPE)
endfunction()


#-------------------------------------------------------------------------
# Function to get requested components.
#-------------------------------------------------------------------------
Expand All @@ -44,8 +66,10 @@ function(get_requested_components installed_components_in requested_components_o
message(DEBUG "get_requested_components: No components explicitly requested. Importing all installed components including: ${result}")
set(${requested_components_out} ${result} PARENT_SCOPE)
else()
message(DEBUG "get_requested_components: Components requested: ${opentelemetry-cpp_FIND_COMPONENTS}")
foreach(_COMPONENT IN LISTS opentelemetry-cpp_FIND_COMPONENTS)
set(REQUESTED_COMPONENTS ${opentelemetry-cpp_FIND_COMPONENTS})
message(DEBUG "get_requested_components: Components requested: ${REQUESTED_COMPONENTS}")
resolve_deprecated_components(REQUESTED_COMPONENTS)
foreach(_COMPONENT IN LISTS REQUESTED_COMPONENTS)
if(NOT ${_COMPONENT} IN_LIST OTEL_BUILT_COMPONENTS_LIST)
message(ERROR " get_requested_components: Component `${_COMPONENT}` is not a built component of the opentelemetry-cpp package. Built components include: ${OTEL_BUILT_COMPONENTS_LIST}")
return()
Expand Down
58 changes: 52 additions & 6 deletions cmake/otel-install-functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -317,28 +317,44 @@ endfunction()

#-----------------------------------------------------------------------
# otel_add_component:
# Adds a component to the list of components to be installed. A component name and list of targest are required.
# Adds a component to the list of components to be installed. A component name and list of targets are required.
# Optional files can be added to the component by specifying a directory, destination and matching pattern.
# Each target is assigned to the component and its dependencies are identified based on the LINK_LIBRARIES property.
# An alias target is also created for each target in the form of PROJECT_NAME::TARGET_EXPORT_NAME.
# DEPRECATED_NAMES lists old component names that are redirected to this component with a deprecation warning.
# DEPRECATED marks a component that has been fully removed with no replacement (no TARGETS required).
# Usage:
# otel_add_component(
# COMPONENT <component_name>
# [DEPRECATED_NAMES <old_name1> <old_name2> ...]
# TARGETS <target1> <target2> ...
# FILES_DIRECTORY <directory>
# FILES_DESTINATION <destination>
# FILES_MATCHING <matching>)
# [FILES_DIRECTORY <directory>
# FILES_DESTINATION <destination>
# FILES_MATCHING <matching>])
# otel_add_component(
# COMPONENT <removed_component_name>
# DEPRECATED)
#-----------------------------------------------------------------------
function(otel_add_component)
set(optionArgs )
set(optionArgs DEPRECATED)
set(oneValueArgs COMPONENT FILES_DIRECTORY FILES_DESTINATION)
set(multiValueArgs TARGETS FILES_MATCHING)
set(multiValueArgs TARGETS FILES_MATCHING DEPRECATED_NAMES)
cmake_parse_arguments(_OTEL_ADD_COMP "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")

if(NOT _OTEL_ADD_COMP_COMPONENT)
message(FATAL_ERROR "otel_add_component: COMPONENT is required")
endif()

if(_OTEL_ADD_COMP_DEPRECATED)
# TODO: Support deprecated components that still install their targets, and
# mark those targets deprecated during the deprecation window.
get_property(_deprecated_components DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_DEPRECATED_COMPONENTS_LIST)
list(APPEND _deprecated_components "${_OTEL_ADD_COMP_COMPONENT}")
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_DEPRECATED_COMPONENTS_LIST "${_deprecated_components}")
message(DEBUG " DEPRECATED: ${_OTEL_ADD_COMP_COMPONENT} (no replacement)")
return()
endif()

if(NOT _OTEL_ADD_COMP_TARGETS)
message(FATAL_ERROR "otel_add_component: TARGETS is required")
endif()
Expand Down Expand Up @@ -378,6 +394,16 @@ function(otel_add_component)
FILES_MATCHING ${_OTEL_ADD_COMP_FILES_MATCHING}
COMPONENT_DEPENDS ${_COMPONENT_DEPENDS}
THIRDPARTY_DEPENDS ${_THIRDPARTY_DEPENDS})

foreach(_DEP_NAME IN LISTS _OTEL_ADD_COMP_DEPRECATED_NAMES)
get_property(_deprecated_components DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_DEPRECATED_COMPONENTS_LIST)
list(APPEND _deprecated_components "${_DEP_NAME}")
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_DEPRECATED_COMPONENTS_LIST "${_deprecated_components}")
set_property(DIRECTORY ${PROJECT_SOURCE_DIR}
PROPERTY OTEL_COMPONENT_REPLACEMENT_${_DEP_NAME}
"${_OTEL_ADD_COMP_COMPONENT}")
message(DEBUG " DEPRECATED_NAME: ${_DEP_NAME} -> ${_OTEL_ADD_COMP_COMPONENT}")
endforeach()
endfunction()

#-----------------------------------------------------------------------
Expand Down Expand Up @@ -420,6 +446,26 @@ function(otel_install_components)
_otel_populate_component_thirdparty_depends_block(${_COMPONENT} OTEL_COMPONENTS_THIRDPARTY_DEPENDENCIES_BLOCK)
endforeach()

get_property(OTEL_DEPRECATED_COMPONENTS_LIST DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_DEPRECATED_COMPONENTS_LIST)

if(OTEL_DEPRECATED_COMPONENTS_LIST)
message(STATUS "Install DEPRECATED COMPONENT definitions:")
endif()

set(OTEL_COMPONENTS_REPLACEMENTS_BLOCK "")
foreach(_DEPRECATED_COMPONENT IN LISTS OTEL_DEPRECATED_COMPONENTS_LIST)
get_property(_REPLACEMENT_COMPONENT DIRECTORY ${PROJECT_SOURCE_DIR}
PROPERTY OTEL_COMPONENT_REPLACEMENT_${_DEPRECATED_COMPONENT})
message(STATUS " Deprecated COMPONENT ${_DEPRECATED_COMPONENT}")
if(_REPLACEMENT_COMPONENT)
message(STATUS " Replacement: ${_REPLACEMENT_COMPONENT}")
string(APPEND OTEL_COMPONENTS_REPLACEMENTS_BLOCK
"set(COMPONENT_${_DEPRECATED_COMPONENT}_REPLACEMENT ${_REPLACEMENT_COMPONENT})\n")
else()
message(STATUS " No replacement installed.")
endif()
endforeach()

configure_file(
"${PROJECT_SOURCE_DIR}/cmake/templates/component-definitions.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/component-definitions.cmake"
Expand Down
11 changes: 11 additions & 0 deletions cmake/templates/component-definitions.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@

# Configured from opentelemetry-cpp/cmake/component-definitions.cmake.in

# ----------------------------------------------------------------------
# Deprecated components
# ----------------------------------------------------------------------
set(OTEL_DEPRECATED_COMPONENTS_LIST @OTEL_DEPRECATED_COMPONENTS_LIST@)

# ----------------------------------------------------------------------
# Deprecated component replacements (deprecated_name -> replacement_name)
# ----------------------------------------------------------------------

@OTEL_COMPONENTS_REPLACEMENTS_BLOCK@

# ----------------------------------------------------------------------
# opentelmetry-cpp Built COMPONENT list
# ----------------------------------------------------------------------
Expand Down
13 changes: 13 additions & 0 deletions cmake/templates/opentelemetry-cpp-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
# COMPONENTS
# api
# sdk
# configuration
# ext_common
# ext_http_curl
# ext_dll
Expand All @@ -88,6 +89,14 @@
# resource_detectors
# shims_opentracing
#
# DEPRECATED COMPONENTS
# exporters_otlp_builder_utils - targets moved to COMPONENT exporters_otlp_common
# exporters_otlp_file_builder - targets moved to COMPONENT exporters_otlp_file
# exporters_otlp_http_builder - targets moved to COMPONENT exporters_otlp_http
# exporters_otlp_grpc_builder - targets moved to COMPONENT exporters_otlp_grpc
# exporters_ostream_builder - targets moved to COMPONENT exporters_ostream
# exporters_prometheus_builder - targets moved to COMPONENT exporters_prometheus
# --------------------
# ::
#
# TARGETS
Expand All @@ -99,6 +108,8 @@
# opentelemetry-cpp::trace - Imported target of COMPONENT sdk
# opentelemetry-cpp::metrics - Imported target of COMPONENT sdk
# opentelemetry-cpp::logs - Imported target of COMPONENT sdk
# opentelemetry-cpp::configuration_core - Imported target of COMPONENT sdk
# opentelemetry-cpp::configuration - Imported target of COMPONENT configuration
# opentelemetry-cpp::ext - Imported target of COMPONENT ext_common
# opentelemetry-cpp::http_client_curl - Imported target of COMPONENT ext_http_curl
# opentelemetry-cpp::opentelemetry_cpp - Imported target of COMPONENT ext_dll
Expand Down Expand Up @@ -143,6 +154,7 @@
# - **Protobuf**
# - **gRPC**
# - **prometheus-cpp**
# - **ryml**
# - **OpenTracing**
#
# **Found using the CMake MODULE search mode:**
Expand Down Expand Up @@ -214,6 +226,7 @@ endforeach()
# TRUE if all variables listed contain valid results, e.g. valid file paths.
include("FindPackageHandleStandardArgs")

set(${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS ${_REQUESTED_COMPONENTS})
set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE})

find_package_handle_standard_args(
Expand Down
131 changes: 131 additions & 0 deletions docs/deprecation-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,137 @@ and will not be impacted by the removal to come.
When implementing such logic, document it in the mitigation section,
in file `DEPRECATED`.

### CMake package component deprecation

The installed opentelemetry-cpp CMake package supports the `COMPONENTS`
argument to `find_package(opentelemetry-cpp CONFIG ...)`.
CMake components may need to be deprecated over time.

There are three cases to distinguish:

* a component name is changed,
* a component is merged (with all its targets) into another component,
* a component and its targets are deprecated and set for future removal from the
package.

#### Component name change

For a component name change, keep the CMake target set unchanged and add the
deprecated name under the `DEPRECATED_NAMES` list.

Example:

```cmake
otel_add_component(
COMPONENT component_old_name
TARGETS opentelemetry_some_target)
```

The new component receives the new name but must retain the targets unchanged.

```cmake
otel_add_component(
COMPONENT component_new_name
DEPRECATED_NAMES component_old_name
TARGETS opentelemetry_some_target)
```

When a user requests `component_old_name`, the installed package config emits a CMake
deprecation warning and resolves the request to `component_new_name`.

```cmake
# the following will now resolve `component_old_name` to `component_new_name`
find_package(opentelemetry-cpp CONFIG COMPONENTS component_old_name)
```

#### Component merge

For a component merge, add `component_B` to `component_A`'s
`DEPRECATED_NAMES` list and add `component_B`'s targets to `component_A`'s
`TARGETS` list:

Example:

Before the merge, two components are defined.

```cmake
otel_add_component(
COMPONENT component_A
TARGETS component_A_target)

otel_add_component(
COMPONENT component_B
TARGETS component_B_target)
```

After the merge, `component_B`'s definition is removed.
Its name and targets are added to the deprecated names and targets
for `component_A` respectively.

```cmake
otel_add_component(
COMPONENT component_A
DEPRECATED_NAMES component_B
TARGETS
component_A_target
component_B_target)
```

When a user requests `component_B`, the installed package config emits a CMake
deprecation warning and resolves the request to `component_A` importing
the merged set of targets.

```cmake
# the following will now resolve deprecated `component_B` to `component_A`
# all targets from the merged component are imported and remain unchanged
find_package(opentelemetry-cpp CONFIG COMPONENTS component_B)

target_link_libraries(my_library PRIVATE
opentelemetry-cpp::component_A_target
opentelemetry-cpp::component_B_target)
```

Note: The set of targets provided by the independent components before merge
and from the merged component must not change. Changing target names risks
breaking the user's CMake configuration. Deprecating and renaming targets
remains a TODO and is currently not supported.

#### Deprecating a component for removal

[TODO] This use case is not fully implemented in `otel_add_component`

When a component and its targets are set for removal from the package, the
component must be marked deprecated with the `DEPRECATED` tag and remain in the
package for a deprecation period. During this time the component and its targets
must be installed with the package and be imported by `find_package`.

Example:

```cmake
otel_add_component(
COMPONENT component_to_remove
DEPRECATED
TARGETS component_target
)
```

```cmake
# the following will import the deprecated component's targets and emit a
# CMake deprecation warning
find_package(opentelemetry-cpp CONFIG COMPONENTS component_to_remove)
```

#### Validate the deprecated component

Add the deprecated component name to the `./ci/do_ci.sh` script's
`cmake.install.test` target's `DEPRECATED_COMPONENTS` variable.

The install test
`./install/test/cmake/usage_tests/deprecated_components` verifies that
requesting deprecated
component names with `find_package` configures successfully and that
CMake emits a deprecation warning.

### C++ deprecation

#### C++ header deprecation
Expand Down
Loading
Loading