Skip to content
Open
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
20 changes: 20 additions & 0 deletions .github/workflows/cmake_install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
- name: Build dependencies with vcpkg submodule
run: |
./ci/setup_windows_ci_environment.ps1
- name: Run Install Functions Tests
run: ./ci/do_ci.ps1 cmake.install_functions.test
- name: Run Tests
run: ./ci/do_ci.ps1 cmake.install.test
- name: Run DLL Tests
Expand All @@ -51,6 +53,8 @@ jobs:
- name: Build dependencies with vcpkg submodule
run: |
./ci/setup_windows_ci_environment.ps1
- name: Run Install Functions Tests
run: ./ci/do_ci.ps1 cmake.install_functions.test
- name: Run Tests
run: ./ci/do_ci.ps1 cmake.install.test

Expand Down Expand Up @@ -78,6 +82,8 @@ jobs:
sudo -E apt-get update
sudo -E apt-get install -y libabsl-dev libcurl4-openssl-dev zlib1g-dev nlohmann-json3-dev libprotobuf-dev libgrpc++-dev protobuf-compiler protobuf-compiler-grpc
sudo -E ./ci/install_thirdparty.sh --install-dir /usr/local --tags-file third_party_release --packages "googletest;benchmark"
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down Expand Up @@ -108,6 +114,8 @@ jobs:
- name: Install Dependencies
run: |
sudo -E ./ci/install_thirdparty.sh --install-dir /usr/local --tags-file install/cmake/third_party_latest
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down Expand Up @@ -138,6 +146,8 @@ jobs:
- name: Install Dependencies
run: |
sudo -E ./ci/install_thirdparty.sh --install-dir /usr/local --tags-file install/cmake/third_party_stable
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down Expand Up @@ -172,6 +182,8 @@ jobs:
- name: Install Dependencies
run: |
sudo -E ./ci/install_thirdparty.sh --install-dir /usr/local --tags-file install/cmake/third_party_minimum
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down Expand Up @@ -209,6 +221,8 @@ jobs:
run: |
conan install install/conan/conanfile_stable.txt --build=missing -of /home/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD}
conan cache clean --source --build
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down Expand Up @@ -248,6 +262,8 @@ jobs:
run: |
conan install install/conan/conanfile_latest.txt --build=missing -of /home/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD}
conan cache clean --source --build
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down Expand Up @@ -288,6 +304,8 @@ jobs:
run: |
conan install install/conan/conanfile_stable.txt --build=missing -of /Users/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD}
conan cache clean --source --build
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down Expand Up @@ -320,6 +338,8 @@ jobs:
brew install grpc
brew install nlohmann-json
brew install prometheus-cpp
- name: Run Install Functions Tests
run: ./ci/do_ci.sh cmake.install_functions.test
- name: Run Tests (static libs)
env:
BUILD_SHARED_LIBS: 'OFF'
Expand Down
55 changes: 55 additions & 0 deletions ci/do_ci.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,61 @@ switch ($action) {

exit 0
}
"cmake.install_functions.test" {
# Test the otel install functions and installed cmake package config
# with mock components injected via OPENTELEMETRY_EXTERNAL_COMPONENT_PATH.
# The package is installed, it then runs cmake configure time tests from
# install/test/cmake/install_functions_test.
Remove-Item -Recurse -Force "$BUILD_DIR\*"
Remove-Item -Recurse -Force "$INSTALL_TEST_DIR\*"
cd "$BUILD_DIR"

cmake $SRC_DIR `
-DVCPKG_TARGET_TRIPLET=x64-windows `
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" `
"-DCMAKE_INSTALL_PREFIX=$INSTALL_TEST_DIR" `
-DOPENTELEMETRY_INSTALL=ON `
"-DOPENTELEMETRY_EXTERNAL_COMPONENT_PATH=$SRC_DIR\install\test\cmake\install_functions_test\components" `
-DENABLE_EXAMPLES=OFF `
-DENABLE_TESTS=OFF `
-DENABLE_COMPONENTS=OFF `
-DENABLE_PREVIEW=OFF `
"-C $SRC_DIR/test_common/cmake/all-options-abiv1.cmake"
$exit = $LASTEXITCODE
if ($exit -ne 0) {
exit $exit
}

cmake --build . -j $nproc
$exit = $LASTEXITCODE
if ($exit -ne 0) {
exit $exit
}

cmake --build . --target install
$exit = $LASTEXITCODE
if ($exit -ne 0) {
exit $exit
}

mkdir "$BUILD_DIR\install_functions_test"
cd "$BUILD_DIR\install_functions_test"

cmake "-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" `
-S "$SRC_DIR\install\test\cmake\install_functions_test"
$exit = $LASTEXITCODE
if ($exit -ne 0) {
exit $exit
}

ctest -C Debug --output-on-failure
$exit = $LASTEXITCODE
if ($exit -ne 0) {
exit $exit
}

exit 0
}
"cmake.dll.install.test" {
cd "$BUILD_DIR"
Remove-Item -Recurse -Force "$BUILD_DIR\*"
Expand Down
39 changes: 39 additions & 0 deletions ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,45 @@ elif [[ "$1" == "cmake.do_not_install.test" ]]; then
cmake --build . "${CMAKE_BUILD_ARGS[@]}"
ctest --output-on-failure
exit 0
elif [[ "$1" == "cmake.install_functions.test" ]]; then
# Test the otel install functions and installed cmake package config
# with mock components injected via
# OPENTELEMETRY_EXTERNAL_COMPONENT_PATH. The package is installed, it then runs
# cmake configure time tests from install/test/cmake/install_functions_test.
if [[ -n "${BUILD_SHARED_LIBS}" && "${BUILD_SHARED_LIBS}" == "ON" ]]; then
CMAKE_OPTIONS+=("-DBUILD_SHARED_LIBS=ON")
echo "BUILD_SHARED_LIBS is set to: ON"
else
CMAKE_OPTIONS+=("-DBUILD_SHARED_LIBS=OFF")
echo "BUILD_SHARED_LIBS is set to: OFF"
fi
CMAKE_OPTIONS+=("-DCMAKE_POSITION_INDEPENDENT_CODE=ON")

cd "${BUILD_DIR}"
rm -rf *
rm -rf ${INSTALL_TEST_DIR}/*

cmake "${CMAKE_OPTIONS[@]}" \
-DCMAKE_INSTALL_PREFIX=${INSTALL_TEST_DIR} \
-DOPENTELEMETRY_INSTALL=ON \
-DOPENTELEMETRY_EXTERNAL_COMPONENT_PATH=${SRC_DIR}/install/test/cmake/install_functions_test/components \
-DENABLE_COMPONENTS=OFF \
-DENABLE_EXAMPLES=OFF \
-DENABLE_TESTS=OFF \
-DENABLE_PREVIEW=OFF \
-C ${SRC_DIR}/test_common/cmake/all-options-abiv1.cmake \
"${SRC_DIR}"

cmake --build . "${CMAKE_BUILD_ARGS[@]}"
cmake --build . "${CMAKE_BUILD_ARGS[@]}" --target install
export LD_LIBRARY_PATH="${INSTALL_TEST_DIR}/lib:$LD_LIBRARY_PATH"

mkdir -p "${BUILD_DIR}/install_functions_test"
cd "${BUILD_DIR}/install_functions_test"
cmake "-DCMAKE_PREFIX_PATH=${INSTALL_TEST_DIR}" \
-S "${SRC_DIR}/install/test/cmake/install_functions_test"
ctest --output-on-failure
exit 0
elif [[ "$1" == "cmake.install.test" ]]; then
if [[ -n "${BUILD_SHARED_LIBS}" && "${BUILD_SHARED_LIBS}" == "ON" ]]; then
CMAKE_OPTIONS+=("-DBUILD_SHARED_LIBS=ON")
Expand Down
47 changes: 44 additions & 3 deletions cmake/find-package-support-functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@
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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if() re-dereferences an unquoted left operand that names a defined variable, so if(${_COMPONENT} IN_LIST ...) can take the wrong branch.

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})
Comment thread
dbarker marked this conversation as resolved.
list(APPEND _result ${${_replacement_var}})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it OK to change the order?

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 set the <package>_<component>_FOUND variable for requested
# deprecated component names that have a replacement component.
#-------------------------------------------------------------------------
function(set_deprecated_components_found requested_components_in)
foreach(_COMPONENT IN LISTS ${requested_components_in})
if(${_COMPONENT} IN_LIST OTEL_DEPRECATED_COMPONENTS_LIST)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to use a map-based approach here to avoid the $O(N^2)$ lookup cost?

set(_replacement_var "COMPONENT_${_COMPONENT}_REPLACEMENT")
if(DEFINED ${_replacement_var}
AND ${CMAKE_FIND_PACKAGE_NAME}_${${_replacement_var}}_FOUND)
set(${CMAKE_FIND_PACKAGE_NAME}_${_COMPONENT}_FOUND TRUE
CACHE BOOL "whether ${CMAKE_FIND_PACKAGE_NAME} deprecated component ${_COMPONENT} is found (via replacement ${${_replacement_var}})" FORCE)
endif()
endif()
endforeach()
endfunction()

#-------------------------------------------------------------------------
# Function to get installed components.
#-------------------------------------------------------------------------
Expand Down Expand Up @@ -33,7 +73,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 +83,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
57 changes: 51 additions & 6 deletions cmake/otel-install-functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -317,28 +317,43 @@ 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.
#
# TODO: add a DEPRECATED tag to support deprecated components that are still installed but will be removed in the future.
#
# 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>])
#-----------------------------------------------------------------------
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()

# TODO: Support deprecated components that still install their targets, and mark those targets deprecated during the deprecation window.
#
# if(_OTEL_ADD_COMP_DEPRECATED)
# 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 +393,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 +445,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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alias resolver is single-pass over the original request list: foreach(_COMPONENT IN LISTS ${requested_components_inout}) iterates the input, and the replacement is only list(APPEND)-ed to _result, so a replacement that is itself deprecated is never resolved further. That makes this a one-hop lookup rather than a resolve-to-final.

message(STATUS " Replacement: ${_REPLACEMENT_COMPONENT}")
string(APPEND OTEL_COMPONENTS_REPLACEMENTS_BLOCK
"set(COMPONENT_${_DEPRECATED_COMPONENT}_REPLACEMENT ${_REPLACEMENT_COMPONENT})\n")
else()
message(FATAL_ERROR " no DEPRECATED_NAME on an installed component was found for ${_DEPRECATED_COMPONENT} -- deprecating components with no replacement is not currently supported.")
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
Loading
Loading