diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 09123c7155..e29cced631 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -587,6 +587,31 @@ jobs: CXX_STANDARD: '23' run: ./ci/do_ci.sh cmake.c++23.stl.test + cmake_test_different_std_for_protobuf_and_otel_gcc: + name: CMake C++23 test with protobuf built with C++17 (GCC) + runs-on: ubuntu-latest + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + with: + egress-policy: audit + + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + submodules: 'recursive' + - name: setup + run: | + sudo -E ./ci/setup_ci_environment.sh + - name: install dependencies + env: + CXX_STANDARD: '17' + run: | + sudo -E ./ci/install_thirdparty.sh --install-dir /usr/local --tags-file install/cmake/third_party_latest --build-shared-libs "ON" --packages "zlib;abseil;protobuf;nlohmann-json;curl;grpc;googletest;benchmark" + - name: run tests + env: + CXX_STANDARD: '23' + run: ./ci/do_ci.sh cmake.different_std.test + cmake_otprotocol_test: name: CMake test (with otlp-exporter) runs-on: ubuntu-22.04 @@ -1044,6 +1069,31 @@ jobs: - name: run otprotocol test run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.with_async_export.test + # Test case where protobuf is built with C++17 and OpenTelemetry with C++20 on MSVC will trigger a Internal compiler error + # We can enable this test case when MSVC on github runner is upgraded. + # cmake_test_different_std_for_protobuf_and_otel_msvc: + # name: CMake C++20 test with protobuf built with C++17 (MSVC) + # runs-on: windows-2022 + # steps: + # - name: Harden the runner (Audit all outbound calls) + # uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + # with: + # egress-policy: audit + # + # - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + # with: + # submodules: 'recursive' + # - name: setup + # run: | + # ./ci/setup_windows_ci_environment.ps1 + # - name: install dependencies + # env: + # CXX_STANDARD: '17' + # run: | + # pwsh -File ./ci/install_thirdparty.ps1 --install-dir "$HOME/otel-third_party" --tags-file install/cmake/third_party_latest --build-type Debug --build-shared-libs "ON" --packages "zlib;abseil;protobuf;nlohmann-json;curl;grpc;googletest;benchmark" + # - name: run cmake test + # run: ./ci/do_ci.ps1 cmake.different_std.test + windows_bazel: name: Bazel Windows runs-on: windows-2022 diff --git a/ci/do_ci.ps1 b/ci/do_ci.ps1 index 82c70ce8ef..95c5c1013b 100644 --- a/ci/do_ci.ps1 +++ b/ci/do_ci.ps1 @@ -67,7 +67,7 @@ switch ($action) { cmake $SRC_DIR ` -DVCPKG_TARGET_TRIPLET=x64-windows ` -DOPENTELEMETRY_BUILD_DLL=1 ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -90,7 +90,7 @@ switch ($action) { -DCMAKE_CXX_STANDARD=20 ` -DVCPKG_TARGET_TRIPLET=x64-windows ` -DOPENTELEMETRY_BUILD_DLL=1 ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -208,7 +208,7 @@ switch ($action) { "-C $SRC_DIR/test_common/cmake/all-options-abiv1-preview.cmake" ` -DWITH_OPENTRACING=OFF ` -DVCPKG_TARGET_TRIPLET=x64-windows ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -270,6 +270,35 @@ switch ($action) { exit $exit } } + "cmake.different_std.test" { + cd "$BUILD_DIR" + cmake $SRC_DIR ` + "-DCMAKE_PREFIX_PATH=$HOME/otel-third_party" ` + "-DCMAKE_FIND_ROOT_PATH=$HOME/otel-third_party" ` + -DCMAKE_BUILD_TYPE=Debug ` + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON ` + -DWITH_ASYNC_EXPORT_PREVIEW=ON ` + -DWITH_STL=CXX23 ` + -DCMAKE_CXX_STANDARD=23 ` + -DCMAKE_CXX_STANDARD_REQUIRED=ON ` + -DWITH_OTLP_GRPC=ON ` + -DWITH_OTLP_HTTP=ON ` + -DWITH_OTLP_FILE=ON + $exit = $LASTEXITCODE + if ($exit -ne 0) { + exit $exit + } + cmake --build . -j $nproc --config Debug + $exit = $LASTEXITCODE + if ($exit -ne 0) { + exit $exit + } + ctest -C Debug + $exit = $LASTEXITCODE + if ($exit -ne 0) { + exit $exit + } + } "cmake.build_example_plugin" { cd "$BUILD_DIR" cmake $SRC_DIR ` @@ -316,21 +345,22 @@ switch ($action) { cd "$BUILD_DIR" if (Test-Path Env:\CXX_STANDARD) { - $CXX_STANDARD = [int](Get-Item Env:\CXX_STANDARD).Value - } else { - $CXX_STANDARD = 17 + $CXX_STANDARD = [int](Get-Item Env:\CXX_STANDARD).Value + } + else { + $CXX_STANDARD = 17 } if (-not $CXX_STANDARD) { - $CXX_STANDARD = 17 + $CXX_STANDARD = 17 } Write-Host "Using CXX_STANDARD: $CXX_STANDARD" $CMAKE_OPTIONS = @( - "-DCMAKE_CXX_STANDARD=$CXX_STANDARD", - "-DCMAKE_CXX_STANDARD_REQUIRED=ON", - "-DCMAKE_CXX_EXTENSIONS=OFF", - "-DVCPKG_TARGET_TRIPLET=x64-windows", - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_CXX_STANDARD=$CXX_STANDARD", + "-DCMAKE_CXX_STANDARD_REQUIRED=ON", + "-DCMAKE_CXX_EXTENSIONS=OFF", + "-DVCPKG_TARGET_TRIPLET=x64-windows", + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" ) cmake $SRC_DIR ` @@ -390,10 +420,10 @@ switch ($action) { 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" ` - -S "$SRC_DIR\install\test\cmake" + "-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" ` + "-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" ` + "-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" ` + -S "$SRC_DIR\install\test\cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -414,10 +444,10 @@ switch ($action) { Remove-Item -Recurse -Force "$INSTALL_TEST_DIR\*" $CMAKE_OPTIONS = @( - "-DCMAKE_CXX_STANDARD=17", - "-DVCPKG_TARGET_TRIPLET=x64-windows", - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake", - "-DOPENTELEMETRY_BUILD_DLL=1" + "-DCMAKE_CXX_STANDARD=17", + "-DVCPKG_TARGET_TRIPLET=x64-windows", + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake", + "-DOPENTELEMETRY_BUILD_DLL=1" ) cmake $SRC_DIR ` @@ -485,10 +515,10 @@ switch ($action) { 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" ` - -S "$SRC_DIR\install\test\cmake" + "-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" ` + "-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" ` + "-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" ` + -S "$SRC_DIR\install\test\cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 067913128e..505952aa15 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -333,6 +333,22 @@ elif [[ "$1" == "cmake.c++23.stl.test" ]]; then eval "$MAKE_COMMAND" make test exit 0 +elif [[ "$1" == "cmake.different_std.test" ]]; then + cd "${BUILD_DIR}" + rm -rf * + cmake "${CMAKE_OPTIONS[@]}" \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ + -DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS" \ + -DWITH_ASYNC_EXPORT_PREVIEW=ON \ + -DBUILD_SHARED_LIBS=ON \ + -DWITH_STL=CXX23 \ + -DWITH_OTLP_GRPC=ON \ + -DWITH_OTLP_HTTP=ON \ + -DWITH_OTLP_FILE=ON \ + "${SRC_DIR}" + eval "$MAKE_COMMAND" + make test + exit 0 elif [[ "$1" == "cmake.legacy.test" ]]; then cd "${BUILD_DIR}" rm -rf * diff --git a/ci/install_thirdparty.ps1 b/ci/install_thirdparty.ps1 new file mode 100644 index 0000000000..b0eb916f5f --- /dev/null +++ b/ci/install_thirdparty.ps1 @@ -0,0 +1,220 @@ +<# +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +.SYNOPSIS + Install OpenTelemetry C++ third-party dependencies using CMake. + +.DESCRIPTION + PowerShell counterpart to ci/install_thirdparty.sh. + + This script configures and builds the CMake project in install/cmake to + install third-party packages into a provided prefix. + +.PARAMETER --install-dir + Path where third-party packages will be installed (required). + +.PARAMETER --tags-file + File containing tags for third-party packages (optional). + +.PARAMETER --packages + Semicolon-separated list of packages to build (optional). Default installs all. + +.EXAMPLE + ./ci/install_thirdparty.ps1 --install-dir C:/third_party + +.EXAMPLE + ./ci/install_thirdparty.ps1 --install-dir C:/third_party --tags-file C:/tags.txt --packages "grpc;protobuf" +#> + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +function Show-Usage { + $scriptName = Split-Path -Leaf $PSCommandPath + Write-Host ('Usage: {0} --install-dir [--tags-file ] [--packages ";"]' -f $scriptName) + Write-Host " --install-dir Path where third-party packages will be installed (required)" + Write-Host " --tags-file File containing tags for third-party packages (optional)" + Write-Host ' --packages ";;..." Semicolon-separated list of packages to build (optional). Default installs all third-party packages.' + Write-Host ' --build-type CMake build type (optional)' + Write-Host ' --build-shared-libs Build shared libraries (optional)' + Write-Host " -h, --help Show this help message" +} + +function Invoke-External { + param( + [Parameter(Mandatory = $true)] + [string] $FilePath, + + [Parameter(Mandatory = $false)] + [string[]] $Arguments = @() + ) + + & $FilePath @Arguments + $exitCode = $LASTEXITCODE + if ($exitCode -ne 0) { + throw "Command failed (exit $exitCode): $FilePath $($Arguments -join ' ')" + } +} + +$ThirdpartyTagsFile = '' +$ThirdpartyPackages = '' +$ThirdpartyInstallDir = '' +$CmakeBuildType = '' +$CmakeBuildSharedLibs = '' + +# Match install_thirdparty.sh behavior: parse GNU-style args from $args. +for ($i = 0; $i -lt $args.Count; ) { + $a = [string]$args[$i] + + switch ($a) { + '--install-dir' { + if (($i + 1) -ge $args.Count -or ([string]$args[$i + 1]).StartsWith('--')) { + [Console]::Error.WriteLine('Error: --install-dir requires a value') + Show-Usage + exit 1 + } + $ThirdpartyInstallDir = [string]$args[$i + 1] + $i += 2 + continue + } + '--tags-file' { + if (($i + 1) -ge $args.Count -or ([string]$args[$i + 1]).StartsWith('--')) { + [Console]::Error.WriteLine('Error: --tags-file requires a value') + Show-Usage + exit 1 + } + $ThirdpartyTagsFile = [string]$args[$i + 1] + $i += 2 + continue + } + '--packages' { + if (($i + 1) -ge $args.Count -or ([string]$args[$i + 1]).StartsWith('--')) { + [Console]::Error.WriteLine('Error: --packages requires a value') + Show-Usage + exit 1 + } + $ThirdpartyPackages = [string]$args[$i + 1] + $i += 2 + continue + } + '--build-type' { + if (($i + 1) -ge $args.Count -or ([string]$args[$i + 1]).StartsWith('--')) { + [Console]::Error.WriteLine('Error: --build-type requires a value') + Show-Usage + exit 1 + } + $CmakeBuildType = [string]$args[$i + 1] + $i += 2 + continue + } + '--build-shared-libs' { + if (($i + 1) -ge $args.Count -or ([string]$args[$i + 1]).StartsWith('--')) { + [Console]::Error.WriteLine('Error: --build-shared-libs requires a value') + Show-Usage + exit 1 + } + $CmakeBuildSharedLibs = [string]$args[$i + 1] + $i += 2 + continue + } + '-h' { Show-Usage; exit 0 } + '--help' { Show-Usage; exit 0 } + default { + [Console]::Error.WriteLine(("Unknown option: {0}" -f $a)) + Show-Usage + exit 1 + } + } +} + +if ([string]::IsNullOrWhiteSpace($ThirdpartyInstallDir)) { + [Console]::Error.WriteLine('Error: --install-dir is a required argument.') + Show-Usage + exit 1 +} + +$SrcDir = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Definition) + +$CxxStandard = $env:CXX_STANDARD +if ([string]::IsNullOrWhiteSpace($CxxStandard)) { + $CxxStandard = '17' +} + +$TempRoot = $env:TEMP +if ([string]::IsNullOrWhiteSpace($TempRoot)) { + # Fallback if TEMP isn't set. + $TempRoot = [System.IO.Path]::GetTempPath() +} + +$ThirdpartyBuildDir = Join-Path $TempRoot 'otel-cpp-third-party-build' +if (Test-Path -LiteralPath $ThirdpartyBuildDir) { + Remove-Item -LiteralPath $ThirdpartyBuildDir -Recurse -Force +} + +if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) { + throw 'cmake was not found in PATH. Please install CMake and ensure it is available on PATH.' +} + +$CmakeSourceDir = Join-Path $SrcDir 'install' 'cmake' +if (-not (Test-Path -LiteralPath $CmakeSourceDir)) { + throw "CMake source directory not found: $CmakeSourceDir" +} + +$OtelcppProtoPath = $env:OTELCPP_PROTO_PATH +if ($null -eq $OtelcppProtoPath) { + $OtelcppProtoPath = '' +} + +$CmakeConfigureArgs = @( + '-S', $CmakeSourceDir, + '-B', $ThirdpartyBuildDir, + "-DCMAKE_INSTALL_PREFIX=$ThirdpartyInstallDir", + "-DCMAKE_CXX_STANDARD=$CxxStandard", + "-DOTELCPP_THIRDPARTY_TAGS_FILE=$ThirdpartyTagsFile", + "-DOTELCPP_PROTO_PATH=$OtelcppProtoPath", + "-DOTELCPP_THIRDPARTY_INSTALL_LIST=$ThirdpartyPackages" +) + +$parallel = [Math]::Max([Environment]::ProcessorCount, 1) + +$CmakeBuildArgs = @( + '--build', $ThirdpartyBuildDir, + '--clean-first', + '--parallel', $parallel +) + +if (-not [string]::IsNullOrWhiteSpace($CmakeBuildType)) { + $CmakeConfigureArgs += "-DCMAKE_BUILD_TYPE=$CmakeBuildType" + $CmakeBuildArgs += @('--config', $CmakeBuildType) +} + +if (-not [string]::IsNullOrWhiteSpace($CmakeBuildSharedLibs)) { + $CmakeConfigureArgs += "-DBUILD_SHARED_LIBS=$CmakeBuildSharedLibs" +} + +Invoke-External -FilePath 'cmake' -Arguments $CmakeConfigureArgs + +# Use CMake's cross-generator parallel flag. +Invoke-External -FilePath 'cmake' -Arguments $CmakeBuildArgs + +# Keep parity with the bash script (no-op on Windows). +if ($ThirdpartyInstallDir -eq '/usr/local') { + if (Get-Command ldconfig -ErrorAction SilentlyContinue) { + Invoke-External -FilePath 'ldconfig' -Arguments @() + } +} + +Write-Host 'Third-party packages installed successfully.' +Write-Host "-- THIRDPARTY_INSTALL_DIR: $ThirdpartyInstallDir" +Write-Host "-- THIRDPARTY_TAGS_FILE: $ThirdpartyTagsFile" +if ([string]::IsNullOrWhiteSpace($ThirdpartyPackages)) { + Write-Host '-- THIRDPARTY_PACKAGES: all' +} +else { + Write-Host "-- THIRDPARTY_PACKAGES: $ThirdpartyPackages" +} +Write-Host "-- CXX_STANDARD: $CxxStandard" +if (-not [string]::IsNullOrWhiteSpace($CmakeBuildType)) { + Write-Host "-- CMAKE_BUILD_TYPE: $CmakeBuildType" +} diff --git a/ci/install_thirdparty.sh b/ci/install_thirdparty.sh index 7c23bcbb2b..9ddb74ac27 100755 --- a/ci/install_thirdparty.sh +++ b/ci/install_thirdparty.sh @@ -10,13 +10,17 @@ usage() { echo " --install-dir Path where third-party packages will be installed (required)" echo " --tags-file File containing tags for third-party packages (optional)" echo " --packages \";;...\" Semicolon-separated list of packages to build (optional). Default installs all third-party packages." + echo " --build-type CMake build type (optional)" + echo " --build-shared-libs Build shared libraries (optional)" echo " -h, --help Show this help message" } THIRDPARTY_TAGS_FILE="" THIRDPARTY_PACKAGES="" -SRC_DIR="$(pwd)" +SRC_DIR="$(cd "$(dirname "$0")/.." && pwd)" THIRDPARTY_INSTALL_DIR="" +CMAKE_BUILD_TYPE="" +CMAKE_BUILD_SHARED_LIBS="" while [[ $# -gt 0 ]]; do case $1 in @@ -47,6 +51,24 @@ while [[ $# -gt 0 ]]; do THIRDPARTY_PACKAGES="$2" shift 2 ;; + --build-type) + if [ -z "$2" ] || [[ "$2" == --* ]]; then + echo "Error: --build-type requires a value" >&2 + usage + exit 1 + fi + CMAKE_BUILD_TYPE="$2" + shift 2 + ;; + --build-shared-libs) + if [ -z "$2" ] || [[ "$2" == --* ]]; then + echo "Error: --build-shared-libs requires a value" >&2 + usage + exit 1 + fi + CMAKE_BUILD_SHARED_LIBS="$2" + shift 2 + ;; -h|--help) usage exit 0 @@ -75,14 +97,31 @@ if [ -d "${THIRDPARTY_BUILD_DIR}" ]; then rm -rf "${THIRDPARTY_BUILD_DIR}" fi -cmake -S "${SRC_DIR}/install/cmake" -B "${THIRDPARTY_BUILD_DIR}" \ - "-DCMAKE_INSTALL_PREFIX=${THIRDPARTY_INSTALL_DIR}" \ - "-DCMAKE_CXX_STANDARD=${CXX_STANDARD}" \ - "-DOTELCPP_THIRDPARTY_TAGS_FILE=${THIRDPARTY_TAGS_FILE}" \ - "-DOTELCPP_PROTO_PATH=${OTELCPP_PROTO_PATH}" \ +CMAKE_CONFIGURE_ARGS=( + -S "${SRC_DIR}/install/cmake" -B "${THIRDPARTY_BUILD_DIR}" + "-DCMAKE_INSTALL_PREFIX=${THIRDPARTY_INSTALL_DIR}" + "-DCMAKE_CXX_STANDARD=${CXX_STANDARD}" + "-DOTELCPP_THIRDPARTY_TAGS_FILE=${THIRDPARTY_TAGS_FILE}" + "-DOTELCPP_PROTO_PATH=${OTELCPP_PROTO_PATH}" "-DOTELCPP_THIRDPARTY_INSTALL_LIST=${THIRDPARTY_PACKAGES}" +) -cmake --build "${THIRDPARTY_BUILD_DIR}" --clean-first -j"$(nproc)" +CMAKE_BUILD_ARGS=( + --build "${THIRDPARTY_BUILD_DIR}" --clean-first -j"$(nproc)" +) + +if [ -n "${CMAKE_BUILD_TYPE}" ]; then + CMAKE_CONFIGURE_ARGS+=("-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") + CMAKE_BUILD_ARGS+=("--config" "${CMAKE_BUILD_TYPE}") +fi + +if [ -n "${CMAKE_BUILD_SHARED_LIBS}" ]; then + CMAKE_CONFIGURE_ARGS+=("-DBUILD_SHARED_LIBS=${CMAKE_BUILD_SHARED_LIBS}") +fi + +cmake "${CMAKE_CONFIGURE_ARGS[@]}" + +cmake "${CMAKE_BUILD_ARGS[@]}" if [ "${THIRDPARTY_INSTALL_DIR}" = "/usr/local" ]; then ldconfig @@ -93,3 +132,6 @@ echo "-- THIRDPARTY_INSTALL_DIR: ${THIRDPARTY_INSTALL_DIR}" echo "-- THIRDPARTY_TAGS_FILE: ${THIRDPARTY_TAGS_FILE}" echo "-- THIRDPARTY_PACKAGES: ${THIRDPARTY_PACKAGES:-all}" echo "-- CXX_STANDARD: ${CXX_STANDARD}" +if [ -n "${CMAKE_BUILD_TYPE}" ]; then + echo "-- CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}" +fi diff --git a/cmake/opentelemetry-proto.cmake b/cmake/opentelemetry-proto.cmake index 648d21d2f2..09623d50e4 100644 --- a/cmake/opentelemetry-proto.cmake +++ b/cmake/opentelemetry-proto.cmake @@ -2,17 +2,21 @@ # SPDX-License-Identifier: Apache-2.0 # -# The dependency on opentelemetry-proto can be provided by order -# of decreasing priority, options are: +# 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 +# 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) +# 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 +# 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") +set(OPENTELEMETRY_PROTO_SUBMODULE + "${opentelemetry-cpp_SOURCE_DIR}/third_party/opentelemetry-proto") if(OTELCPP_PROTO_PATH) if(NOT EXISTS @@ -21,29 +25,32 @@ if(OTELCPP_PROTO_PATH) 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} + 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. + # 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} - ) + 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}") + 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}") + 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}") + string(REGEX + REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" "\\1" + opentelemetry-proto_VERSION "${opentelemetry-proto_GIT_TAG}") endif() FetchContent_MakeAvailable(opentelemetry-proto) @@ -191,9 +198,24 @@ endif() # opentelemetry_exporter_otlp_grpc_client as a static library. if(TARGET protobuf::libprotobuf) get_target_property(protobuf_lib_type protobuf::libprotobuf TYPE) + # On Windows, protobuf and abseil-cpp are built with C++17 by default, and the + # protobuf v31/v6.31 have a ABI compatibility issue for GlobalEmptyString when + # .pb.cc files are built with C++20 or higher. See + # https://github.com/open-telemetry/opentelemetry-cpp/pull/3800 for details. + if(MSVC) + if(DEFINED CMAKE_CXX_STANDARD + AND CMAKE_CXX_STANDARD GREATER_EQUAL 20 + AND (Protobuf_VERSION_MAJOR EQUAL 31 OR Protobuf_VERSION MATCHES + "31\\..*")) + set(protobuf_lib_compile_features_cxx_std 17) + message( + STATUS + "protobuf::libprotobuf $(Protobuf_VERSION) detected and we force set CXX_STANDARD to 17 for .pb.cc files." + ) + endif() + endif() 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)$") diff --git a/cmake/tools.cmake b/cmake/tools.cmake index 43ac5156d4..4fc60187f0 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -15,12 +15,19 @@ if(NOT PATCH_PROTOBUF_SOURCES_OPTIONS_SET) if(MSVC) unset(PATCH_PROTOBUF_SOURCES_OPTIONS CACHE) set(PATCH_PROTOBUF_SOURCES_OPTIONS + /wd4100 /wd4244 /wd4251 /wd4267 /wd4309 /wd4668 + /wd4702 + /wd4715 + /wd4800 + /wd4090 /wd4946 + /wd4996 + /wd5054 /wd6001 /wd6244 /wd6246) @@ -43,8 +50,15 @@ if(NOT PATCH_PROTOBUF_SOURCES_OPTIONS_SET) unset(PATCH_PROTOBUF_SOURCES_OPTIONS CACHE) include(CheckCXXCompilerFlag) check_append_cxx_compiler_flag( - PATCH_PROTOBUF_SOURCES_OPTIONS -Wno-type-limits - -Wno-deprecated-declarations -Wno-unused-parameter) + PATCH_PROTOBUF_SOURCES_OPTIONS + -Wno-type-limits + -Wno-sign-compare + -Wno-sign-conversion + -Wno-shadow + -Wno-uninitialized + -Wno-conversion + -Wno-deprecated-declarations + -Wno-unused-parameter) endif() set(PATCH_PROTOBUF_SOURCES_OPTIONS_SET TRUE) if(PATCH_PROTOBUF_SOURCES_OPTIONS) @@ -56,41 +70,121 @@ if(NOT PATCH_PROTOBUF_SOURCES_OPTIONS_SET) endif() function(patch_protobuf_sources) - if(PATCH_PROTOBUF_SOURCES_OPTIONS) - foreach(PROTO_SRC ${ARGN}) - unset(PROTO_SRC_OPTIONS) - get_source_file_property(PROTO_SRC_OPTIONS ${PROTO_SRC} COMPILE_OPTIONS) - if(PROTO_SRC_OPTIONS) - list(APPEND PROTO_SRC_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + if(protobuf_lib_compile_features_cxx_std) + if(MSVC) + set(__additional_cxx_standard + "/std:c++${protobuf_lib_compile_features_cxx_std}") + else() + set(__additional_cxx_standard + "-std=c++${protobuf_lib_compile_features_cxx_std}") + endif() + endif() + + foreach(PROTO_SRC ${ARGN}) + unset(PROTO_SRC_OPTIONS) + set(__proto_src_options_changed FALSE) + get_source_file_property(PROTO_SRC_OPTIONS ${PROTO_SRC} COMPILE_OPTIONS) + if(PROTO_SRC_OPTIONS) + set(__need_cxx_standard TRUE) + if(NOT protobuf_lib_compile_features_cxx_std + OR PROTO_SRC_OPTIONS MATCHES + "(/std:|-std=)(c|gnu)\\+\\+${protobuf_lib_compile_features_cxx_std}" + ) + set(__need_cxx_standard FALSE) else() - set(PROTO_SRC_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + if(MSVC) + string(REGEX REPLACE "/std:c\\+\\+[0-9a-zA-Z_]+" "" PROTO_SRC_OPTIONS + "${PROTO_SRC_OPTIONS}") + endif() + string(REGEX REPLACE "-std=(c|gnu)\\+\\+[0-9a-zA-Z_]+" "" + PROTO_SRC_OPTIONS "${PROTO_SRC_OPTIONS}") + set(__need_cxx_standard TRUE) + endif() + + foreach(TEST_OPTION ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + if(NOT "${TEST_OPTION}" IN_LIST PROTO_SRC_OPTIONS) + list(APPEND PROTO_SRC_OPTIONS "${TEST_OPTION}") + set(__proto_src_options_changed TRUE) + endif() + endforeach() + if(__need_cxx_standard) + list(APPEND PROTO_SRC_OPTIONS "${__additional_cxx_standard}") + set(__proto_src_options_changed TRUE) + endif() + else() + set(PROTO_SRC_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + if(__additional_cxx_standard) + list(APPEND PROTO_SRC_OPTIONS "${__additional_cxx_standard}") endif() + set(__proto_src_options_changed TRUE) + endif() + if(__proto_src_options_changed) set_source_files_properties( ${PROTO_SRC} PROPERTIES COMPILE_OPTIONS "${PROTO_SRC_OPTIONS}") - endforeach() - unset(PROTO_SRC) - unset(PROTO_SRC_OPTIONS) - endif() + endif() + endforeach() endfunction() function(patch_protobuf_targets) - if(PATCH_PROTOBUF_SOURCES_OPTIONS) + if(protobuf_lib_compile_features_cxx_std) foreach(PROTO_TARGET ${ARGN}) - unset(PROTO_TARGET_OPTIONS) - get_target_property(PROTO_TARGET_OPTIONS ${PROTO_TARGET} COMPILE_OPTIONS) - if(PROTO_TARGET_OPTIONS) - list(APPEND PROTO_TARGET_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + set_target_properties( + ${PROTO_TARGET} PROPERTIES CXX_STANDARD + ${protobuf_lib_compile_features_cxx_std}) + endforeach() + + if(MSVC) + set(__additional_cxx_standard + "/std:c++${protobuf_lib_compile_features_cxx_std}") + else() + set(__additional_cxx_standard + "-std=c++${protobuf_lib_compile_features_cxx_std}") + endif() + endif() + + foreach(PROTO_TARGET ${ARGN}) + set(__proto_target_options_changed FALSE) + get_target_property(PROTO_TARGET_OPTIONS ${PROTO_TARGET} COMPILE_OPTIONS) + if(PROTO_TARGET_OPTIONS) + set(__need_cxx_standard TRUE) + if(NOT protobuf_lib_compile_features_cxx_std + OR PROTO_TARGET_OPTIONS MATCHES + "(/std:|-std=)(c|gnu)\\+\\+${protobuf_lib_compile_features_cxx_std}" + ) + set(__need_cxx_standard FALSE) else() - set(PROTO_TARGET_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + if(MSVC) + string(REGEX REPLACE "/std:c\\+\\+[0-9a-zA-Z_]+" "" + PROTO_TARGET_OPTIONS "${PROTO_TARGET_OPTIONS}") + endif() + string(REGEX REPLACE "-std=(c|gnu)\\+\\+[0-9a-zA-Z_]+" "" + PROTO_TARGET_OPTIONS "${PROTO_TARGET_OPTIONS}") + set(__need_cxx_standard TRUE) endif() + foreach(TEST_OPTION ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + if(NOT "${TEST_OPTION}" IN_LIST PROTO_TARGET_OPTIONS) + list(APPEND PROTO_TARGET_OPTIONS "${TEST_OPTION}") + set(__proto_target_options_changed TRUE) + endif() + endforeach() + if(__need_cxx_standard) + list(APPEND PROTO_TARGET_OPTIONS "${__additional_cxx_standard}") + set(__proto_target_options_changed TRUE) + endif() + else() + set(PROTO_TARGET_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS}) + if(__additional_cxx_standard) + list(APPEND PROTO_TARGET_OPTIONS "${__additional_cxx_standard}") + endif() + set(__proto_target_options_changed TRUE) + endif() + if(__proto_target_options_changed) set_target_properties( ${PROTO_TARGET} PROPERTIES COMPILE_OPTIONS "${PROTO_TARGET_OPTIONS}") - endforeach() - unset(PROTO_TARGET) - unset(PROTO_TARGET_OPTIONS) - endif() + endif() + endforeach() endfunction() function(project_build_tools_get_imported_location OUTPUT_VAR_NAME TARGET_NAME) diff --git a/install/cmake/CMakeLists.txt b/install/cmake/CMakeLists.txt index 39babcf854..0768277d69 100644 --- a/install/cmake/CMakeLists.txt +++ b/install/cmake/CMakeLists.txt @@ -97,12 +97,17 @@ endif() set(CMAKE_OPTIONS "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" + "-DCMAKE_FIND_ROOT_PATH=${CMAKE_INSTALL_PREFIX}" "-DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}" "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" "-DCMAKE_CXX_STANDARD_REQUIRED=ON" "-DCMAKE_CXX_EXTENSIONS=OFF" "-DCMAKE_POSITION_INDEPENDENT_CODE=ON") +if(DEFINED CACHE{BUILD_SHARED_LIBS}) + list(APPEND CMAKE_OPTIONS "-DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}") +endif() + message(STATUS "Installing third-party packages....") message(STATUS " opentelemetry-cpp_SOURCE_DIR = ${OTELCPP_SOURCE_DIR}") message(STATUS " third-party packages = ${_THIRDPARTY_PACKAGE_LIST}")