From e29e971640be8d70bd1263a8277f7aa3b98b6362 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 26 Oct 2020 14:40:13 -0700 Subject: [PATCH 01/54] Using STD library for API surface --- .github/workflows/ci.yml | 566 +++---- .gitignore | 6 + .gitmodules | 25 +- CMakeLists.txt | 39 + api/CMakeLists.txt | 6 + .../opentelemetry/common/attribute_value.h | 39 +- .../opentelemetry/common/key_value_iterable.h | 18 + .../common/key_value_iterable_view.h | 1 - .../opentelemetry/nostd/function_ref.h | 14 + .../opentelemetry/nostd/mpark/variant.h | 1281 ++++++++++++++++ api/include/opentelemetry/nostd/shared_ptr.h | 25 +- api/include/opentelemetry/nostd/span.h | 34 +- api/include/opentelemetry/nostd/string_view.h | 44 +- api/include/opentelemetry/nostd/type_traits.h | 34 +- api/include/opentelemetry/nostd/unique_ptr.h | 28 +- api/include/opentelemetry/nostd/utility.h | 31 +- api/include/opentelemetry/nostd/variant.h | 1294 +---------------- api/include/opentelemetry/std/shared_ptr.h | 31 + api/include/opentelemetry/std/span.h | 76 + api/include/opentelemetry/std/string_view.h | 36 + api/include/opentelemetry/std/type_traits.h | 31 + api/include/opentelemetry/std/unique_ptr.h | 31 + api/include/opentelemetry/std/utility.h | 80 + api/include/opentelemetry/std/variant.h | 232 +++ api/include/opentelemetry/trace/span.h | 11 + api/test/context/CMakeLists.txt | 10 +- api/test/core/CMakeLists.txt | 11 +- api/test/metrics/CMakeLists.txt | 10 +- api/test/nostd/BUILD | 155 +- api/test/nostd/CMakeLists.txt | 10 +- api/test/nostd/shared_ptr_test.cc | 383 ++--- api/test/nostd/span_test.cc | 421 +++--- api/test/nostd/string_view_test.cc | 319 ++-- api/test/plugin/CMakeLists.txt | 11 +- api/test/trace/CMakeLists.txt | 11 +- api/test/trace/propagation/CMakeLists.txt | 10 +- ci/do_ci.sh | 1 + docs/abi-compatibility.md | 35 + docs/building-with-stdlib.md | 102 ++ examples/batch/CMakeLists.txt | 5 +- examples/metrics_simple/CMakeLists.txt | 2 +- examples/otlp/CMakeLists.txt | 7 +- examples/plugin/plugin/tracer.cc | 145 +- exporters/memory/CMakeLists.txt | 12 +- exporters/ostream/CMakeLists.txt | 16 +- exporters/otlp/CMakeLists.txt | 6 +- exporters/prometheus/test/CMakeLists.txt | 6 +- ext/test/zpages/CMakeLists.txt | 5 +- .../sdk/common/empty_attributes.h | 8 + .../opentelemetry/sdk/trace/attribute_utils.h | 27 +- .../opentelemetry/sdk/trace/span_data.h | 7 +- .../opentelemetry/sdk/trace/tracer_provider.h | 5 + sdk/src/common/BUILD | 61 +- sdk/src/common/CMakeLists.txt | 5 +- sdk/src/common/core.cc | 12 + sdk/src/trace/CMakeLists.txt | 3 +- sdk/src/trace/tracer_provider.cc | 79 +- sdk/test/common/CMakeLists.txt | 17 +- sdk/test/metrics/CMakeLists.txt | 10 +- sdk/test/trace/CMakeLists.txt | 16 +- tools/build-all.sh | 6 + tools/build-benchmark.cmd | 35 + tools/build-gtest.sh | 28 + tools/build-vs2015.cmd | 6 + tools/build-vs2017.cmd | 5 + tools/build-vs2019.cmd | 5 + tools/build.cmd | 74 + tools/build.sh | 76 + tools/download.cmd | 3 + tools/download.ps1 | 4 + tools/format.sh | 2 +- tools/install-vs-addons.cmd | 39 + tools/install_llvm-win32.ps1 | 8 + tools/install_llvm-win64.ps1 | 8 + tools/ports/benchmark/CONTROL | 5 + tools/ports/benchmark/portfile.cmake | 49 + tools/setup-buildtools-mac.sh | 2 + tools/setup-buildtools.cmd | 50 + tools/setup-buildtools.sh | 13 +- tools/vcvars.cmd | 86 ++ 80 files changed, 4125 insertions(+), 2335 deletions(-) create mode 100644 api/include/opentelemetry/nostd/mpark/variant.h create mode 100644 api/include/opentelemetry/std/shared_ptr.h create mode 100644 api/include/opentelemetry/std/span.h create mode 100644 api/include/opentelemetry/std/string_view.h create mode 100644 api/include/opentelemetry/std/type_traits.h create mode 100644 api/include/opentelemetry/std/unique_ptr.h create mode 100644 api/include/opentelemetry/std/utility.h create mode 100644 api/include/opentelemetry/std/variant.h create mode 100644 docs/abi-compatibility.md create mode 100644 docs/building-with-stdlib.md create mode 100644 sdk/src/common/core.cc create mode 100644 tools/build-all.sh create mode 100644 tools/build-benchmark.cmd create mode 100644 tools/build-gtest.sh create mode 100644 tools/build-vs2015.cmd create mode 100644 tools/build-vs2017.cmd create mode 100644 tools/build-vs2019.cmd create mode 100644 tools/build.cmd create mode 100644 tools/build.sh create mode 100644 tools/download.cmd create mode 100644 tools/download.ps1 create mode 100644 tools/install-vs-addons.cmd create mode 100644 tools/install_llvm-win32.ps1 create mode 100644 tools/install_llvm-win64.ps1 create mode 100644 tools/ports/benchmark/CONTROL create mode 100644 tools/ports/benchmark/portfile.cmake create mode 100644 tools/setup-buildtools.cmd create mode 100644 tools/vcvars.cmd diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb2bb26841..aaaf635f14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,246 +1,320 @@ -name: CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - cmake_test: - name: CMake test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - - name: run tests - run: ./ci/do_ci.sh cmake.test - - name: run prometheus exporter tests - run: ./ci/do_ci.sh cmake.exporter.prometheus.test - - cmake_gcc_48_test: - name: CMake gcc 4.8 - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_gcc48.sh - - name: setup cmake - run: | - sudo CC=/usr/bin/gcc-4.8 CXX=/usr/bin/g++-4.8 ./ci/setup_cmake.sh - - name: run tests - run: ./ci/do_ci.sh cmake.legacy.test - env: - CC: /usr/bin/gcc-4.8 - CXX: /usr/bin/g++-4.8 - - cmake_test_cxx20: - name: CMake C++20 test - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - - name: run tests - run: ./ci/do_ci.sh cmake.c++20.test - - plugin_test: - name: Plugin -> CMake - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - - name: run tests - run: ./ci/do_ci.sh cmake.test_example_plugin - - gcc_48_test: - name: Legacy Bazel - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - sudo ./ci/install_gcc48.sh - - name: run tests - run: ./ci/do_ci.sh bazel.legacy.test - env: - CC: /usr/bin/gcc-4.8 - - bazel_test: - name: Bazel - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.test - - bazel_valgrind: - name: Bazel valgrind - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.valgrind - - bazel_noexcept: - name: Bazel noexcept - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.noexcept - - bazel_asan: - name: Bazel asan config - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.asan - - bazel_tsan: - name: Bazel tsan config - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.tsan - - benchmark: - name: Benchmark - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: | - env BENCHMARK_DIR=/benchmark - ./ci/do_ci.sh benchmark - - name: Upload benchmark results - uses: actions/upload-artifact@v2 - with: - name: benchmark_reports - path: /home/runner/benchmark - - format: - name: Format - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: sudo ./ci/install_format_tools.sh - - name: run tests - run: ./ci/do_ci.sh format - - osx_test: - name: Bazel on MacOS - runs-on: macos-latest - steps: - - uses: actions/checkout@v2 - - name: run tests - run: ./ci/do_ci.sh bazel.test - - windows: - name: CMake -> exporter proto - runs-on: windows-2019 - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - ./ci/setup_windows_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - ./ci/install_windows_protobuf.ps1 - - name: run cmake test - run: ./ci/do_ci.ps1 cmake.test - - name: run otprotocol test - run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.test - - windows_bazel: - name: Bazel Windows - runs-on: windows-2019 - steps: - - uses: actions/checkout@v2 - - name: setup - run: ./ci/install_windows_bazelisk.ps1 - - name: run tests - run: ./ci/do_ci.ps1 bazel.build - - windows_plugin_test: - name: Plugin -> CMake Windows - runs-on: windows-2019 - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - ./ci/setup_windows_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: run tests - run: ./ci/do_ci.ps1 cmake.test_example_plugin - - code_coverage: - name: Code coverage - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - - name: run tests and generate report - run: ./ci/do_ci.sh code.coverage - - name: upload report - uses: codecov/codecov-action@v1 - with: - file: /home/runner/build/coverage.info - - docfx_check: - name: DocFX check - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - name: install docfx - run: choco install docfx -y - - name: run ./ci/docfx.cmd - shell: cmd - run: ./ci/docfx.cmd +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + cmake_test: + name: CMake test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + - name: run tests + run: ./ci/do_ci.sh cmake.test + - name: run prometheus exporter tests + run: ./ci/do_ci.sh cmake.exporter.prometheus.test + + cmake_gcc_48_test: + name: CMake gcc 4.8 + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_gcc48.sh + - name: setup cmake + run: | + sudo CC=/usr/bin/gcc-4.8 CXX=/usr/bin/g++-4.8 ./ci/setup_cmake.sh + - name: run tests + run: ./ci/do_ci.sh cmake.legacy.test + env: + CC: /usr/bin/gcc-4.8 + CXX: /usr/bin/g++-4.8 + + cmake_test_cxx20: + name: CMake C++20 test + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_ci_environment.sh + sudo ./ci/setup_cmake.sh + - name: run tests + run: ./ci/do_ci.sh cmake.c++20.test + + cmake_posix: + name: Build on ${{ matrix.os }} ${{ matrix.config }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + config: [release] + os: [ubuntu-18.04, ubuntu-20.04, macos-latest] + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: build + run: tools/build.sh ${{ matrix.config }} + + # TODO #1: add vs2015 + # TODO #2: consolidate cmake_[vs2015|vs2017|vs2019] into one matrix build + cmake_windows_vs2017: + name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + arch: [x64] + config: [release] + os: [windows-2016] + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: 'true' + - name: Setup build tools + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\setup-buildtools.cmd + - name: Build + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\build-vs2017.cmd ${{ matrix.config }} + + cmake_windows_vs2019: + name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + arch: [x64] + config: [release] + os: [windows-2019] + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: 'true' + - name: Setup build tools + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\setup-buildtools.cmd + - name: Build + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\build-vs2017.cmd ${{ matrix.config }} + + plugin_test: + name: Plugin -> CMake + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + - name: run tests + run: ./ci/do_ci.sh cmake.test_example_plugin + + gcc_48_test: + name: Legacy Bazel + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + sudo ./ci/install_gcc48.sh + - name: run tests + run: ./ci/do_ci.sh bazel.legacy.test + env: + CC: /usr/bin/gcc-4.8 + + bazel_test: + name: Bazel + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.test + + bazel_valgrind: + name: Bazel valgrind + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.valgrind + + bazel_noexcept: + name: Bazel noexcept + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.noexcept + + bazel_asan: + name: Bazel asan config + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.asan + + bazel_tsan: + name: Bazel tsan config + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.tsan + + bazel_osx: + name: Bazel on MacOS + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: run tests + run: ./ci/do_ci.sh bazel.test + + benchmark: + name: Benchmark + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: | + env BENCHMARK_DIR=/benchmark + ./ci/do_ci.sh benchmark + - name: Upload benchmark results + uses: actions/upload-artifact@v2 + with: + name: benchmark_reports + path: /home/runner/benchmark + + format: + name: Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: sudo ./ci/install_format_tools.sh + - name: run tests + run: ./ci/do_ci.sh format + + windows: + name: CMake -> exporter proto + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + ./ci/setup_windows_cmake.ps1 + ./ci/setup_windows_ci_environment.ps1 + ./ci/install_windows_protobuf.ps1 + - name: run cmake test + run: ./ci/do_ci.ps1 cmake.test + - name: run otprotocol test + run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.test + + windows_bazel: + name: Bazel Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + - name: setup + run: ./ci/install_windows_bazelisk.ps1 + - name: run tests + run: ./ci/do_ci.ps1 bazel.build + + windows_plugin_test: + name: Plugin -> CMake Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + ./ci/setup_windows_cmake.ps1 + ./ci/setup_windows_ci_environment.ps1 + - name: run tests + run: ./ci/do_ci.ps1 cmake.test_example_plugin + + code_coverage: + name: Code coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + - name: run tests and generate report + run: ./ci/do_ci.sh code.coverage + - name: upload report + uses: codecov/codecov-action@v1 + with: + file: /home/runner/build/coverage.info + + docfx_check: + name: DocFX check + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: install docfx + run: choco install docfx -y + - name: run ./ci/docfx.cmd + shell: cmd + run: ./ci/docfx.cmd diff --git a/.gitignore b/.gitignore index ae5b7926b2..360c37e288 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,9 @@ # Bazel files /bazel-* + +# Output directories +/out +/out.* +# Indicator that the tools were deployed +.buildtools diff --git a/.gitmodules b/.gitmodules index 94dac0ba74..5744efc614 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,22 @@ -[submodule "third_party/prometheus-cpp"] - path = third_party/prometheus-cpp - url = https://github.com/jupp0r/prometheus-cpp.git +[submodule "third_party/prometheus-cpp"] + path = third_party/prometheus-cpp + url = https://github.com/jupp0r/prometheus-cpp.git + +[submodule "tools/vcpkg"] + path = tools/vcpkg + url = https://github.com/Microsoft/vcpkg + branch = master + +[submodule "third_party/ms-gsl"] + path = third_party/ms-gsl + url = https://github.com/microsoft/GSL + branch = master + +[submodule "third_party/googletest"] + path = third_party/googletest + url = https://github.com/google/googletest + branch = master + +[submodule "third_party/benchmark"] + path = third_party/benchmark + url = https://github.com/google/benchmark diff --git a/CMakeLists.txt b/CMakeLists.txt index e9b7cbc24f..313657d5fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,45 @@ if(NOT DEFINED CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 11) endif() +option(WITH_STL "Whether to use Standard Library for C++latest features" OFF) + +option(WITH_ABSEIL "Whether to use Abseil for C++latest features" OFF) + +if(WITH_ABSEIL) + add_definitions(-DHAVE_ABSEIL) + find_package(absl CONFIG REQUIRED) + + # Abseil headers-only lib is needed for absl::variant to work vs2015. + # `nostd::mpark::variant` is not compiling in vs2015. + set(CORE_RUNTIME_LIBS absl::any absl::base absl::bits absl::city) + + # target_link_libraries(main PRIVATE absl::any absl::base absl::bits + # absl::city) +endif() + +if(WITH_STL) + + # Require at least C++17. C++20 is needed to avoid gsl::span + add_definitions(-DHAVE_CPP_STDLIB -DHAVE_GSL) + + # Ask for 20, but may get C++17 + set(CMAKE_CXX_STANDARD 20) + + # Guidelines Support Library path. Used if we are not on not get C++20. + # + # TODO: respect WITH_ABSEIL as alternate implementation of std::span + set(GSL_DIR third_party/ms-gsl) + include_directories(${GSL_DIR}/include) + + # Optimize for speed to reduce the hops + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS_SPEED "/O2") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} /Zc:__cplusplus ${CMAKE_CXX_FLAGS_SPEED}") + endif() + +endif() + option(WITH_OTPROTOCOL "Whether to include the OpenTelemetry Protocol in the SDK" OFF) diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index e446300a03..2f6eed51fb 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -12,3 +12,9 @@ install( if(BUILD_TESTING) add_subdirectory(test) endif() + +if(WITH_STL) + message("Building with standard library types...") +else() + message("Building with nostd types...") +endif() diff --git a/api/include/opentelemetry/common/attribute_value.h b/api/include/opentelemetry/common/attribute_value.h index e68b6d8bb1..3df800e187 100644 --- a/api/include/opentelemetry/common/attribute_value.h +++ b/api/include/opentelemetry/common/attribute_value.h @@ -10,20 +10,27 @@ OPENTELEMETRY_BEGIN_NAMESPACE namespace common { -using AttributeValue = nostd::variant, - nostd::span, - nostd::span, - nostd::span, - nostd::span, - nostd::span, - nostd::span>; +using AttributeValue = + nostd::variant, +#endif + nostd::span, + nostd::span, + nostd::span, + nostd::span, + nostd::span, + nostd::span, + nostd::span>; enum AttributeType { @@ -35,7 +42,9 @@ enum AttributeType TYPE_DOUBLE, TYPE_STRING, TYPE_CSTRING, - // TYPE_SPAN_BYTE, // TODO: not part of OT spec yet +#if HAVE_SPAN_BYTE + TYPE_SPAN_BYTE, +#endif TYPE_SPAN_BOOL, TYPE_SPAN_INT, TYPE_SPAN_INT64, diff --git a/api/include/opentelemetry/common/key_value_iterable.h b/api/include/opentelemetry/common/key_value_iterable.h index f4e4a92bc3..0742082e56 100644 --- a/api/include/opentelemetry/common/key_value_iterable.h +++ b/api/include/opentelemetry/common/key_value_iterable.h @@ -30,5 +30,23 @@ class KeyValueIterable */ virtual size_t size() const noexcept = 0; }; + +// +// NULL object pattern empty iterable. +// +class NullKeyValueIterable : public KeyValueIterable +{ +public: + NullKeyValueIterable(){}; + + virtual bool ForEachKeyValue( + nostd::function_ref) const noexcept + { + return true; + }; + + virtual size_t size() const noexcept { return 0; } +}; + } // namespace common OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/common/key_value_iterable_view.h b/api/include/opentelemetry/common/key_value_iterable_view.h index a9b61cd87b..6aa300d933 100644 --- a/api/include/opentelemetry/common/key_value_iterable_view.h +++ b/api/include/opentelemetry/common/key_value_iterable_view.h @@ -33,7 +33,6 @@ struct is_key_value_iterable template class KeyValueIterableView final : public KeyValueIterable { - static_assert(detail::is_key_value_iterable::value, "Must be a key-value iterable"); public: explicit KeyValueIterableView(const T &container) noexcept : container_{&container} {} diff --git a/api/include/opentelemetry/nostd/function_ref.h b/api/include/opentelemetry/nostd/function_ref.h index de61c7040a..508cc53029 100644 --- a/api/include/opentelemetry/nostd/function_ref.h +++ b/api/include/opentelemetry/nostd/function_ref.h @@ -1,3 +1,17 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once #include diff --git a/api/include/opentelemetry/nostd/mpark/variant.h b/api/include/opentelemetry/nostd/mpark/variant.h new file mode 100644 index 0000000000..097bb57355 --- /dev/null +++ b/api/include/opentelemetry/nostd/mpark/variant.h @@ -0,0 +1,1281 @@ +// MPark.Variant +// +// Copyright Michael Park, 2015-2017 +// Copyright OpenTelemetry Authors, 2020 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file third_party/boost/LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#pragma once + +#include +#include +#include + +#include "opentelemetry/nostd/detail/all.h" +#include "opentelemetry/nostd/detail/dependent_type.h" +#include "opentelemetry/nostd/detail/find_index.h" +#include "opentelemetry/nostd/detail/functional.h" +#include "opentelemetry/nostd/detail/recursive_union.h" +#include "opentelemetry/nostd/detail/trait.h" +#include "opentelemetry/nostd/detail/type_pack_element.h" +#include "opentelemetry/nostd/detail/variant_alternative.h" +#include "opentelemetry/nostd/detail/variant_fwd.h" +#include "opentelemetry/nostd/detail/variant_size.h" +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/nostd/utility.h" +#include "opentelemetry/version.h" + +#define AUTO_RETURN(...) \ + ->decay_t { return __VA_ARGS__; } + +#define AUTO_REFREF_RETURN(...) \ + ->decltype((__VA_ARGS__)) \ + { \ + static_assert(std::is_reference::value, ""); \ + return __VA_ARGS__; \ + } + +#define DECLTYPE_AUTO_RETURN(...) \ + ->decltype(__VA_ARGS__) { return __VA_ARGS__; } + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +constexpr std::size_t variant_npos = static_cast(-1); + +class bad_variant_access : public std::exception +{ +public: + virtual const char *what() const noexcept override { return "bad_variant_access"; } +}; + +[[noreturn]] inline void throw_bad_variant_access() +{ +#if __EXCEPTIONS + throw bad_variant_access{}; +#else + std::terminate(); +#endif +} + +namespace detail +{ +namespace access +{ +struct base +{ + template + inline static constexpr auto get_alt(V &&v) +#ifdef _MSC_VER + AUTO_REFREF_RETURN(recursive_union::get_alt(std::forward(v).data_, in_place_index_t{})) +#else + AUTO_REFREF_RETURN(recursive_union::get_alt(data(std::forward(v)), in_place_index_t{})) +#endif +}; + +struct variant +{ + template + inline static constexpr auto get_alt(V &&v) + AUTO_REFREF_RETURN(base::get_alt(std::forward(v).impl_)) +}; +} // namespace access +} // namespace detail + +namespace detail +{ +namespace visitation +{ + +struct base +{ + template + using dispatch_result_t = decltype( + nostd::invoke(std::declval(), access::base::get_alt<0>(std::declval())...)); + + template + struct expected + { + template + inline static constexpr bool but_got() + { + return std::is_same::value; + } + }; + + template + struct visit_return_type_check + { + static_assert(expected::template but_got(), + "`visit` requires the visitor to have a single return type"); + + template + inline static constexpr auto invoke(Visitor &&visitor, Alts &&... alts) + DECLTYPE_AUTO_RETURN(nostd::invoke(std::forward(visitor), + std::forward(alts)...)) + }; + + template + inline static constexpr const T &at(const T &elem) noexcept + { + return elem; + } + + template + inline static constexpr const remove_all_extents_t &at(const std::array &elems, + std::size_t i, + Is... is) noexcept + { + return at(elems[i], is...); + } + + template + inline static constexpr std::array, sizeof...(Fs) + 1> make_farray(F &&f, Fs &&... fs) + { + return {{std::forward(f), std::forward(fs)...}}; + } + + template + struct make_fmatrix_impl + { + + template + inline static constexpr dispatch_result_t dispatch(F &&f, Vs &&... vs) + { + using Expected = dispatch_result_t; + using Actual = decltype( + nostd::invoke(std::forward(f), access::base::get_alt(std::forward(vs))...)); + return visit_return_type_check::invoke( + std::forward(f), access::base::get_alt(std::forward(vs))...); + } + + template + struct impl; + + template + struct impl> + { + inline constexpr auto operator()() const AUTO_RETURN(&dispatch) + }; + + template + struct impl, Ls...> + { + inline constexpr auto operator()() const + AUTO_RETURN(make_farray(impl, Ls...>{}()...)) + }; + }; + + template + inline static constexpr auto make_fmatrix() AUTO_RETURN( + typename make_fmatrix_impl:: + template impl, make_index_sequence::size()>...>{}()) + + template + struct make_fdiagonal_impl + { + template + inline static constexpr dispatch_result_t dispatch(F &&f, Vs &&... vs) + { + using Expected = dispatch_result_t; + using Actual = decltype( + nostd::invoke(std::forward(f), access::base::get_alt(std::forward(vs))...)); + return visit_return_type_check::invoke( + std::forward(f), access::base::get_alt(std::forward(vs))...); + } + + template + inline static constexpr auto impl(index_sequence) + AUTO_RETURN(make_farray(&dispatch...)) + }; + + template + inline static constexpr auto make_fdiagonal() + -> decltype(make_fdiagonal_impl::impl(make_index_sequence::size()>{})) + { + static_assert(all<(decay_t::size() == decay_t::size())...>::value, + "all of the variants must be the same size."); + return make_fdiagonal_impl::impl(make_index_sequence::size()>{}); + } +}; + +#if !defined(_MSC_VER) || _MSC_VER >= 1910 +template +using fmatrix_t = decltype(base::make_fmatrix()); + +template +struct fmatrix +{ + static constexpr fmatrix_t value = base::make_fmatrix(); +}; + +template +constexpr fmatrix_t fmatrix::value; + +template +using fdiagonal_t = decltype(base::make_fdiagonal()); + +template +struct fdiagonal +{ + static constexpr fdiagonal_t value = base::make_fdiagonal(); +}; + +template +constexpr fdiagonal_t fdiagonal::value; +#endif + +struct alt +{ + template + inline static constexpr auto visit_alt(Visitor &&visitor, Vs &&... vs) DECLTYPE_AUTO_RETURN( + base::at(base::make_fmatrix(vs)))...>(), + vs.index()...)(std::forward(visitor), as_base(std::forward(vs))...)) + + template + inline static constexpr auto visit_alt_at(std::size_t index, Visitor &&visitor, Vs &&... vs) + DECLTYPE_AUTO_RETURN(base::at( + base::make_fdiagonal(vs)))...>(), + index)(std::forward(visitor), as_base(std::forward(vs))...)) +}; + +struct variant +{ +private: + template + struct visitor + { + template + inline static constexpr bool does_not_handle() + { + return nostd::is_invocable::value; + } + }; + + template + struct visit_exhaustiveness_check + { + static_assert(visitor::template does_not_handle(), + "`visit` requires the visitor to be exhaustive."); + + inline static constexpr auto invoke(Visitor &&visitor, Values &&... values) + DECLTYPE_AUTO_RETURN(nostd::invoke(std::forward(visitor), + std::forward(values)...)) + }; + + template + struct value_visitor + { + Visitor &&visitor_; + + template + inline constexpr auto operator()(Alts &&... alts) const DECLTYPE_AUTO_RETURN( + visit_exhaustiveness_check(alts).value))...>::invoke( + std::forward(visitor_), + std::forward(alts).value...)) + }; + + template + inline static constexpr auto make_value_visitor(Visitor &&visitor) + AUTO_RETURN(value_visitor{std::forward(visitor)}) + + public + : template + inline static constexpr auto visit_alt(Visitor &&visitor, Vs &&... vs) + DECLTYPE_AUTO_RETURN(alt::visit_alt(std::forward(visitor), + std::forward(vs).impl_...)) + + template + inline static constexpr auto visit_alt_at(std::size_t index, + Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN(alt::visit_alt_at(index, + std::forward(visitor), + std::forward(vs).impl_...)) + + template + inline static constexpr auto visit_value(Visitor &&visitor, Vs &&... vs) + DECLTYPE_AUTO_RETURN( + visit_alt(make_value_visitor(std::forward(visitor)), + std::forward(vs)...)) + + template + inline static constexpr auto visit_value_at(std::size_t index, + Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN(visit_alt_at( + index, + make_value_visitor(std::forward(visitor)), + std::forward(vs)...)) +}; +} // namespace visitation + +template +using index_t = typename std::conditional< + sizeof...(Ts) < (std::numeric_limits::max)(), + unsigned char, + typename std::conditional::max)(), + unsigned short, + unsigned int>::type>::type; + +template +class base +{ +public: + inline explicit constexpr base(valueless_t tag) noexcept + : data_(tag), index_(static_cast>(-1)) + {} + + template + inline explicit constexpr base(in_place_index_t, Args &&... args) + : data_(in_place_index_t{}, std::forward(args)...), index_(I) + {} + + inline constexpr bool valueless_by_exception() const noexcept + { + return index_ == static_cast>(-1); + } + + inline constexpr std::size_t index() const noexcept + { + return valueless_by_exception() ? variant_npos : index_; + } + +protected: + using data_t = recursive_union; + + friend inline constexpr base &as_base(base &b) { return b; } + friend inline constexpr const base &as_base(const base &b) { return b; } + friend inline constexpr base &&as_base(base &&b) { return std::move(b); } + friend inline constexpr const base &&as_base(const base &&b) { return std::move(b); } + + friend inline constexpr data_t &data(base &b) { return b.data_; } + friend inline constexpr const data_t &data(const base &b) { return b.data_; } + friend inline constexpr data_t &&data(base &&b) { return std::move(b).data_; } + friend inline constexpr const data_t &&data(const base &&b) { return std::move(b).data_; } + + inline static constexpr std::size_t size() { return sizeof...(Ts); } + + data_t data_; + index_t index_; + + friend struct access::base; + friend struct visitation::base; +}; + +struct dtor +{ +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4100) +#endif + template + inline void operator()(Alt &alt) const noexcept + { + alt.~Alt(); + } +#ifdef _MSC_VER +# pragma warning(pop) +#endif +}; + +template +class destructor; + +#define OPENTELEMETRY_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \ + template \ + class destructor, destructible_trait> : public base \ + { \ + using super = base; \ + \ + public: \ + using super::super; \ + using super::operator=; \ + \ + destructor(const destructor &) = default; \ + destructor(destructor &&) = default; \ + definition destructor &operator=(const destructor &) = default; \ + destructor &operator=(destructor &&) = default; \ + \ + protected: \ + destroy \ + } + +OPENTELEMETRY_VARIANT_DESTRUCTOR( + Trait::TriviallyAvailable, ~destructor() = default; + , inline void destroy() noexcept { this->index_ = static_cast>(-1); }); + +OPENTELEMETRY_VARIANT_DESTRUCTOR( + Trait::Available, + ~destructor() { destroy(); }, + inline void destroy() noexcept { + if (!this->valueless_by_exception()) + { + visitation::alt::visit_alt(dtor{}, *this); + } + this->index_ = static_cast>(-1); + }); + +OPENTELEMETRY_VARIANT_DESTRUCTOR(Trait::Unavailable, ~destructor() = delete; + , inline void destroy() noexcept = delete;); + +#undef OPENTELEMETRY_VARIANT_DESTRUCTOR + +template +class constructor : public destructor +{ + using super = destructor; + +public: + using super::super; + using super::operator=; + +protected: + struct ctor + { + template + inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const + { + constructor::construct_alt(lhs_alt, std::forward(rhs_alt).value); + } + }; + + template + inline static T &construct_alt(alt &a, Args &&... args) + { + auto *result = ::new (static_cast(std::addressof(a))) + alt(in_place_t{}, std::forward(args)...); + return result->value; + } + + template + inline static void generic_construct(constructor &lhs, Rhs &&rhs) + { + lhs.destroy(); + if (!rhs.valueless_by_exception()) + { + visitation::alt::visit_alt_at(rhs.index(), ctor{}, lhs, std::forward(rhs)); + lhs.index_ = rhs.index_; + } + } +}; + +template +class move_constructor; + +#define OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \ + template \ + class move_constructor, move_constructible_trait> \ + : public constructor> \ + { \ + using super = constructor>; \ + \ + public: \ + using super::super; \ + using super::operator=; \ + \ + move_constructor(const move_constructor &) = default; \ + definition ~move_constructor() = default; \ + move_constructor &operator=(const move_constructor &) = default; \ + move_constructor &operator=(move_constructor &&) = default; \ + } + +OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR(Trait::TriviallyAvailable, + move_constructor(move_constructor &&that) = default;); + +OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR( + Trait::Available, + move_constructor(move_constructor &&that) noexcept( + all::value...>::value) + : move_constructor(valueless_t{}) { this->generic_construct(*this, std::move(that)); }); + +OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR(Trait::Unavailable, + move_constructor(move_constructor &&) = delete;); + +#undef OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR + +template +class copy_constructor; + +#define OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \ + template \ + class copy_constructor, copy_constructible_trait> \ + : public move_constructor> \ + { \ + using super = move_constructor>; \ + \ + public: \ + using super::super; \ + using super::operator=; \ + \ + definition copy_constructor(copy_constructor &&) = default; \ + ~copy_constructor() = default; \ + copy_constructor &operator=(const copy_constructor &) = default; \ + copy_constructor &operator=(copy_constructor &&) = default; \ + } + +OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR(Trait::TriviallyAvailable, + copy_constructor(const copy_constructor &that) = default;); + +OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR( + Trait::Available, copy_constructor(const copy_constructor &that) + : copy_constructor(valueless_t{}) { this->generic_construct(*this, that); }); + +OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR(Trait::Unavailable, + copy_constructor(const copy_constructor &) = delete;); + +#undef OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR + +template +class assignment : public copy_constructor +{ + using super = copy_constructor; + +public: + using super::super; + using super::operator=; + + template + inline /* auto & */ auto emplace(Args &&... args) + -> decltype(this->construct_alt(access::base::get_alt(*this), std::forward(args)...)) + { + this->destroy(); + auto &result = + this->construct_alt(access::base::get_alt(*this), std::forward(args)...); + this->index_ = I; + return result; + } + +protected: + template + struct assigner + { + template + inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const + { + self->assign_alt(this_alt, std::forward(that_alt).value); + } + assignment *self; + }; + + template + inline void assign_alt(alt &a, Arg &&arg) + { + if (this->index() == I) + { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4244) +#endif + a.value = std::forward(arg); +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } + else + { + struct + { + void operator()(std::true_type) const { this_->emplace(std::forward(arg_)); } + void operator()(std::false_type) const { this_->emplace(T(std::forward(arg_))); } + assignment *this_; + Arg &&arg_; + } impl{this, std::forward(arg)}; + impl(bool_constant < std::is_nothrow_constructible::value || + !std::is_nothrow_move_constructible::value > {}); + } + } + + template + inline void generic_assign(That &&that) + { + if (this->valueless_by_exception() && that.valueless_by_exception()) + { + // do nothing. + } + else if (that.valueless_by_exception()) + { + this->destroy(); + } + else + { + visitation::alt::visit_alt_at(that.index(), assigner{this}, *this, + std::forward(that)); + } + } +}; + +template +class move_assignment; + +#define OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \ + template \ + class move_assignment, move_assignable_trait> : public assignment> \ + { \ + using super = assignment>; \ + \ + public: \ + using super::super; \ + using super::operator=; \ + \ + move_assignment(const move_assignment &) = default; \ + move_assignment(move_assignment &&) = default; \ + ~move_assignment() = default; \ + move_assignment &operator=(const move_assignment &) = default; \ + definition \ + } + +OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT( + Trait::TriviallyAvailable, move_assignment &operator=(move_assignment &&that) = default;); + +OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT( + Trait::Available, + move_assignment & + operator=(move_assignment &&that) noexcept( + all<(std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value)...>::value) { + this->generic_assign(std::move(that)); + return *this; + }); + +OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT(Trait::Unavailable, + move_assignment &operator=(move_assignment &&) = delete;); + +#undef OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT + +template +class copy_assignment; + +#define OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \ + template \ + class copy_assignment, copy_assignable_trait> \ + : public move_assignment> \ + { \ + using super = move_assignment>; \ + \ + public: \ + using super::super; \ + using super::operator=; \ + \ + copy_assignment(const copy_assignment &) = default; \ + copy_assignment(copy_assignment &&) = default; \ + ~copy_assignment() = default; \ + definition copy_assignment &operator=(copy_assignment &&) = default; \ + } + +OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT( + Trait::TriviallyAvailable, copy_assignment &operator=(const copy_assignment &that) = default;); + +OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT( + Trait::Available, + copy_assignment & + operator=(const copy_assignment &that) { + this->generic_assign(that); + return *this; + }); + +OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT( + Trait::Unavailable, copy_assignment &operator=(const copy_assignment &) = delete;); + +#undef OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT +template +class impl : public copy_assignment> +{ + using super = copy_assignment>; + +public: + using super::super; + using super::operator=; + + impl(const impl &) = default; + impl(impl &&) = default; + ~impl() = default; + impl &operator=(const impl &) = default; + impl &operator=(impl &&) = default; + + template + inline void assign(Arg &&arg) + { + this->assign_alt(access::base::get_alt(*this), std::forward(arg)); + } + + inline void swap(impl &that) + { + if (this->valueless_by_exception() && that.valueless_by_exception()) + { + // do nothing. + } + else if (this->index() == that.index()) + { + visitation::alt::visit_alt_at(this->index(), swapper{}, *this, that); + } + else + { + impl *lhs = this; + impl *rhs = std::addressof(that); + if (lhs->move_nothrow() && !rhs->move_nothrow()) + { + std::swap(lhs, rhs); + } + impl tmp(std::move(*rhs)); +#if __EXCEPTIONS + // EXTENSION: When the move construction of `lhs` into `rhs` throws + // and `tmp` is nothrow move constructible then we move `tmp` back + // into `rhs` and provide the strong exception safety guarantee. + try + { + this->generic_construct(*rhs, std::move(*lhs)); + } + catch (...) + { + if (tmp.move_nothrow()) + { + this->generic_construct(*rhs, std::move(tmp)); + } + throw; + } +#else + this->generic_construct(*rhs, std::move(*lhs)); +#endif + this->generic_construct(*lhs, std::move(tmp)); + } + } + +private: + struct swapper + { + template + inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const + { + using std::swap; + swap(this_alt.value, that_alt.value); + } + }; + + inline constexpr bool move_nothrow() const + { + return this->valueless_by_exception() || + std::array{ + {std::is_nothrow_move_constructible::value...}}[this->index()]; + } +}; + +template +struct is_non_narrowing_convertible +{ + template + static std::true_type test(T(&&)[1]); + + template + static auto impl(int) -> decltype(test({std::declval()})); + + template + static auto impl(...) -> std::false_type; + + static constexpr bool value = decltype(impl(0))::value; +}; + +template ::value, + typename = void> +struct overload_leaf +{}; + +template +struct overload_leaf +{ + using impl = size_constant (*)(T); + operator impl() const { return nullptr; }; +}; + +template +struct overload_leaf, bool>::value + ? std::is_same, bool>::value + : +#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ >= 5 + is_non_narrowing_convertible::value +#else + std::is_convertible::value +#endif + >> +{ + using impl = size_constant (*)(T); + operator impl() const { return nullptr; }; +}; + +template +struct overload_impl +{ +private: + template + struct impl; + + template + struct impl> : overload_leaf... + {}; + +public: + using type = impl>; +}; + +template +using overload = typename overload_impl::type; + +template +using best_match = invoke_result_t, Arg>; + +template +struct is_in_place_index : std::false_type +{}; + +template +struct is_in_place_index> : std::true_type +{}; + +template +struct is_in_place_type : std::false_type +{}; + +template +struct is_in_place_type> : std::true_type +{}; +} // namespace detail + +template +class variant +{ + static_assert(0 < sizeof...(Ts), "variant must consist of at least one alternative."); + + static_assert(detail::all::value...>::value, + "variant can not have an array type as an alternative."); + + static_assert(detail::all::value...>::value, + "variant can not have a reference type as an alternative."); + + static_assert(detail::all::value...>::value, + "variant can not have a void type as an alternative."); + +public: + template , + enable_if_t::value, int> = 0> + inline constexpr variant() noexcept(std::is_nothrow_default_constructible::value) + : impl_(in_place_index_t<0>{}) + {} + + variant(const variant &) = default; + variant(variant &&) = default; + + template , + enable_if_t::value, int> = 0, + enable_if_t::value, int> = 0, + enable_if_t::value, int> = 0, + std::size_t I = detail::best_match::value, + typename T = detail::type_pack_element_t, + enable_if_t::value, int> = 0> + inline constexpr variant(Arg &&arg) noexcept(std::is_nothrow_constructible::value) + : impl_(in_place_index_t{}, std::forward(arg)) + {} + + template , + enable_if_t::value, int> = 0> + inline explicit constexpr variant(in_place_index_t, Args &&... args) noexcept( + std::is_nothrow_constructible::value) + : impl_(in_place_index_t{}, std::forward(args)...) + {} + + template < + std::size_t I, + typename Up, + typename... Args, + typename T = detail::type_pack_element_t, + enable_if_t &, Args...>::value, int> = 0> + inline explicit constexpr variant( + in_place_index_t, + std::initializer_list il, + Args &&... args) noexcept(std::is_nothrow_constructible &, + Args...>::value) + : impl_(in_place_index_t{}, il, std::forward(args)...) + {} + + template ::value, + enable_if_t::value, int> = 0> + inline explicit constexpr variant(in_place_type_t, Args &&... args) noexcept( + std::is_nothrow_constructible::value) + : impl_(in_place_index_t{}, std::forward(args)...) + {} + + template < + typename T, + typename Up, + typename... Args, + std::size_t I = detail::find_index_sfinae::value, + enable_if_t &, Args...>::value, int> = 0> + inline explicit constexpr variant( + in_place_type_t, + std::initializer_list il, + Args &&... args) noexcept(std::is_nothrow_constructible &, + Args...>::value) + : impl_(in_place_index_t{}, il, std::forward(args)...) + {} + + ~variant() = default; + + variant &operator=(const variant &) = default; + variant &operator=(variant &&) = default; + + template < + typename Arg, + enable_if_t, variant>::value, int> = 0, + std::size_t I = detail::best_match::value, + typename T = detail::type_pack_element_t, + enable_if_t<(std::is_assignable::value && std::is_constructible::value), + int> = 0> + inline variant &operator=(Arg &&arg) noexcept((std::is_nothrow_assignable::value && + std::is_nothrow_constructible::value)) + { + impl_.template assign(std::forward(arg)); + return *this; + } + + template , + enable_if_t::value, int> = 0> + inline T &emplace(Args &&... args) + { + return impl_.template emplace(std::forward(args)...); + } + + template < + std::size_t I, + typename Up, + typename... Args, + typename T = detail::type_pack_element_t, + enable_if_t &, Args...>::value, int> = 0> + inline T &emplace(std::initializer_list il, Args &&... args) + { + return impl_.template emplace(il, std::forward(args)...); + } + + template ::value, + enable_if_t::value, int> = 0> + inline T &emplace(Args &&... args) + { + return impl_.template emplace(std::forward(args)...); + } + + template < + typename T, + typename Up, + typename... Args, + std::size_t I = detail::find_index_sfinae::value, + enable_if_t &, Args...>::value, int> = 0> + inline T &emplace(std::initializer_list il, Args &&... args) + { + return impl_.template emplace(il, std::forward(args)...); + } + + inline constexpr bool valueless_by_exception() const noexcept + { + return impl_.valueless_by_exception(); + } + + inline constexpr std::size_t index() const noexcept { return impl_.index(); } + + template , Dummy>::value && + detail::dependent_type, Dummy>::value)...>::value, + int> = 0> + inline void swap(variant &that) noexcept( + detail::all<(std::is_nothrow_move_constructible::value && + is_nothrow_swappable::value)...>::value) + { + impl_.swap(that.impl_); + } + +private: + detail::impl impl_; + + friend struct detail::access::variant; + friend struct detail::visitation::variant; +}; + +template +inline constexpr bool holds_alternative(const variant &v) noexcept +{ + return v.index() == I; +} + +template +inline constexpr bool holds_alternative(const variant &v) noexcept +{ + return holds_alternative::value>(v); +} + +namespace detail +{ +template +struct generic_get_impl +{ + constexpr generic_get_impl(int) noexcept {} + + constexpr auto operator()(V &&v) const + AUTO_REFREF_RETURN(access::variant::get_alt(std::forward(v)).value) +}; + +template +inline constexpr auto generic_get(V &&v) AUTO_REFREF_RETURN(generic_get_impl( + holds_alternative(v) ? 0 : (throw_bad_variant_access(), 0))(std::forward(v))) +} // namespace detail + +template +inline constexpr variant_alternative_t> &get(variant &v) +{ + return detail::generic_get(v); +} + +template +inline constexpr variant_alternative_t> &&get(variant &&v) +{ + return detail::generic_get(std::move(v)); +} + +template +inline constexpr const variant_alternative_t> &get(const variant &v) +{ + return detail::generic_get(v); +} + +template +inline constexpr const variant_alternative_t> &&get(const variant &&v) +{ + return detail::generic_get(std::move(v)); +} + +template +inline constexpr T &get(variant &v) +{ + return get::value>(v); +} + +template +inline constexpr T &&get(variant &&v) +{ + return get::value>(std::move(v)); +} + +template +inline constexpr const T &get(const variant &v) +{ + return get::value>(v); +} + +template +inline constexpr const T &&get(const variant &&v) +{ + return get::value>(std::move(v)); +} + +namespace detail +{ + +template +inline constexpr /* auto * */ auto generic_get_if(V *v) noexcept AUTO_RETURN( + v &&holds_alternative(*v) ? std::addressof(access::variant::get_alt(*v).value) : nullptr) + +} // namespace detail + +template +inline constexpr add_pointer_t>> get_if( + variant *v) noexcept +{ + return detail::generic_get_if(v); +} + +template +inline constexpr add_pointer_t>> get_if( + const variant *v) noexcept +{ + return detail::generic_get_if(v); +} + +template +inline constexpr add_pointer_t get_if(variant *v) noexcept +{ + return get_if::value>(v); +} + +template +inline constexpr add_pointer_t get_if(const variant *v) noexcept +{ + return get_if::value>(v); +} + +namespace detail +{ +template +struct convert_to_bool +{ + template + inline constexpr bool operator()(Lhs &&lhs, Rhs &&rhs) const + { + static_assert(std::is_convertible, bool>::value, + "relational operators must return a type" + " implicitly convertible to bool"); + return nostd::invoke(RelOp{}, std::forward(lhs), std::forward(rhs)); + } +}; +} // namespace detail + +template +inline constexpr bool operator==(const variant &lhs, const variant &rhs) +{ + using detail::visitation::variant; + using equal_to = detail::convert_to_bool; + return lhs.index() == rhs.index() && (lhs.valueless_by_exception() || + variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs)); +} + +template +inline constexpr bool operator!=(const variant &lhs, const variant &rhs) +{ + using detail::visitation::variant; + using not_equal_to = detail::convert_to_bool; + return lhs.index() != rhs.index() || + (!lhs.valueless_by_exception() && + variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs)); +} + +template +inline constexpr bool operator<(const variant &lhs, const variant &rhs) +{ + using detail::visitation::variant; + using less = detail::convert_to_bool; + return !rhs.valueless_by_exception() && + (lhs.valueless_by_exception() || lhs.index() < rhs.index() || + (lhs.index() == rhs.index() && variant::visit_value_at(lhs.index(), less{}, lhs, rhs))); +} + +template +inline constexpr bool operator>(const variant &lhs, const variant &rhs) +{ + using detail::visitation::variant; + using greater = detail::convert_to_bool; + return !lhs.valueless_by_exception() && + (rhs.valueless_by_exception() || lhs.index() > rhs.index() || + (lhs.index() == rhs.index() && + variant::visit_value_at(lhs.index(), greater{}, lhs, rhs))); +} + +template +inline constexpr bool operator<=(const variant &lhs, const variant &rhs) +{ + using detail::visitation::variant; + using less_equal = detail::convert_to_bool; + return lhs.valueless_by_exception() || + (!rhs.valueless_by_exception() && + (lhs.index() < rhs.index() || + (lhs.index() == rhs.index() && + variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs)))); +} + +template +inline constexpr bool operator>=(const variant &lhs, const variant &rhs) +{ + using detail::visitation::variant; + using greater_equal = detail::convert_to_bool; + return rhs.valueless_by_exception() || + (!lhs.valueless_by_exception() && + (lhs.index() > rhs.index() || + (lhs.index() == rhs.index() && + variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs)))); +} + +struct monostate +{}; + +inline constexpr bool operator<(monostate, monostate) noexcept +{ + return false; +} + +inline constexpr bool operator>(monostate, monostate) noexcept +{ + return false; +} + +inline constexpr bool operator<=(monostate, monostate) noexcept +{ + return true; +} + +inline constexpr bool operator>=(monostate, monostate) noexcept +{ + return true; +} + +inline constexpr bool operator==(monostate, monostate) noexcept +{ + return true; +} + +inline constexpr bool operator!=(monostate, monostate) noexcept +{ + return false; +} + +namespace detail +{ + +template +inline constexpr bool all_of_impl(const std::array &bs, std::size_t idx) +{ + return idx >= N || (bs[idx] && all_of_impl(bs, idx + 1)); +} + +template +inline constexpr bool all_of(const std::array &bs) +{ + return all_of_impl(bs, 0); +} + +} // namespace detail + +template +inline constexpr auto visit(Visitor &&visitor, Vs &&... vs) DECLTYPE_AUTO_RETURN( + (detail::all_of(std::array{{!vs.valueless_by_exception()...}}) + ? (void)0 + : throw_bad_variant_access()), + detail::visitation::variant::visit_value(std::forward(visitor), + std::forward(vs)...)) template +inline auto swap(variant &lhs, variant &rhs) noexcept(noexcept(lhs.swap(rhs))) + -> decltype(lhs.swap(rhs)) +{ + lhs.swap(rhs); +} +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE + +#undef AUTO_RETURN + +#undef AUTO_REFREF_RETURN + +#undef DECLTYPE_AUTO_RETURN diff --git a/api/include/opentelemetry/nostd/shared_ptr.h b/api/include/opentelemetry/nostd/shared_ptr.h index 7d84b6f408..e7c2a464d2 100644 --- a/api/include/opentelemetry/nostd/shared_ptr.h +++ b/api/include/opentelemetry/nostd/shared_ptr.h @@ -1,8 +1,26 @@ -#pragma once +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -#include +#pragma once +#ifdef HAVE_CPP_STDLIB +# include "opentelemetry/std/shared_ptr.h" +#else +# include +# include +# include -#include "opentelemetry/version.h" +# include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd @@ -180,3 +198,4 @@ inline bool operator!=(std::nullptr_t, const shared_ptr &rhs) noexcept } } // namespace nostd OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/api/include/opentelemetry/nostd/span.h b/api/include/opentelemetry/nostd/span.h index f28a80cbbf..5b95010edd 100644 --- a/api/include/opentelemetry/nostd/span.h +++ b/api/include/opentelemetry/nostd/span.h @@ -1,14 +1,31 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once -#include -#include -#include -#include -#include -#include +#ifdef HAVE_CPP_STDLIB +# include "opentelemetry/std/span.h" +#else +# include +# include +# include +# include +# include +# include -#include "opentelemetry/nostd/utility.h" -#include "opentelemetry/version.h" +# include "opentelemetry/nostd/utility.h" +# include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd @@ -238,3 +255,4 @@ class span }; } // namespace nostd OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/api/include/opentelemetry/nostd/string_view.h b/api/include/opentelemetry/nostd/string_view.h index a5d65d00aa..4a5bdefa81 100644 --- a/api/include/opentelemetry/nostd/string_view.h +++ b/api/include/opentelemetry/nostd/string_view.h @@ -1,13 +1,30 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once -#include -#include -#include -#include -#include -#include +#ifdef HAVE_CPP_STDLIB +# include "opentelemetry/std/string_view.h" +#else +# include +# include +# include +# include +# include +# include -#include "opentelemetry/version.h" +# include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd @@ -58,11 +75,11 @@ class string_view { if (pos > length_) { -#if __EXCEPTIONS +# if __EXCEPTIONS throw std::out_of_range{"opentelemetry::nostd::string_view"}; -#else +# else std::terminate(); -#endif +# endif } n = (std::min)(n, length_ - pos); return string_view(data_ + pos, n); @@ -118,12 +135,12 @@ class string_view inline bool operator==(string_view lhs, string_view rhs) noexcept { return lhs.length() == rhs.length() && -#if _MSC_VER == 1900 +# if _MSC_VER == 1900 // Avoid SCL error in Visual Studio 2015 (std::memcmp(lhs.data(), rhs.data(), lhs.length()) == 0); -#else +# else std::equal(lhs.data(), lhs.data() + lhs.length(), rhs.data()); -#endif +# endif } inline bool operator==(string_view lhs, const std::string &rhs) noexcept @@ -192,3 +209,4 @@ struct hash } }; } // namespace std +#endif diff --git a/api/include/opentelemetry/nostd/type_traits.h b/api/include/opentelemetry/nostd/type_traits.h index a42f440df8..c1e4cfdf02 100644 --- a/api/include/opentelemetry/nostd/type_traits.h +++ b/api/include/opentelemetry/nostd/type_traits.h @@ -1,11 +1,28 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once -#include -#include +#ifdef HAVE_CPP_STDLIB +# include "opentelemetry/std/type_traits.h" +#else +# include +# include -#include "opentelemetry/config.h" -#include "opentelemetry/nostd/detail/void.h" -#include "opentelemetry/version.h" +# include "opentelemetry/config.h" +# include "opentelemetry/nostd/detail/void.h" +# include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd @@ -116,12 +133,12 @@ using is_nothrow_swappable = detail::swappable::is_nothrow_swappable struct is_trivially_copy_constructible { @@ -145,6 +162,7 @@ struct is_trivially_move_assignable { static constexpr bool value = __is_trivial(T); }; -#endif +# endif } // namespace nostd OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/api/include/opentelemetry/nostd/unique_ptr.h b/api/include/opentelemetry/nostd/unique_ptr.h index fc9a36aa7b..b0418891d0 100644 --- a/api/include/opentelemetry/nostd/unique_ptr.h +++ b/api/include/opentelemetry/nostd/unique_ptr.h @@ -1,11 +1,28 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once -#include -#include -#include -#include +#ifdef HAVE_CPP_STDLIB +# include "opentelemetry/std/unique_ptr.h" +#else +# include +# include +# include +# include -#include "opentelemetry/version.h" +# include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd @@ -166,3 +183,4 @@ bool operator!=(std::nullptr_t, const unique_ptr &rhs) noexcept } } // namespace nostd OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/api/include/opentelemetry/nostd/utility.h b/api/include/opentelemetry/nostd/utility.h index d7fa3bfc19..ae9197e714 100644 --- a/api/include/opentelemetry/nostd/utility.h +++ b/api/include/opentelemetry/nostd/utility.h @@ -1,12 +1,30 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once -#include -#include -#include +#ifdef HAVE_CPP_STDLIB +# include "opentelemetry/std/utility.h" +#else + +# include +# include +# include -#include "opentelemetry/nostd/detail/decay.h" -#include "opentelemetry/nostd/detail/invoke.h" -#include "opentelemetry/version.h" +# include "opentelemetry/nostd/detail/decay.h" +# include "opentelemetry/nostd/detail/invoke.h" +# include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd @@ -146,3 +164,4 @@ struct in_place_type_t }; } // namespace nostd OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/api/include/opentelemetry/nostd/variant.h b/api/include/opentelemetry/nostd/variant.h index 097bb57355..37281e1db6 100644 --- a/api/include/opentelemetry/nostd/variant.h +++ b/api/include/opentelemetry/nostd/variant.h @@ -1,1281 +1,33 @@ -// MPark.Variant +// Copyright 2020, OpenTelemetry Authors // -// Copyright Michael Park, 2015-2017 -// Copyright OpenTelemetry Authors, 2020 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at // -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file third_party/boost/LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #pragma once -#include -#include -#include - -#include "opentelemetry/nostd/detail/all.h" -#include "opentelemetry/nostd/detail/dependent_type.h" -#include "opentelemetry/nostd/detail/find_index.h" -#include "opentelemetry/nostd/detail/functional.h" -#include "opentelemetry/nostd/detail/recursive_union.h" -#include "opentelemetry/nostd/detail/trait.h" -#include "opentelemetry/nostd/detail/type_pack_element.h" -#include "opentelemetry/nostd/detail/variant_alternative.h" -#include "opentelemetry/nostd/detail/variant_fwd.h" -#include "opentelemetry/nostd/detail/variant_size.h" -#include "opentelemetry/nostd/type_traits.h" -#include "opentelemetry/nostd/utility.h" -#include "opentelemetry/version.h" - -#define AUTO_RETURN(...) \ - ->decay_t { return __VA_ARGS__; } - -#define AUTO_REFREF_RETURN(...) \ - ->decltype((__VA_ARGS__)) \ - { \ - static_assert(std::is_reference::value, ""); \ - return __VA_ARGS__; \ - } - -#define DECLTYPE_AUTO_RETURN(...) \ - ->decltype(__VA_ARGS__) { return __VA_ARGS__; } - +#ifdef HAVE_CPP_STDLIB +# include "opentelemetry/std/variant.h" +#elif defined(HAVE_ABSEIL) +// TODO: prefer `absl::variant` over `nostd::variant` since the latter does not compile with vs2015 +# include "absl/types/variant.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd { -constexpr std::size_t variant_npos = static_cast(-1); - -class bad_variant_access : public std::exception -{ -public: - virtual const char *what() const noexcept override { return "bad_variant_access"; } -}; - -[[noreturn]] inline void throw_bad_variant_access() -{ -#if __EXCEPTIONS - throw bad_variant_access{}; -#else - std::terminate(); -#endif -} - -namespace detail -{ -namespace access -{ -struct base -{ - template - inline static constexpr auto get_alt(V &&v) -#ifdef _MSC_VER - AUTO_REFREF_RETURN(recursive_union::get_alt(std::forward(v).data_, in_place_index_t{})) -#else - AUTO_REFREF_RETURN(recursive_union::get_alt(data(std::forward(v)), in_place_index_t{})) -#endif -}; - -struct variant -{ - template - inline static constexpr auto get_alt(V &&v) - AUTO_REFREF_RETURN(base::get_alt(std::forward(v).impl_)) -}; -} // namespace access -} // namespace detail - -namespace detail -{ -namespace visitation -{ - -struct base -{ - template - using dispatch_result_t = decltype( - nostd::invoke(std::declval(), access::base::get_alt<0>(std::declval())...)); - - template - struct expected - { - template - inline static constexpr bool but_got() - { - return std::is_same::value; - } - }; - - template - struct visit_return_type_check - { - static_assert(expected::template but_got(), - "`visit` requires the visitor to have a single return type"); - - template - inline static constexpr auto invoke(Visitor &&visitor, Alts &&... alts) - DECLTYPE_AUTO_RETURN(nostd::invoke(std::forward(visitor), - std::forward(alts)...)) - }; - - template - inline static constexpr const T &at(const T &elem) noexcept - { - return elem; - } - - template - inline static constexpr const remove_all_extents_t &at(const std::array &elems, - std::size_t i, - Is... is) noexcept - { - return at(elems[i], is...); - } - - template - inline static constexpr std::array, sizeof...(Fs) + 1> make_farray(F &&f, Fs &&... fs) - { - return {{std::forward(f), std::forward(fs)...}}; - } - - template - struct make_fmatrix_impl - { - - template - inline static constexpr dispatch_result_t dispatch(F &&f, Vs &&... vs) - { - using Expected = dispatch_result_t; - using Actual = decltype( - nostd::invoke(std::forward(f), access::base::get_alt(std::forward(vs))...)); - return visit_return_type_check::invoke( - std::forward(f), access::base::get_alt(std::forward(vs))...); - } - - template - struct impl; - - template - struct impl> - { - inline constexpr auto operator()() const AUTO_RETURN(&dispatch) - }; - - template - struct impl, Ls...> - { - inline constexpr auto operator()() const - AUTO_RETURN(make_farray(impl, Ls...>{}()...)) - }; - }; - - template - inline static constexpr auto make_fmatrix() AUTO_RETURN( - typename make_fmatrix_impl:: - template impl, make_index_sequence::size()>...>{}()) - - template - struct make_fdiagonal_impl - { - template - inline static constexpr dispatch_result_t dispatch(F &&f, Vs &&... vs) - { - using Expected = dispatch_result_t; - using Actual = decltype( - nostd::invoke(std::forward(f), access::base::get_alt(std::forward(vs))...)); - return visit_return_type_check::invoke( - std::forward(f), access::base::get_alt(std::forward(vs))...); - } - - template - inline static constexpr auto impl(index_sequence) - AUTO_RETURN(make_farray(&dispatch...)) - }; - - template - inline static constexpr auto make_fdiagonal() - -> decltype(make_fdiagonal_impl::impl(make_index_sequence::size()>{})) - { - static_assert(all<(decay_t::size() == decay_t::size())...>::value, - "all of the variants must be the same size."); - return make_fdiagonal_impl::impl(make_index_sequence::size()>{}); - } -}; - -#if !defined(_MSC_VER) || _MSC_VER >= 1910 -template -using fmatrix_t = decltype(base::make_fmatrix()); - -template -struct fmatrix -{ - static constexpr fmatrix_t value = base::make_fmatrix(); -}; - -template -constexpr fmatrix_t fmatrix::value; - -template -using fdiagonal_t = decltype(base::make_fdiagonal()); - -template -struct fdiagonal -{ - static constexpr fdiagonal_t value = base::make_fdiagonal(); -}; - -template -constexpr fdiagonal_t fdiagonal::value; -#endif - -struct alt -{ - template - inline static constexpr auto visit_alt(Visitor &&visitor, Vs &&... vs) DECLTYPE_AUTO_RETURN( - base::at(base::make_fmatrix(vs)))...>(), - vs.index()...)(std::forward(visitor), as_base(std::forward(vs))...)) - - template - inline static constexpr auto visit_alt_at(std::size_t index, Visitor &&visitor, Vs &&... vs) - DECLTYPE_AUTO_RETURN(base::at( - base::make_fdiagonal(vs)))...>(), - index)(std::forward(visitor), as_base(std::forward(vs))...)) -}; - -struct variant -{ -private: - template - struct visitor - { - template - inline static constexpr bool does_not_handle() - { - return nostd::is_invocable::value; - } - }; - - template - struct visit_exhaustiveness_check - { - static_assert(visitor::template does_not_handle(), - "`visit` requires the visitor to be exhaustive."); - - inline static constexpr auto invoke(Visitor &&visitor, Values &&... values) - DECLTYPE_AUTO_RETURN(nostd::invoke(std::forward(visitor), - std::forward(values)...)) - }; - - template - struct value_visitor - { - Visitor &&visitor_; - - template - inline constexpr auto operator()(Alts &&... alts) const DECLTYPE_AUTO_RETURN( - visit_exhaustiveness_check(alts).value))...>::invoke( - std::forward(visitor_), - std::forward(alts).value...)) - }; - - template - inline static constexpr auto make_value_visitor(Visitor &&visitor) - AUTO_RETURN(value_visitor{std::forward(visitor)}) - - public - : template - inline static constexpr auto visit_alt(Visitor &&visitor, Vs &&... vs) - DECLTYPE_AUTO_RETURN(alt::visit_alt(std::forward(visitor), - std::forward(vs).impl_...)) - - template - inline static constexpr auto visit_alt_at(std::size_t index, - Visitor &&visitor, - Vs &&... vs) - DECLTYPE_AUTO_RETURN(alt::visit_alt_at(index, - std::forward(visitor), - std::forward(vs).impl_...)) - - template - inline static constexpr auto visit_value(Visitor &&visitor, Vs &&... vs) - DECLTYPE_AUTO_RETURN( - visit_alt(make_value_visitor(std::forward(visitor)), - std::forward(vs)...)) - - template - inline static constexpr auto visit_value_at(std::size_t index, - Visitor &&visitor, - Vs &&... vs) - DECLTYPE_AUTO_RETURN(visit_alt_at( - index, - make_value_visitor(std::forward(visitor)), - std::forward(vs)...)) -}; -} // namespace visitation - -template -using index_t = typename std::conditional< - sizeof...(Ts) < (std::numeric_limits::max)(), - unsigned char, - typename std::conditional::max)(), - unsigned short, - unsigned int>::type>::type; - -template -class base -{ -public: - inline explicit constexpr base(valueless_t tag) noexcept - : data_(tag), index_(static_cast>(-1)) - {} - - template - inline explicit constexpr base(in_place_index_t, Args &&... args) - : data_(in_place_index_t{}, std::forward(args)...), index_(I) - {} - - inline constexpr bool valueless_by_exception() const noexcept - { - return index_ == static_cast>(-1); - } - - inline constexpr std::size_t index() const noexcept - { - return valueless_by_exception() ? variant_npos : index_; - } - -protected: - using data_t = recursive_union; - - friend inline constexpr base &as_base(base &b) { return b; } - friend inline constexpr const base &as_base(const base &b) { return b; } - friend inline constexpr base &&as_base(base &&b) { return std::move(b); } - friend inline constexpr const base &&as_base(const base &&b) { return std::move(b); } - - friend inline constexpr data_t &data(base &b) { return b.data_; } - friend inline constexpr const data_t &data(const base &b) { return b.data_; } - friend inline constexpr data_t &&data(base &&b) { return std::move(b).data_; } - friend inline constexpr const data_t &&data(const base &&b) { return std::move(b).data_; } - - inline static constexpr std::size_t size() { return sizeof...(Ts); } - - data_t data_; - index_t index_; - - friend struct access::base; - friend struct visitation::base; -}; - -struct dtor -{ -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4100) -#endif - template - inline void operator()(Alt &alt) const noexcept - { - alt.~Alt(); - } -#ifdef _MSC_VER -# pragma warning(pop) -#endif -}; - -template -class destructor; - -#define OPENTELEMETRY_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \ - template \ - class destructor, destructible_trait> : public base \ - { \ - using super = base; \ - \ - public: \ - using super::super; \ - using super::operator=; \ - \ - destructor(const destructor &) = default; \ - destructor(destructor &&) = default; \ - definition destructor &operator=(const destructor &) = default; \ - destructor &operator=(destructor &&) = default; \ - \ - protected: \ - destroy \ - } - -OPENTELEMETRY_VARIANT_DESTRUCTOR( - Trait::TriviallyAvailable, ~destructor() = default; - , inline void destroy() noexcept { this->index_ = static_cast>(-1); }); - -OPENTELEMETRY_VARIANT_DESTRUCTOR( - Trait::Available, - ~destructor() { destroy(); }, - inline void destroy() noexcept { - if (!this->valueless_by_exception()) - { - visitation::alt::visit_alt(dtor{}, *this); - } - this->index_ = static_cast>(-1); - }); - -OPENTELEMETRY_VARIANT_DESTRUCTOR(Trait::Unavailable, ~destructor() = delete; - , inline void destroy() noexcept = delete;); - -#undef OPENTELEMETRY_VARIANT_DESTRUCTOR - -template -class constructor : public destructor -{ - using super = destructor; - -public: - using super::super; - using super::operator=; - -protected: - struct ctor - { - template - inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const - { - constructor::construct_alt(lhs_alt, std::forward(rhs_alt).value); - } - }; - - template - inline static T &construct_alt(alt &a, Args &&... args) - { - auto *result = ::new (static_cast(std::addressof(a))) - alt(in_place_t{}, std::forward(args)...); - return result->value; - } - - template - inline static void generic_construct(constructor &lhs, Rhs &&rhs) - { - lhs.destroy(); - if (!rhs.valueless_by_exception()) - { - visitation::alt::visit_alt_at(rhs.index(), ctor{}, lhs, std::forward(rhs)); - lhs.index_ = rhs.index_; - } - } -}; - -template -class move_constructor; - -#define OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \ - template \ - class move_constructor, move_constructible_trait> \ - : public constructor> \ - { \ - using super = constructor>; \ - \ - public: \ - using super::super; \ - using super::operator=; \ - \ - move_constructor(const move_constructor &) = default; \ - definition ~move_constructor() = default; \ - move_constructor &operator=(const move_constructor &) = default; \ - move_constructor &operator=(move_constructor &&) = default; \ - } - -OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR(Trait::TriviallyAvailable, - move_constructor(move_constructor &&that) = default;); - -OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR( - Trait::Available, - move_constructor(move_constructor &&that) noexcept( - all::value...>::value) - : move_constructor(valueless_t{}) { this->generic_construct(*this, std::move(that)); }); - -OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR(Trait::Unavailable, - move_constructor(move_constructor &&) = delete;); - -#undef OPENTELEMETRY_VARIANT_MOVE_CONSTRUCTOR - -template -class copy_constructor; - -#define OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \ - template \ - class copy_constructor, copy_constructible_trait> \ - : public move_constructor> \ - { \ - using super = move_constructor>; \ - \ - public: \ - using super::super; \ - using super::operator=; \ - \ - definition copy_constructor(copy_constructor &&) = default; \ - ~copy_constructor() = default; \ - copy_constructor &operator=(const copy_constructor &) = default; \ - copy_constructor &operator=(copy_constructor &&) = default; \ - } - -OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR(Trait::TriviallyAvailable, - copy_constructor(const copy_constructor &that) = default;); - -OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR( - Trait::Available, copy_constructor(const copy_constructor &that) - : copy_constructor(valueless_t{}) { this->generic_construct(*this, that); }); - -OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR(Trait::Unavailable, - copy_constructor(const copy_constructor &) = delete;); - -#undef OPENTELEMETRY_VARIANT_COPY_CONSTRUCTOR - -template -class assignment : public copy_constructor -{ - using super = copy_constructor; - -public: - using super::super; - using super::operator=; - - template - inline /* auto & */ auto emplace(Args &&... args) - -> decltype(this->construct_alt(access::base::get_alt(*this), std::forward(args)...)) - { - this->destroy(); - auto &result = - this->construct_alt(access::base::get_alt(*this), std::forward(args)...); - this->index_ = I; - return result; - } - -protected: - template - struct assigner - { - template - inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const - { - self->assign_alt(this_alt, std::forward(that_alt).value); - } - assignment *self; - }; - - template - inline void assign_alt(alt &a, Arg &&arg) - { - if (this->index() == I) - { -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4244) -#endif - a.value = std::forward(arg); -#ifdef _MSC_VER -# pragma warning(pop) -#endif - } - else - { - struct - { - void operator()(std::true_type) const { this_->emplace(std::forward(arg_)); } - void operator()(std::false_type) const { this_->emplace(T(std::forward(arg_))); } - assignment *this_; - Arg &&arg_; - } impl{this, std::forward(arg)}; - impl(bool_constant < std::is_nothrow_constructible::value || - !std::is_nothrow_move_constructible::value > {}); - } - } - - template - inline void generic_assign(That &&that) - { - if (this->valueless_by_exception() && that.valueless_by_exception()) - { - // do nothing. - } - else if (that.valueless_by_exception()) - { - this->destroy(); - } - else - { - visitation::alt::visit_alt_at(that.index(), assigner{this}, *this, - std::forward(that)); - } - } -}; - -template -class move_assignment; - -#define OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \ - template \ - class move_assignment, move_assignable_trait> : public assignment> \ - { \ - using super = assignment>; \ - \ - public: \ - using super::super; \ - using super::operator=; \ - \ - move_assignment(const move_assignment &) = default; \ - move_assignment(move_assignment &&) = default; \ - ~move_assignment() = default; \ - move_assignment &operator=(const move_assignment &) = default; \ - definition \ - } - -OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT( - Trait::TriviallyAvailable, move_assignment &operator=(move_assignment &&that) = default;); - -OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT( - Trait::Available, - move_assignment & - operator=(move_assignment &&that) noexcept( - all<(std::is_nothrow_move_constructible::value && - std::is_nothrow_move_assignable::value)...>::value) { - this->generic_assign(std::move(that)); - return *this; - }); - -OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT(Trait::Unavailable, - move_assignment &operator=(move_assignment &&) = delete;); - -#undef OPENTELEMETRY_VARIANT_MOVE_ASSIGNMENT - -template -class copy_assignment; - -#define OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \ - template \ - class copy_assignment, copy_assignable_trait> \ - : public move_assignment> \ - { \ - using super = move_assignment>; \ - \ - public: \ - using super::super; \ - using super::operator=; \ - \ - copy_assignment(const copy_assignment &) = default; \ - copy_assignment(copy_assignment &&) = default; \ - ~copy_assignment() = default; \ - definition copy_assignment &operator=(copy_assignment &&) = default; \ - } - -OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT( - Trait::TriviallyAvailable, copy_assignment &operator=(const copy_assignment &that) = default;); - -OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT( - Trait::Available, - copy_assignment & - operator=(const copy_assignment &that) { - this->generic_assign(that); - return *this; - }); - -OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT( - Trait::Unavailable, copy_assignment &operator=(const copy_assignment &) = delete;); - -#undef OPENTELEMETRY_VARIANT_COPY_ASSIGNMENT -template -class impl : public copy_assignment> -{ - using super = copy_assignment>; - -public: - using super::super; - using super::operator=; - - impl(const impl &) = default; - impl(impl &&) = default; - ~impl() = default; - impl &operator=(const impl &) = default; - impl &operator=(impl &&) = default; - - template - inline void assign(Arg &&arg) - { - this->assign_alt(access::base::get_alt(*this), std::forward(arg)); - } - - inline void swap(impl &that) - { - if (this->valueless_by_exception() && that.valueless_by_exception()) - { - // do nothing. - } - else if (this->index() == that.index()) - { - visitation::alt::visit_alt_at(this->index(), swapper{}, *this, that); - } - else - { - impl *lhs = this; - impl *rhs = std::addressof(that); - if (lhs->move_nothrow() && !rhs->move_nothrow()) - { - std::swap(lhs, rhs); - } - impl tmp(std::move(*rhs)); -#if __EXCEPTIONS - // EXTENSION: When the move construction of `lhs` into `rhs` throws - // and `tmp` is nothrow move constructible then we move `tmp` back - // into `rhs` and provide the strong exception safety guarantee. - try - { - this->generic_construct(*rhs, std::move(*lhs)); - } - catch (...) - { - if (tmp.move_nothrow()) - { - this->generic_construct(*rhs, std::move(tmp)); - } - throw; - } -#else - this->generic_construct(*rhs, std::move(*lhs)); -#endif - this->generic_construct(*lhs, std::move(tmp)); - } - } - -private: - struct swapper - { - template - inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const - { - using std::swap; - swap(this_alt.value, that_alt.value); - } - }; - - inline constexpr bool move_nothrow() const - { - return this->valueless_by_exception() || - std::array{ - {std::is_nothrow_move_constructible::value...}}[this->index()]; - } -}; - -template -struct is_non_narrowing_convertible -{ - template - static std::true_type test(T(&&)[1]); - - template - static auto impl(int) -> decltype(test({std::declval()})); - - template - static auto impl(...) -> std::false_type; - - static constexpr bool value = decltype(impl(0))::value; -}; - -template ::value, - typename = void> -struct overload_leaf -{}; - -template -struct overload_leaf -{ - using impl = size_constant (*)(T); - operator impl() const { return nullptr; }; -}; - -template -struct overload_leaf, bool>::value - ? std::is_same, bool>::value - : -#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ >= 5 - is_non_narrowing_convertible::value -#else - std::is_convertible::value -#endif - >> -{ - using impl = size_constant (*)(T); - operator impl() const { return nullptr; }; -}; - -template -struct overload_impl -{ -private: - template - struct impl; - - template - struct impl> : overload_leaf... - {}; - -public: - using type = impl>; -}; - -template -using overload = typename overload_impl::type; - -template -using best_match = invoke_result_t, Arg>; - -template -struct is_in_place_index : std::false_type -{}; - -template -struct is_in_place_index> : std::true_type -{}; - -template -struct is_in_place_type : std::false_type -{}; - -template -struct is_in_place_type> : std::true_type -{}; -} // namespace detail - -template -class variant -{ - static_assert(0 < sizeof...(Ts), "variant must consist of at least one alternative."); - - static_assert(detail::all::value...>::value, - "variant can not have an array type as an alternative."); - - static_assert(detail::all::value...>::value, - "variant can not have a reference type as an alternative."); - - static_assert(detail::all::value...>::value, - "variant can not have a void type as an alternative."); - -public: - template , - enable_if_t::value, int> = 0> - inline constexpr variant() noexcept(std::is_nothrow_default_constructible::value) - : impl_(in_place_index_t<0>{}) - {} - - variant(const variant &) = default; - variant(variant &&) = default; - - template , - enable_if_t::value, int> = 0, - enable_if_t::value, int> = 0, - enable_if_t::value, int> = 0, - std::size_t I = detail::best_match::value, - typename T = detail::type_pack_element_t, - enable_if_t::value, int> = 0> - inline constexpr variant(Arg &&arg) noexcept(std::is_nothrow_constructible::value) - : impl_(in_place_index_t{}, std::forward(arg)) - {} - - template , - enable_if_t::value, int> = 0> - inline explicit constexpr variant(in_place_index_t, Args &&... args) noexcept( - std::is_nothrow_constructible::value) - : impl_(in_place_index_t{}, std::forward(args)...) - {} - - template < - std::size_t I, - typename Up, - typename... Args, - typename T = detail::type_pack_element_t, - enable_if_t &, Args...>::value, int> = 0> - inline explicit constexpr variant( - in_place_index_t, - std::initializer_list il, - Args &&... args) noexcept(std::is_nothrow_constructible &, - Args...>::value) - : impl_(in_place_index_t{}, il, std::forward(args)...) - {} - - template ::value, - enable_if_t::value, int> = 0> - inline explicit constexpr variant(in_place_type_t, Args &&... args) noexcept( - std::is_nothrow_constructible::value) - : impl_(in_place_index_t{}, std::forward(args)...) - {} - - template < - typename T, - typename Up, - typename... Args, - std::size_t I = detail::find_index_sfinae::value, - enable_if_t &, Args...>::value, int> = 0> - inline explicit constexpr variant( - in_place_type_t, - std::initializer_list il, - Args &&... args) noexcept(std::is_nothrow_constructible &, - Args...>::value) - : impl_(in_place_index_t{}, il, std::forward(args)...) - {} - - ~variant() = default; - - variant &operator=(const variant &) = default; - variant &operator=(variant &&) = default; - - template < - typename Arg, - enable_if_t, variant>::value, int> = 0, - std::size_t I = detail::best_match::value, - typename T = detail::type_pack_element_t, - enable_if_t<(std::is_assignable::value && std::is_constructible::value), - int> = 0> - inline variant &operator=(Arg &&arg) noexcept((std::is_nothrow_assignable::value && - std::is_nothrow_constructible::value)) - { - impl_.template assign(std::forward(arg)); - return *this; - } - - template , - enable_if_t::value, int> = 0> - inline T &emplace(Args &&... args) - { - return impl_.template emplace(std::forward(args)...); - } - - template < - std::size_t I, - typename Up, - typename... Args, - typename T = detail::type_pack_element_t, - enable_if_t &, Args...>::value, int> = 0> - inline T &emplace(std::initializer_list il, Args &&... args) - { - return impl_.template emplace(il, std::forward(args)...); - } - - template ::value, - enable_if_t::value, int> = 0> - inline T &emplace(Args &&... args) - { - return impl_.template emplace(std::forward(args)...); - } - - template < - typename T, - typename Up, - typename... Args, - std::size_t I = detail::find_index_sfinae::value, - enable_if_t &, Args...>::value, int> = 0> - inline T &emplace(std::initializer_list il, Args &&... args) - { - return impl_.template emplace(il, std::forward(args)...); - } - - inline constexpr bool valueless_by_exception() const noexcept - { - return impl_.valueless_by_exception(); - } - - inline constexpr std::size_t index() const noexcept { return impl_.index(); } - - template , Dummy>::value && - detail::dependent_type, Dummy>::value)...>::value, - int> = 0> - inline void swap(variant &that) noexcept( - detail::all<(std::is_nothrow_move_constructible::value && - is_nothrow_swappable::value)...>::value) - { - impl_.swap(that.impl_); - } - -private: - detail::impl impl_; - - friend struct detail::access::variant; - friend struct detail::visitation::variant; -}; - -template -inline constexpr bool holds_alternative(const variant &v) noexcept -{ - return v.index() == I; -} - -template -inline constexpr bool holds_alternative(const variant &v) noexcept -{ - return holds_alternative::value>(v); -} - -namespace detail -{ -template -struct generic_get_impl -{ - constexpr generic_get_impl(int) noexcept {} - - constexpr auto operator()(V &&v) const - AUTO_REFREF_RETURN(access::variant::get_alt(std::forward(v)).value) -}; - -template -inline constexpr auto generic_get(V &&v) AUTO_REFREF_RETURN(generic_get_impl( - holds_alternative(v) ? 0 : (throw_bad_variant_access(), 0))(std::forward(v))) -} // namespace detail - -template -inline constexpr variant_alternative_t> &get(variant &v) -{ - return detail::generic_get(v); -} - -template -inline constexpr variant_alternative_t> &&get(variant &&v) -{ - return detail::generic_get(std::move(v)); -} - -template -inline constexpr const variant_alternative_t> &get(const variant &v) -{ - return detail::generic_get(v); -} - -template -inline constexpr const variant_alternative_t> &&get(const variant &&v) -{ - return detail::generic_get(std::move(v)); -} - -template -inline constexpr T &get(variant &v) -{ - return get::value>(v); -} - -template -inline constexpr T &&get(variant &&v) -{ - return get::value>(std::move(v)); -} - -template -inline constexpr const T &get(const variant &v) -{ - return get::value>(v); -} - -template -inline constexpr const T &&get(const variant &&v) -{ - return get::value>(std::move(v)); -} - -namespace detail -{ - -template -inline constexpr /* auto * */ auto generic_get_if(V *v) noexcept AUTO_RETURN( - v &&holds_alternative(*v) ? std::addressof(access::variant::get_alt(*v).value) : nullptr) - -} // namespace detail - -template -inline constexpr add_pointer_t>> get_if( - variant *v) noexcept -{ - return detail::generic_get_if(v); -} - -template -inline constexpr add_pointer_t>> get_if( - const variant *v) noexcept -{ - return detail::generic_get_if(v); -} - -template -inline constexpr add_pointer_t get_if(variant *v) noexcept -{ - return get_if::value>(v); -} - -template -inline constexpr add_pointer_t get_if(const variant *v) noexcept -{ - return get_if::value>(v); -} - -namespace detail -{ -template -struct convert_to_bool -{ - template - inline constexpr bool operator()(Lhs &&lhs, Rhs &&rhs) const - { - static_assert(std::is_convertible, bool>::value, - "relational operators must return a type" - " implicitly convertible to bool"); - return nostd::invoke(RelOp{}, std::forward(lhs), std::forward(rhs)); - } -}; -} // namespace detail - -template -inline constexpr bool operator==(const variant &lhs, const variant &rhs) -{ - using detail::visitation::variant; - using equal_to = detail::convert_to_bool; - return lhs.index() == rhs.index() && (lhs.valueless_by_exception() || - variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs)); -} - -template -inline constexpr bool operator!=(const variant &lhs, const variant &rhs) -{ - using detail::visitation::variant; - using not_equal_to = detail::convert_to_bool; - return lhs.index() != rhs.index() || - (!lhs.valueless_by_exception() && - variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs)); -} - -template -inline constexpr bool operator<(const variant &lhs, const variant &rhs) -{ - using detail::visitation::variant; - using less = detail::convert_to_bool; - return !rhs.valueless_by_exception() && - (lhs.valueless_by_exception() || lhs.index() < rhs.index() || - (lhs.index() == rhs.index() && variant::visit_value_at(lhs.index(), less{}, lhs, rhs))); -} - -template -inline constexpr bool operator>(const variant &lhs, const variant &rhs) -{ - using detail::visitation::variant; - using greater = detail::convert_to_bool; - return !lhs.valueless_by_exception() && - (rhs.valueless_by_exception() || lhs.index() > rhs.index() || - (lhs.index() == rhs.index() && - variant::visit_value_at(lhs.index(), greater{}, lhs, rhs))); -} - -template -inline constexpr bool operator<=(const variant &lhs, const variant &rhs) -{ - using detail::visitation::variant; - using less_equal = detail::convert_to_bool; - return lhs.valueless_by_exception() || - (!rhs.valueless_by_exception() && - (lhs.index() < rhs.index() || - (lhs.index() == rhs.index() && - variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs)))); -} - -template -inline constexpr bool operator>=(const variant &lhs, const variant &rhs) -{ - using detail::visitation::variant; - using greater_equal = detail::convert_to_bool; - return rhs.valueless_by_exception() || - (!lhs.valueless_by_exception() && - (lhs.index() > rhs.index() || - (lhs.index() == rhs.index() && - variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs)))); -} - -struct monostate -{}; - -inline constexpr bool operator<(monostate, monostate) noexcept -{ - return false; -} - -inline constexpr bool operator>(monostate, monostate) noexcept -{ - return false; -} - -inline constexpr bool operator<=(monostate, monostate) noexcept -{ - return true; -} - -inline constexpr bool operator>=(monostate, monostate) noexcept -{ - return true; -} - -inline constexpr bool operator==(monostate, monostate) noexcept -{ - return true; -} - -inline constexpr bool operator!=(monostate, monostate) noexcept -{ - return false; -} - -namespace detail -{ - -template -inline constexpr bool all_of_impl(const std::array &bs, std::size_t idx) -{ - return idx >= N || (bs[idx] && all_of_impl(bs, idx + 1)); -} - -template -inline constexpr bool all_of(const std::array &bs) -{ - return all_of_impl(bs, 0); -} - -} // namespace detail - -template -inline constexpr auto visit(Visitor &&visitor, Vs &&... vs) DECLTYPE_AUTO_RETURN( - (detail::all_of(std::array{{!vs.valueless_by_exception()...}}) - ? (void)0 - : throw_bad_variant_access()), - detail::visitation::variant::visit_value(std::forward(visitor), - std::forward(vs)...)) template -inline auto swap(variant &lhs, variant &rhs) noexcept(noexcept(lhs.swap(rhs))) - -> decltype(lhs.swap(rhs)) -{ - lhs.swap(rhs); -} +using absl::get; +using absl::holds_alternative; +using absl::variant; +using absl::visit; } // namespace nostd OPENTELEMETRY_END_NAMESPACE - -#undef AUTO_RETURN - -#undef AUTO_REFREF_RETURN - -#undef DECLTYPE_AUTO_RETURN +#else +# include "opentelemetry/nostd/mpark/variant.h" +#endif diff --git a/api/include/opentelemetry/std/shared_ptr.h b/api/include/opentelemetry/std/shared_ptr.h new file mode 100644 index 0000000000..8969f2ced5 --- /dev/null +++ b/api/include/opentelemetry/std/shared_ptr.h @@ -0,0 +1,31 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "opentelemetry/version.h" + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +// Standard Type aliases in nostd namespace +namespace nostd +{ + +// nostd::shared_ptr +template +using shared_ptr = std::shared_ptr<_Types...>; + +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/std/span.h b/api/include/opentelemetry/std/span.h new file mode 100644 index 0000000000..da9fcb48a3 --- /dev/null +++ b/api/include/opentelemetry/std/span.h @@ -0,0 +1,76 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "opentelemetry/version.h" + +// Standard library implementation requires at least C++17 compiler. +// Older C++14 compilers may provide support for __has_include as a +// conforming extension. +#if defined __has_include +# if __has_include() // Check for __cpp_{feature} +# include +# if defined(__cpp_lib_span) +# define HAVE_SPAN +# endif +# endif +# if __has_include() && !defined(HAVE_SPAN) // Check for span +# define HAVE_SPAN +# endif +# if !__has_include() // Check for string_view +# error \ + "STL library does not support std::span. Possible solution:" \ + " - #undef HAVE_CPP_STDLIB // to use OpenTelemetry nostd::string_view" +# endif +#endif + +#if !defined(HAVE_SPAN) +# if defined(HAVE_GSL) +# include +// Guidelines Support Library provides an implementation of std::span +# include +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +template +using span = gsl::span; +} +OPENTELEMETRY_END_NAMESPACE +# else +// No span implementation provided. +# error \ + "STL library does not support std::span. Possible solutions:" \ + " - #undef HAVE_CPP_STDLIB // to use OpenTelemetry nostd::span .. or " \ + " - #define HAVE_GSL // to use gsl::span " +# endif + +#else // HAVE_SPAN +// Using std::span (https://wg21.link/P0122R7) from Standard Library available in C++20 : +// - GCC libstdc++ 10+ +// - Clang libc++ 7 +// - MSVC Standard Library 19.26* +// - Apple Clang 10.0.0* +# include +# include +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +constexpr std::size_t dynamic_extent = std::numeric_limits::max(); + +template +using span = std::span; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE +#endif // of HAVE_SPAN diff --git a/api/include/opentelemetry/std/string_view.h b/api/include/opentelemetry/std/string_view.h new file mode 100644 index 0000000000..755b4387a1 --- /dev/null +++ b/api/include/opentelemetry/std/string_view.h @@ -0,0 +1,36 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "opentelemetry/version.h" + +#include "opentelemetry/std/utility.h" + +#include +#include +#include +#include +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +// Standard Type aliases in nostd namespace +namespace nostd +{ + +// nostd::string_view +using string_view = std::string_view; + +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/std/type_traits.h b/api/include/opentelemetry/std/type_traits.h new file mode 100644 index 0000000000..1fd6ef7f88 --- /dev/null +++ b/api/include/opentelemetry/std/type_traits.h @@ -0,0 +1,31 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "opentelemetry/version.h" + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +// Standard Type aliases in nostd namespace +namespace nostd +{ + +// nostd::enable_if_t<...> +template +using enable_if_t = typename std::enable_if::type; + +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/std/unique_ptr.h b/api/include/opentelemetry/std/unique_ptr.h new file mode 100644 index 0000000000..7877d2d854 --- /dev/null +++ b/api/include/opentelemetry/std/unique_ptr.h @@ -0,0 +1,31 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "opentelemetry/version.h" + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +// Standard Type aliases in nostd namespace +namespace nostd +{ + +// nostd::unique_ptr +template +using unique_ptr = std::unique_ptr<_Types...>; + +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/std/utility.h b/api/include/opentelemetry/std/utility.h new file mode 100644 index 0000000000..a0d73c9fe9 --- /dev/null +++ b/api/include/opentelemetry/std/utility.h @@ -0,0 +1,80 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "opentelemetry/version.h" + +#include +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +// Standard Type aliases in nostd namespace +namespace nostd +{ + +// +// Backport of std::data +// +// See https://en.cppreference.com/w/cpp/iterator/data +// +template +auto data(C &c) noexcept(noexcept(c.data())) -> decltype(c.data()) +{ + return c.data(); +} + +template +auto data(const C &c) noexcept(noexcept(c.data())) -> decltype(c.data()) +{ + return c.data(); +} + +template +T *data(T (&array)[N]) noexcept +{ + return array; +} + +template +const E *data(std::initializer_list list) noexcept +{ + return list.begin(); +} + +// +// Backport of std::size +// +// See https://en.cppreference.com/w/cpp/iterator/size +// +template +auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size()) +{ + return c.size(); +} + +template +std::size_t size(T (&array)[N]) noexcept +{ + return N; +} + +template +using make_index_sequence = std::make_index_sequence; + +template +using index_sequence = std::index_sequence; + +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/std/variant.h b/api/include/opentelemetry/std/variant.h new file mode 100644 index 0000000000..aca8d4de5f --- /dev/null +++ b/api/include/opentelemetry/std/variant.h @@ -0,0 +1,232 @@ +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "opentelemetry/version.h" + +#include +#include +#include +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +// Standard Type aliases in nostd namespace +namespace nostd +{ + +// nostd::variant<...> +template +using variant = std::variant<_Types...>; + +#if defined(__APPLE__) && defined(_LIBCPP_USE_AVAILABILITY_APPLE) +// Apple Platforms provide std::bad_variant_access only in newer versions of OS. +// To keep API compatible with any version of OS - we are providing our own +// implementation of nostd::bad_variant_access exception. +# if __EXCEPTIONS + +// nostd::bad_variant_access +class bad_variant_access : public std::exception +{ +public: + virtual const char *what() const noexcept override { return "bad_variant_access"; } +}; + +[[noreturn]] inline void throw_bad_variant_access() +{ + throw bad_variant_access{}; +} +# endif + +# if __EXCEPTIONS +# define THROW_BAD_VARIANT_ACCESS throw_bad_variant_access() +# else +# define THROW_BAD_VARIANT_ACCESS std::terminate() +# endif + +// +// nostd::get<...> for Apple Clang +// +template +constexpr auto get_type = [](auto &&t) constexpr -> decltype(auto) +{ + auto v = t; + auto result = std::get_if(&v); // TODO: optimize with std::forward(t) if t is not rvalue + if (result) + { + return *result; + } + THROW_BAD_VARIANT_ACCESS; + return *result; +}; + +template +constexpr auto get_index = [](auto &&t) constexpr -> decltype(auto) +{ + auto v = t; + auto result = std::get_if(&v); // TODO: optimize with std::forward(t) if t is not rvalue + if (result) + { + return *result; + } + THROW_BAD_VARIANT_ACCESS; + return *result; +}; + +template +constexpr std::variant_alternative_t> &get(std::variant &v) +{ + return get_index(v); +}; + +template +constexpr std::variant_alternative_t> &&get(std::variant &&v) +{ + return get_index(std::forward(v)); +}; + +template +constexpr const std::variant_alternative_t> &get( + const std::variant &v) +{ + return get_index(v); +}; + +template +constexpr const std::variant_alternative_t> &&get( + const std::variant &&v) +{ + return get_index(std::forward(v)); +}; + +template +constexpr T &get(std::variant &v) +{ + return get_type(v); +}; + +template +constexpr T /*&&*/ get(std::variant &&v) +{ + return get_type(v); +}; + +template +constexpr const T &get(const std::variant &v) +{ + return get_type(v); +}; + +template +constexpr const T &&get(const std::variant &&v) +{ + return get_type(std::forward(v)); +}; + +template +constexpr auto visit(_Callable &&_Obj, _Variants &&... _Args) +{ + // Ref: + // https://stackoverflow.com/questions/52310835/xcode-10-call-to-unavailable-function-stdvisit + return std::__variant_detail::__visitation::__variant::__visit_value(_Obj, _Args...); +}; + +#else + +template +constexpr std::variant_alternative_t> &get(std::variant &v) +{ + return std::get(v); +}; + +template +constexpr std::variant_alternative_t> &&get(std::variant &&v) +{ + return std::get(std::forward(v)); +}; + +template +constexpr const std::variant_alternative_t> &get( + const std::variant &v) +{ + return std::get(v); +}; + +template +constexpr const std::variant_alternative_t> &&get( + const std::variant &&v) +{ + return std::get(std::forward(v)); +}; + +template +constexpr T &get(std::variant &v) +{ + return std::get(v); +}; + +template +constexpr T &&get(std::variant &&v) +{ + return std::get(std::forward(v)); +}; + +template +constexpr const T &get(const std::variant &v) +{ + return std::get(v); +}; + +template +constexpr const T &&get(const std::variant &&v) +{ + return std::get(std::forward(v)); +}; + +template +constexpr auto visit(_Callable &&_Obj, _Variants &&... _Args) +{ + return std::visit<_Callable, _Variants...>(static_cast<_Callable &&>(_Obj), + static_cast<_Variants &&>(_Args)...); +}; + +#endif + +/* +# if _HAS_CXX20 +template +constexpr _Ret visit(_Callable &&_Obj, _Variants &&... _Args) +{ + return std::visit<_Ret, _Callable, _Variants...>( + static_cast<_Callable &&>(_Obj), + static_cast<_Variants &&>(_Args)...); +}; +# endif +*/ + +// nostd::holds_alternative +template +inline constexpr bool holds_alternative(const variant &v) noexcept +{ + return v.index() == I; +} + +template +inline constexpr bool holds_alternative(const variant &v) noexcept +{ + return std::holds_alternative(v); +} + +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/trace/span.h b/api/include/opentelemetry/trace/span.h index f324658740..7235e96ae1 100644 --- a/api/include/opentelemetry/trace/span.h +++ b/api/include/opentelemetry/trace/span.h @@ -5,8 +5,10 @@ #include "opentelemetry/common/attribute_value.h" #include "opentelemetry/common/key_value_iterable_view.h" #include "opentelemetry/core/timestamp.h" +#include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/span.h" #include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" #include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/trace/canonical_code.h" #include "opentelemetry/trace/span_context.h" @@ -167,5 +169,14 @@ class Span // AddEvent). virtual bool IsRecording() const noexcept = 0; }; + +template +nostd::shared_ptr to_span_ptr(TracerType *objPtr, + nostd::string_view name, + const trace::StartSpanOptions &options) +{ + return nostd::shared_ptr{new (std::nothrow) SpanType{*objPtr, name, options}}; +} + } // namespace trace OPENTELEMETRY_END_NAMESPACE diff --git a/api/test/context/CMakeLists.txt b/api/test/context/CMakeLists.txt index 2edbbc6a86..2c9da11191 100644 --- a/api/test/context/CMakeLists.txt +++ b/api/test/context/CMakeLists.txt @@ -2,7 +2,11 @@ include(GoogleTest) foreach(testname context_test runtime_context_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX context. TEST_LIST ${testname}) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX context. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/core/CMakeLists.txt b/api/test/core/CMakeLists.txt index 633759a9d5..0d59831bb4 100644 --- a/api/test/core/CMakeLists.txt +++ b/api/test/core/CMakeLists.txt @@ -1,7 +1,10 @@ include(GoogleTest) add_executable(timestamp_test timestamp_test.cc) -target_link_libraries(timestamp_test ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) -gtest_add_tests(TARGET timestamp_test TEST_PREFIX trace. TEST_LIST - timestamp_test) +target_link_libraries( + timestamp_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) +gtest_add_tests( + TARGET timestamp_test + TEST_PREFIX trace. + TEST_LIST timestamp_test) diff --git a/api/test/metrics/CMakeLists.txt b/api/test/metrics/CMakeLists.txt index c9d2083d5a..f20a46c094 100644 --- a/api/test/metrics/CMakeLists.txt +++ b/api/test/metrics/CMakeLists.txt @@ -1,6 +1,10 @@ foreach(testname noop_instrument_test meter_provider_test noop_metrics_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/nostd/BUILD b/api/test/nostd/BUILD index 35306e6a3c..107512108c 100644 --- a/api/test/nostd/BUILD +++ b/api/test/nostd/BUILD @@ -1,76 +1,79 @@ -cc_test( - name = "function_ref_test", - srcs = [ - "function_ref_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "string_view_test", - srcs = [ - "string_view_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "variant_test", - srcs = [ - "variant_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "unique_ptr_test", - srcs = [ - "unique_ptr_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "utility_test", - srcs = [ - "utility_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "span_test", - srcs = [ - "span_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "shared_ptr_test", - srcs = [ - "shared_ptr_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) +cc_test( + name = "function_ref_test", + srcs = [ + "function_ref_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "string_view_test", + srcs = [ + "string_view_test.cc", + ], + deps = [ + "//api", + "@com_github_google_benchmark//:benchmark", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "variant_test", + srcs = [ + "variant_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "unique_ptr_test", + srcs = [ + "unique_ptr_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "utility_test", + srcs = [ + "utility_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "span_test", + srcs = [ + "span_test.cc", + ], + deps = [ + "//api", + "@com_github_google_benchmark//:benchmark", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "shared_ptr_test", + srcs = [ + "shared_ptr_test.cc", + ], + deps = [ + "//api", + "@com_github_google_benchmark//:benchmark", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index fdbf8e7b07..096da4b48b 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -3,7 +3,11 @@ include(GoogleTest) foreach(testname function_ref_test string_view_test unique_ptr_test utility_test span_test shared_ptr_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX nostd. TEST_LIST ${testname}) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + benchmark::benchmark ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX nostd. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/nostd/shared_ptr_test.cc b/api/test/nostd/shared_ptr_test.cc index 46151d88c4..a453a18456 100644 --- a/api/test/nostd/shared_ptr_test.cc +++ b/api/test/nostd/shared_ptr_test.cc @@ -1,179 +1,204 @@ -#include "opentelemetry/nostd/shared_ptr.h" - -#include - -using opentelemetry::nostd::shared_ptr; - -class A -{ -public: - explicit A(bool &destructed) noexcept : destructed_{destructed} { destructed_ = false; } - - ~A() { destructed_ = true; } - -private: - bool &destructed_; -}; - -class B -{ -public: - int f() const { return 123; } -}; - -class C -{ -public: - virtual ~C() {} -}; - -class D : public C -{ -public: - virtual ~D() {} -}; - -TEST(SharedPtrTest, DefaultConstruction) -{ - shared_ptr ptr1; - EXPECT_EQ(ptr1.get(), nullptr); - - shared_ptr ptr2{nullptr}; - EXPECT_EQ(ptr2.get(), nullptr); -} - -TEST(SharedPtrTest, ExplicitConstruction) -{ - auto c = new C(); - shared_ptr ptr1{c}; - EXPECT_EQ(ptr1.get(), c); - - auto d = new D(); - shared_ptr ptr2{d}; - EXPECT_EQ(ptr2.get(), d); -} - -TEST(SharedPtrTest, MoveConstruction) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - shared_ptr ptr2{std::move(ptr1)}; - EXPECT_EQ(ptr1.get(), nullptr); - EXPECT_EQ(ptr2.get(), value); -} - -TEST(SharedPtrTest, MoveConstructionFromDifferentType) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - shared_ptr ptr2{std::move(ptr1)}; - EXPECT_EQ(ptr1.get(), nullptr); - EXPECT_EQ(ptr2.get(), value); -} - -TEST(SharedPtrTest, MoveConstructionFromStdSharedPtr) -{ - auto value = new int{123}; - std::shared_ptr ptr1{value}; - shared_ptr ptr2{std::move(ptr1)}; - EXPECT_EQ(ptr1.get(), nullptr); - EXPECT_EQ(ptr2.get(), value); -} - -TEST(SharedPtrTest, Destruction) -{ - bool was_destructed; - shared_ptr{new A{was_destructed}}; - EXPECT_TRUE(was_destructed); -} - -TEST(SharedPtrTest, Assignment) -{ - auto value = new int{123}; - shared_ptr ptr1; - - ptr1 = shared_ptr(value); - EXPECT_EQ(ptr1.get(), value); - - ptr1 = nullptr; - EXPECT_EQ(ptr1.get(), nullptr); - - auto value2 = new int{234}; - const shared_ptr ptr2 = shared_ptr(value2); - ptr1 = ptr2; - EXPECT_EQ(ptr1.get(), value2); - - auto value3 = new int{345}; - std::shared_ptr ptr3(value3); - ptr1 = ptr3; - EXPECT_EQ(ptr1.get(), value3); -} - -TEST(SharedPtrTest, BoolConversionOpertor) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - - EXPECT_TRUE(ptr1); - EXPECT_FALSE(shared_ptr{}); -} - -TEST(SharedPtrTest, PointerOperators) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - - EXPECT_EQ(&*ptr1, value); - EXPECT_EQ( - shared_ptr { new B }->f(), 123); -} - -TEST(SharedPtrTest, Swap) -{ - auto value1 = new int{123}; - shared_ptr ptr1{value1}; - - auto value2 = new int{456}; - shared_ptr ptr2{value2}; - ptr1.swap(ptr2); - - EXPECT_EQ(ptr1.get(), value2); - EXPECT_EQ(ptr2.get(), value1); -} - -TEST(SharedPtrTest, Comparison) -{ - shared_ptr ptr1{new int{123}}; - shared_ptr ptr2{new int{456}}; - shared_ptr ptr3{}; - - EXPECT_EQ(ptr1, ptr1); - EXPECT_NE(ptr1, ptr2); - - EXPECT_NE(ptr1, nullptr); - EXPECT_NE(nullptr, ptr1); - - EXPECT_EQ(ptr3, nullptr); - EXPECT_EQ(nullptr, ptr3); -} - -TEST(SharedPtrTest, Sort) -{ - std::vector> nums; - - for (int i = 10; i > 0; i--) - { - nums.push_back(shared_ptr(new int(i))); - } - - auto nums2 = nums; - - std::sort(nums.begin(), nums.end(), - [](shared_ptr a, shared_ptr b) { return *a < *b; }); - - EXPECT_NE(nums, nums2); - - std::reverse(nums2.begin(), nums2.end()); - - EXPECT_EQ(nums, nums2); -} +#include "opentelemetry/nostd/shared_ptr.h" + +#include +#include +#include + +using opentelemetry::nostd::shared_ptr; + +class A +{ +public: + explicit A(bool &destructed) noexcept : destructed_{destructed} { destructed_ = false; } + + ~A() { destructed_ = true; } + +private: + bool &destructed_; +}; + +class B +{ +public: + int f() const { return 123; } +}; + +class C +{ +public: + virtual ~C() {} +}; + +class D : public C +{ +public: + virtual ~D() {} +}; + +TEST(SharedPtrTest, DefaultConstruction) +{ + shared_ptr ptr1; + EXPECT_EQ(ptr1.get(), nullptr); + + shared_ptr ptr2{nullptr}; + EXPECT_EQ(ptr2.get(), nullptr); +} + +TEST(SharedPtrTest, ExplicitConstruction) +{ + auto c = new C(); + shared_ptr ptr1{c}; + EXPECT_EQ(ptr1.get(), c); + + auto d = new D(); + shared_ptr ptr2{d}; + EXPECT_EQ(ptr2.get(), d); +} + +TEST(SharedPtrTest, MoveConstruction) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + shared_ptr ptr2{std::move(ptr1)}; + EXPECT_EQ(ptr1.get(), nullptr); + EXPECT_EQ(ptr2.get(), value); +} + +TEST(SharedPtrTest, MoveConstructionFromDifferentType) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + shared_ptr ptr2{std::move(ptr1)}; + EXPECT_EQ(ptr1.get(), nullptr); + EXPECT_EQ(ptr2.get(), value); +} + +TEST(SharedPtrTest, MoveConstructionFromStdSharedPtr) +{ + auto value = new int{123}; + std::shared_ptr ptr1{value}; + shared_ptr ptr2{std::move(ptr1)}; + EXPECT_EQ(ptr1.get(), nullptr); + EXPECT_EQ(ptr2.get(), value); +} + +TEST(SharedPtrTest, Destruction) +{ + bool was_destructed; + shared_ptr{new A{was_destructed}}; + EXPECT_TRUE(was_destructed); +} + +TEST(SharedPtrTest, Assignment) +{ + auto value = new int{123}; + shared_ptr ptr1; + + ptr1 = shared_ptr(value); + EXPECT_EQ(ptr1.get(), value); + + ptr1 = nullptr; + EXPECT_EQ(ptr1.get(), nullptr); + + auto value2 = new int{234}; + const shared_ptr ptr2 = shared_ptr(value2); + ptr1 = ptr2; + EXPECT_EQ(ptr1.get(), value2); + + auto value3 = new int{345}; + std::shared_ptr ptr3(value3); + ptr1 = ptr3; + EXPECT_EQ(ptr1.get(), value3); +} + +TEST(SharedPtrTest, BoolConversionOpertor) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + + EXPECT_TRUE(ptr1); + EXPECT_FALSE(shared_ptr{}); +} + +TEST(SharedPtrTest, PointerOperators) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + + EXPECT_EQ(&*ptr1, value); + EXPECT_EQ( + shared_ptr { new B }->f(), 123); +} + +TEST(SharedPtrTest, Swap) +{ + auto value1 = new int{123}; + shared_ptr ptr1{value1}; + + auto value2 = new int{456}; + shared_ptr ptr2{value2}; + ptr1.swap(ptr2); + + EXPECT_EQ(ptr1.get(), value2); + EXPECT_EQ(ptr2.get(), value1); +} + +TEST(SharedPtrTest, Comparison) +{ + shared_ptr ptr1{new int{123}}; + shared_ptr ptr2{new int{456}}; + shared_ptr ptr3{}; + + EXPECT_EQ(ptr1, ptr1); + EXPECT_NE(ptr1, ptr2); + + EXPECT_NE(ptr1, nullptr); + EXPECT_NE(nullptr, ptr1); + + EXPECT_EQ(ptr3, nullptr); + EXPECT_EQ(nullptr, ptr3); +} + +static void SharedPtrTest_Sort(size_t size = 10) +{ + std::vector> nums; + + for (int i = size; i > 0; i--) + { + nums.push_back(shared_ptr(new int(i))); + } + + auto nums2 = nums; + + std::sort(nums.begin(), nums.end(), + [](shared_ptr a, shared_ptr b) { return *a < *b; }); + + EXPECT_NE(nums, nums2); + + std::reverse(nums2.begin(), nums2.end()); + + EXPECT_EQ(nums, nums2); +} + +TEST(SharedPtrTest, Sort) +{ + SharedPtrTest_Sort(); +} + +static void SharedPtrTestSort(benchmark::State &state) +{ + for (auto _ : state) + { + SharedPtrTest_Sort(10000); + } +} +BENCHMARK(SharedPtrTestSort); + +TEST(SharedPtr, PerfTests) +{ + // Run all benchmarks + int argc = 0; + const char *argv[] = {""}; + ::benchmark::Initialize(&argc, (char **)(argv)); + ::benchmark::RunSpecifiedBenchmarks(); +} diff --git a/api/test/nostd/span_test.cc b/api/test/nostd/span_test.cc index 44e7d49a15..f3a68167d9 100644 --- a/api/test/nostd/span_test.cc +++ b/api/test/nostd/span_test.cc @@ -1,175 +1,246 @@ -#include "opentelemetry/nostd/span.h" - -#include -#include -#include -#include -#include -#include - -#include - -using opentelemetry::nostd::span; - -TEST(SpanTest, DefaultConstruction) -{ - span s1; - EXPECT_EQ(s1.data(), nullptr); - EXPECT_EQ(s1.size(), 0); - EXPECT_TRUE(s1.empty()); - - span s2; - EXPECT_EQ(s2.data(), nullptr); - EXPECT_EQ(s2.size(), 0); - EXPECT_TRUE(s2.empty()); - - EXPECT_FALSE((std::is_default_constructible>::value)); -} - -TEST(SpanTest, Assignment) -{ - std::array array1 = {1, 2, 3}; - std::array array2 = {1, 2, 3}; - span s1{array1.data(), array1.size()}; - span s2{array1.data(), array1.size()}; - - span s3; - s3 = s1; - EXPECT_EQ(s3.data(), array1.data()); - EXPECT_EQ(s3.size(), array1.size()); - - span s4{array2}; - s4 = s2; - EXPECT_EQ(s4.data(), array1.data()); - EXPECT_EQ(s4.size(), array1.size()); -} - -TEST(SpanTest, PointerCountConstruction) -{ - std::array array = {1, 2, 3}; - - span s1{array.data(), array.size()}; - EXPECT_EQ(s1.data(), array.data()); - EXPECT_EQ(s1.size(), array.size()); - - span s2{array.data(), array.size()}; - EXPECT_EQ(s2.data(), array.data()); - EXPECT_EQ(s2.size(), array.size()); - - EXPECT_DEATH((span{array.data(), array.size()}), ".*"); -} - -TEST(SpanTest, RangeConstruction) -{ - int array[] = {1, 2, 3}; - - span s1{std::begin(array), std::end(array)}; - EXPECT_EQ(s1.data(), array); - EXPECT_EQ(s1.size(), 3); - - span s2{std::begin(array), std::end(array)}; - EXPECT_EQ(s2.data(), array); - EXPECT_EQ(s2.size(), 3); - - EXPECT_DEATH((span{std::begin(array), std::end(array)}), ".*"); -} - -TEST(SpanTest, ArrayConstruction) -{ - int array1[] = {1, 2, 3}; - std::array array2 = {1, 2, 3}; - - span s1{array1}; - EXPECT_EQ(s1.data(), array1); - EXPECT_EQ(s1.size(), 3); - - span s2{array2}; - EXPECT_EQ(s2.data(), array2.data()); - EXPECT_EQ(s2.size(), array2.size()); - - span s3{array1}; - EXPECT_EQ(s3.data(), array1); - EXPECT_EQ(s3.size(), 3); - - span s4{array2}; - EXPECT_EQ(s4.data(), array2.data()); - EXPECT_EQ(s4.size(), array2.size()); - - EXPECT_FALSE((std::is_constructible, int(&)[3]>::value)); -} - -TEST(SpanTest, ContainerConstruction) -{ - std::vector v = {1, 2, 3}; - - span s1{v}; - EXPECT_EQ(s1.data(), v.data()); - EXPECT_EQ(s1.size(), v.size()); - - span s2{v}; - EXPECT_EQ(s2.data(), v.data()); - EXPECT_EQ(s2.size(), v.size()); - EXPECT_DEATH((span{v}), ".*"); - - EXPECT_FALSE((std::is_constructible, std::vector>::value)); - EXPECT_FALSE((std::is_constructible, std::list>::value)); -} - -TEST(SpanTest, OtherSpanConstruction) -{ - std::array array = {1, 2, 3}; - span s1{array.data(), array.size()}; - span s2{array.data(), array.size()}; - - span s3{s1}; - EXPECT_EQ(s3.data(), array.data()); - EXPECT_EQ(s3.size(), array.size()); - - span s4{s2}; - EXPECT_EQ(s4.data(), array.data()); - EXPECT_EQ(s4.size(), array.size()); - - span s5{s1}; - EXPECT_EQ(s5.data(), array.data()); - EXPECT_EQ(s5.size(), array.size()); - - EXPECT_FALSE((std::is_constructible, span>::value)); - EXPECT_FALSE((std::is_constructible, span>::value)); - - span s6{s2}; - EXPECT_EQ(s6.data(), array.data()); - EXPECT_EQ(s6.size(), array.size()); - - span s7{s2}; - EXPECT_EQ(s7.data(), array.data()); - EXPECT_EQ(s7.size(), array.size()); - - EXPECT_FALSE((std::is_constructible, span>::value)); - EXPECT_FALSE((std::is_constructible, span>::value)); -} - -TEST(SpanTest, BracketOperator) -{ - std::array array = {1, 2}; - - span s1{array.data(), array.size()}; - EXPECT_EQ(s1[0], 1); - EXPECT_EQ(s1[1], 2); - - span s2{array.data(), array.size()}; - EXPECT_EQ(s2[0], 1); - EXPECT_EQ(s2[1], 2); -} - -TEST(SpanTest, Iteration) -{ - std::array array = {1, 2, 3}; - - span s1{array.data(), array.size()}; - EXPECT_EQ(std::distance(s1.begin(), s1.end()), array.size()); - EXPECT_TRUE(std::equal(s1.begin(), s1.end(), array.begin())); - - span s2{array.data(), array.size()}; - EXPECT_EQ(std::distance(s2.begin(), s2.end()), array.size()); - EXPECT_TRUE(std::equal(s2.begin(), s2.end(), array.begin())); -} +#include "opentelemetry/nostd/span.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +using opentelemetry::nostd::span; + +TEST(SpanTest, DefaultConstruction) +{ + span s1; + EXPECT_EQ(s1.data(), nullptr); + EXPECT_EQ(s1.size(), 0); + EXPECT_TRUE(s1.empty()); + + span s2; + EXPECT_EQ(s2.data(), nullptr); + EXPECT_EQ(s2.size(), 0); + EXPECT_TRUE(s2.empty()); + + EXPECT_FALSE((std::is_default_constructible>::value)); +} + +TEST(SpanTest, Assignment) +{ + std::array array1 = {1, 2, 3}; + std::array array2 = {1, 2, 3}; + span s1{array1.data(), array1.size()}; + span s2{array1.data(), array1.size()}; + + span s3; + s3 = s1; + EXPECT_EQ(s3.data(), array1.data()); + EXPECT_EQ(s3.size(), array1.size()); + + span s4{array2}; + s4 = s2; + EXPECT_EQ(s4.data(), array1.data()); + EXPECT_EQ(s4.size(), array1.size()); +} + +TEST(SpanTest, PointerCountConstruction) +{ + std::array array = {1, 2, 3}; + + span s1{array.data(), array.size()}; + EXPECT_EQ(s1.data(), array.data()); + EXPECT_EQ(s1.size(), array.size()); + + span s2{array.data(), array.size()}; + EXPECT_EQ(s2.data(), array.data()); + EXPECT_EQ(s2.size(), array.size()); + +#ifndef HAVE_CPP_STDLIB + /* This test is not supposed to fail with STL. Why is this invalid construct? */ + EXPECT_DEATH((span{array.data(), array.size()}), ".*"); +#endif +} + +TEST(SpanTest, RangeConstruction) +{ + int array[] = {1, 2, 3}; + + span s1{std::begin(array), std::end(array)}; + EXPECT_EQ(s1.data(), array); + EXPECT_EQ(s1.size(), 3); + + span s2{std::begin(array), std::end(array)}; + EXPECT_EQ(s2.data(), array); + EXPECT_EQ(s2.size(), 3); + +#ifndef HAVE_CPP_STDLIB + /* This test is not supposed to fail with STL. Why is this invalid construct? */ + EXPECT_DEATH((span{std::begin(array), std::end(array)}), ".*"); +#endif +} + +TEST(SpanTest, ArrayConstruction) +{ + int array1[] = {1, 2, 3}; + std::array array2 = {1, 2, 3}; + + span s1{array1}; + EXPECT_EQ(s1.data(), array1); + EXPECT_EQ(s1.size(), 3); + + span s2{array2}; + EXPECT_EQ(s2.data(), array2.data()); + EXPECT_EQ(s2.size(), array2.size()); + + span s3{array1}; + EXPECT_EQ(s3.data(), array1); + EXPECT_EQ(s3.size(), 3); + + span s4{array2}; + EXPECT_EQ(s4.data(), array2.data()); + EXPECT_EQ(s4.size(), array2.size()); + + EXPECT_FALSE((std::is_constructible, int(&)[3]>::value)); +} + +TEST(SpanTest, ContainerConstruction) +{ + std::vector v = {1, 2, 3}; + + span s1{v}; + EXPECT_EQ(s1.data(), v.data()); + EXPECT_EQ(s1.size(), v.size()); + + span s2{v.data(), 3}; + + EXPECT_EQ(s2.data(), v.data()); + EXPECT_EQ(s2.size(), v.size()); + +#ifndef HAVE_CPP_STDLIB + /* This test is not supposed to fail with STL. Why is this invalid construct? */ + EXPECT_DEATH((span{v.data(), 3}), ".*"); +#endif + + EXPECT_FALSE((std::is_constructible, std::vector>::value)); + EXPECT_FALSE((std::is_constructible, std::list>::value)); +} + +TEST(SpanTest, OtherSpanConstruction) +{ + std::array array = {1, 2, 3}; + span s1{array.data(), array.size()}; + span s2{array.data(), array.size()}; + + span s3{s1}; + EXPECT_EQ(s3.data(), array.data()); + EXPECT_EQ(s3.size(), array.size()); + + span s4{s2}; + EXPECT_EQ(s4.data(), array.data()); + EXPECT_EQ(s4.size(), array.size()); + + span s5{s1}; + EXPECT_EQ(s5.data(), array.data()); + EXPECT_EQ(s5.size(), array.size()); + + EXPECT_FALSE((std::is_constructible, span>::value)); + EXPECT_FALSE((std::is_constructible, span>::value)); + + span s6{s2}; + EXPECT_EQ(s6.data(), array.data()); + EXPECT_EQ(s6.size(), array.size()); + + span s7{s2}; + EXPECT_EQ(s7.data(), array.data()); + EXPECT_EQ(s7.size(), array.size()); + + EXPECT_FALSE((std::is_constructible, span>::value)); + EXPECT_FALSE((std::is_constructible, span>::value)); +} + +TEST(SpanTest, BracketOperator) +{ + std::array array = {1, 2}; + + span s1{array.data(), array.size()}; + EXPECT_EQ(s1[0], 1); + EXPECT_EQ(s1[1], 2); + + span s2{array.data(), array.size()}; + EXPECT_EQ(s2[0], 1); + EXPECT_EQ(s2[1], 2); +} + +TEST(SpanTest, Iteration) +{ + std::array array = {1, 2, 3}; + + span s1{array.data(), array.size()}; + EXPECT_EQ(std::distance(s1.begin(), s1.end()), array.size()); + EXPECT_TRUE(std::equal(s1.begin(), s1.end(), array.begin())); + + span s2{array.data(), array.size()}; + EXPECT_EQ(std::distance(s2.begin(), s2.end()), array.size()); + EXPECT_TRUE(std::equal(s2.begin(), s2.end(), array.begin())); +} + +static void SpanIterator(benchmark::State &state) +{ + constexpr size_t aSize = 100000; + std::array array{}; + for (size_t i = 0; i < aSize; i++) + { + array[i] = i; + } + span s1{array.data(), array.size()}; + for (auto _ : state) + { + size_t i = 0; + for (auto item : s1) + { + EXPECT_EQ(item, i); + i++; + } + } +} +BENCHMARK(SpanIterator); + +static void SpanConstructor(benchmark::State &state) +{ + constexpr size_t aSize = 1000000; + auto *aInt16 = new std::array{}; + auto *aInt32 = new std::array{}; + auto *aInt64 = new std::array{}; + for (size_t i = 0; i < aSize; i++) + { + (*aInt16)[i] = i; + (*aInt32)[i] = i; + (*aInt64)[i] = i; + } + size_t j = aSize; + for (auto _ : state) + { + benchmark::DoNotOptimize([&] { + span s1{aInt16->data(), aInt16->size()}; + span s2{aInt32->data(), aInt32->size()}; + span s3{aInt64->data(), aInt64->size()}; + }); + } + delete aInt16; + delete aInt32; + delete aInt64; +} +BENCHMARK(SpanConstructor); + +TEST(SpanTest, PerfTests) +{ + // Run all benchmarks + int argc = 0; + const char *argv[] = {""}; + ::benchmark::Initialize(&argc, (char **)(argv)); + ::benchmark::RunSpecifiedBenchmarks(); +} diff --git a/api/test/nostd/string_view_test.cc b/api/test/nostd/string_view_test.cc index 364410a312..74985e385f 100644 --- a/api/test/nostd/string_view_test.cc +++ b/api/test/nostd/string_view_test.cc @@ -1,104 +1,215 @@ -#include "opentelemetry/nostd/string_view.h" - -#include - -#include "map" - -using opentelemetry::nostd::string_view; - -TEST(StringViewTest, DefaultConstruction) -{ - string_view ref; - EXPECT_EQ(ref.data(), nullptr); - EXPECT_EQ(ref.length(), 0); -} - -TEST(StringViewTest, CStringInitialization) -{ - const char *val = "hello world"; - - string_view ref(val); - - EXPECT_EQ(ref.data(), val); - EXPECT_EQ(ref.length(), std::strlen(val)); -} - -TEST(StringViewTest, StdStringInitialization) -{ - const std::string val = "hello world"; - - string_view ref(val); - - EXPECT_EQ(ref.data(), val.data()); - EXPECT_EQ(ref.length(), val.size()); -} - -TEST(StringViewTest, Copy) -{ - const std::string val = "hello world"; - - string_view ref(val); - string_view cpy(ref); - - EXPECT_EQ(cpy.data(), val); - EXPECT_EQ(cpy.length(), val.length()); - EXPECT_EQ(cpy, val); -} - -TEST(StringViewTest, Accessor) -{ - string_view s = "abc123"; - EXPECT_EQ(s.data(), &s[0]); - EXPECT_EQ(s.data() + 1, &s[1]); -} - -TEST(StringViewTest, ExplicitStdStringConversion) -{ - std::string s = static_cast(string_view{"abc"}); - EXPECT_EQ(s, "abc"); -} - -TEST(StringViewTest, SubstrPortion) -{ - string_view s = "abc123"; - EXPECT_EQ("123", s.substr(3)); - EXPECT_EQ("12", s.substr(3, 2)); -} - -TEST(StringViewTest, SubstrOutOfRange) -{ - string_view s = "abc123"; -#if __EXCEPTIONS - EXPECT_THROW(s.substr(10), std::out_of_range); -#else - EXPECT_DEATH({ s.substr(10); }, ""); -#endif -} - -TEST(StringViewTest, Compare) -{ - string_view s1 = "aaa"; - string_view s2 = "bbb"; - string_view s3 = "aaa"; - - // Equals - EXPECT_EQ(s1, s3); - EXPECT_EQ(s1, s1); - - // Less then - EXPECT_LT(s1, s2); - - // Greater then - EXPECT_GT(s2, s1); -} - -TEST(StringViewTest, MapKeyOrdering) -{ - std::map m = {{"bbb", 2}, {"aaa", 1}, {"ccc", 3}}; - size_t i = 1; - for (const auto &kv : m) - { - EXPECT_EQ(kv.second, i); - i++; - } -} +#include "opentelemetry/nostd/string_view.h" + +#include + +#include +#include +#include +#include + +using opentelemetry::nostd::string_view; + +TEST(StringViewTest, DefaultConstruction) +{ + string_view ref; + EXPECT_EQ(ref.data(), nullptr); + EXPECT_EQ(ref.length(), 0); +} + +TEST(StringViewTest, CStringInitialization) +{ + const char *val = "hello world"; + + string_view ref(val); + + EXPECT_EQ(ref.data(), val); + EXPECT_EQ(ref.length(), std::strlen(val)); +} + +TEST(StringViewTest, StdStringInitialization) +{ + const std::string val = "hello world"; + + string_view ref(val); + + EXPECT_EQ(ref.data(), val.data()); + EXPECT_EQ(ref.length(), val.size()); +} + +TEST(StringViewTest, Copy) +{ + const std::string val = "hello world"; + + string_view ref(val); + string_view cpy(ref); + + EXPECT_EQ(cpy.data(), val); + EXPECT_EQ(cpy.length(), val.length()); + EXPECT_EQ(cpy, val); +} + +TEST(StringViewTest, Accessor) +{ + string_view s = "abc123"; + EXPECT_EQ(s.data(), &s[0]); + EXPECT_EQ(s.data() + 1, &s[1]); +} + +TEST(StringViewTest, ExplicitStdStringConversion) +{ + std::string s = static_cast(string_view{"abc"}); + EXPECT_EQ(s, "abc"); +} + +TEST(StringViewTest, SubstrPortion) +{ + string_view s = "abc123"; + EXPECT_EQ("123", s.substr(3)); + EXPECT_EQ("12", s.substr(3, 2)); +} + +TEST(StringViewTest, SubstrOutOfRange) +{ + string_view s = "abc123"; +#if __EXCEPTIONS || defined(HAVE_STDLIB_CPP) + EXPECT_THROW(s.substr(10), std::out_of_range); +#else + EXPECT_DEATH({ s.substr(10); }, ""); +#endif +} + +TEST(StringViewTest, Compare) +{ + string_view s1 = "aaa"; + string_view s2 = "bbb"; + string_view s3 = "aaa"; + + // Equals + EXPECT_EQ(s1, s3); + EXPECT_EQ(s1, s1); + + // Less then + EXPECT_LT(s1, s2); + + // Greater then + EXPECT_GT(s2, s1); +} + +TEST(StringViewTest, MapKeyOrdering) +{ + std::map m = {{"bbb", 2}, {"aaa", 1}, {"ccc", 3}}; + size_t i = 1; + for (const auto &kv : m) + { + EXPECT_EQ(kv.second, i); + i++; + } +} + +static void StringViewSubStr(benchmark::State &state) +{ + std::string s = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + for (auto _ : state) + { + string_view sv = s; + auto oneSv = sv.substr(0, 5); + auto twoSv = sv.substr(6, 5); + auto threeSv = sv.substr(12, 5); + auto fourSv = sv.substr(18, 11); + auto fiveSv = sv.substr(30, 5); + benchmark::DoNotOptimize(oneSv); + benchmark::DoNotOptimize(twoSv); + benchmark::DoNotOptimize(threeSv); + benchmark::DoNotOptimize(fourSv); + benchmark::DoNotOptimize(fiveSv); + } +} +BENCHMARK(StringViewSubStr); + +static void StringViewMaps(benchmark::State &state) +{ + std::map m; + std::string txt; + size_t i = 0; + for (auto _ : state) + { + i %= 200; // up to 200 key-value pairs in this collection + m[string_view(std::to_string(i))] = string_view(std::to_string(i)); + i += 1; + }; +} +BENCHMARK(StringViewMaps); + +static void StringViewFromCString(benchmark::State &state) +{ + std::string s = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + for (auto _ : state) + { + string_view sv(s.c_str()); + // scan thru string_view + for (const auto &c : sv) + ; + }; +} +BENCHMARK(StringViewFromCString); + +static void StringViewToString(benchmark::State &state) +{ + string_view s = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + std::string txt; + for (auto _ : state) + { + txt = std::string(s.data(), s.length()); + }; +} +BENCHMARK(StringViewToString); + +static void StringViewExplode(benchmark::State &state) +{ + for (auto _ : state) + { + string_view sv = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + std::string s; + for (size_t i = 0; i < 5; i++) + { + s += std::string(sv.data(), sv.length()); + sv = s; + string_view sv2 = s; + if (sv == sv2) + ; // FIXME: Warning C4390 ';' : empty controlled statement found; is this the intent ? + } + }; +} +BENCHMARK(StringViewExplode); + +static void StringViewVector(benchmark::State &state) +{ + std::vector v; + for (auto _ : state) + { + string_view sv = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + v.push_back(sv); + if (v.size() > 10000) + v.clear(); + } +} +BENCHMARK(StringViewVector); + +TEST(StringView, PerfTests) +{ + // Run all benchmarks + int argc = 0; + const char *argv[] = {""}; + ::benchmark::Initialize(&argc, (char **)(argv)); + ::benchmark::RunSpecifiedBenchmarks(); +} diff --git a/api/test/plugin/CMakeLists.txt b/api/test/plugin/CMakeLists.txt index d17c300794..29a75b6b84 100644 --- a/api/test/plugin/CMakeLists.txt +++ b/api/test/plugin/CMakeLists.txt @@ -1,8 +1,11 @@ include(GoogleTest) add_executable(dynamic_load_test dynamic_load_test.cc) -target_link_libraries(dynamic_load_test ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) +target_link_libraries( + dynamic_load_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) target_link_libraries(dynamic_load_test ${CMAKE_DL_LIBS}) -gtest_add_tests(TARGET dynamic_load_test TEST_PREFIX plugin. TEST_LIST - dynamic_load_test) +gtest_add_tests( + TARGET dynamic_load_test + TEST_PREFIX plugin. + TEST_LIST dynamic_load_test) diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index 3d3dc88891..6c69883b2c 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -10,10 +10,13 @@ foreach( noop_test tracer_test) add_executable(api_${testname} "${testname}.cc") - target_link_libraries(api_${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET api_${testname} TEST_PREFIX trace. TEST_LIST - api_${testname}) + target_link_libraries( + api_${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + gtest_add_tests( + TARGET api_${testname} + TEST_PREFIX trace. + TEST_LIST api_${testname}) endforeach() add_executable(span_id_benchmark span_id_benchmark.cc) diff --git a/api/test/trace/propagation/CMakeLists.txt b/api/test/trace/propagation/CMakeLists.txt index f2a9815426..8f13cd68de 100644 --- a/api/test/trace/propagation/CMakeLists.txt +++ b/api/test/trace/propagation/CMakeLists.txt @@ -1,6 +1,10 @@ foreach(testname http_text_format_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 4790daabf5..5f64601521 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -156,6 +156,7 @@ elif [[ "$1" == "format" ]]; then if [[ ! -z "$CHANGED" ]]; then echo "The following files have changes:" echo "$CHANGED" + git diff exit 1 fi exit 0 diff --git a/docs/abi-compatibility.md b/docs/abi-compatibility.md new file mode 100644 index 0000000000..6b5158bcd7 --- /dev/null +++ b/docs/abi-compatibility.md @@ -0,0 +1,35 @@ +# Windows + +## Visual Studio 2015, 2017, 2019 + +The Microsoft C++ (MSVC) compiler toolsets in Visual Studio 2013 and earlier don't guarantee binary compatibility across versions. You can't link object files, static libraries, dynamic libraries, and executables built by different versions. The ABIs, object formats, and runtime libraries are incompatible. + +We've changed this behavior in Visual Studio 2015, 2017, and 2019. The runtime libraries and apps compiled by any of these versions of the compiler are binary-compatible. It's reflected in the C++ toolset major number, which is 14 for all three versions. (The toolset version is v140 for Visual Studio 2015, v141 for 2017, and v142 for 2019). Say you have third-party libraries built by Visual Studio 2015. You can still use them in an application built by Visual Studio 2017 or 2019. There's no need to recompile with a matching toolset. The latest version of the Microsoft Visual C++ Redistributable package (the Redistributable) works for all of them. + +There are three important restrictions on binary compatibility: + +- You can mix binaries built by different versions of the toolset. However, you must use a toolset at least as recent as the most recent binary to link your app. Here's an example: you can link an app compiled using the 2017 toolset to a static library compiled using 2019, if they're linked using the 2019 toolset. + +- The Redistributable your app uses has a similar binary-compatibility restriction. When you mix binaries built by different supported versions of the toolset, the Redistributable version must be at least as new as the latest toolset used by any app component. + +- Static libraries or object files compiled using the /GL (Whole program optimization) compiler switch aren't binary-compatible across versions. All object files and libraries compiled using /GL must use exactly the same toolset for the compile and the final link. + +[Reference](https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2019) + +## Breaking Compatibility + +### Exceptions + +- [__CxxFrameHandler4](https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/) - static library built with Visual Studio 2019 wont link to executable compiled with Visual Studio 2017 + +### Release vs Debug libraries on Windows + +- [\_SECURE_SCL](https://docs.microsoft.com/en-us/cpp/standard-library/secure-scl?view=vs-2019) - checked iterators (old) + +- [\_ITERATOR_DEBUG_LEVEL](https://docs.microsoft.com/en-us/cpp/standard-library/iterator-debug-level?view=vs-2019) - checked iterators (new) + +### Spectre Mitigation + +- [Runtime Libraries for Spectre Mitigation](https://docs.microsoft.com/en-us/cpp/build/reference/qspectre?view=vs-2019) + +- [New Spectre Mitigations in Visual Studio 2019](https://devblogs.microsoft.com/cppblog/more-spectre-mitigations-in-msvc/) diff --git a/docs/building-with-stdlib.md b/docs/building-with-stdlib.md new file mode 100644 index 0000000000..dafb977080 --- /dev/null +++ b/docs/building-with-stdlib.md @@ -0,0 +1,102 @@ +# Building with Standard C++ Library + +Standard Library build flavor works best for statically linking the SDK in a +process (environment where ABI compat is not a requirement), or for +"header-only" implementation of SDK. + +Proposed approach cannot be employed for shared libs in environments where +ABI compatibility is required: + +- OpenTelemetry SDK binary compiled with compiler A + STL B +- may not be ABI compatible with the main executable compiled with compiler + C + STL D on a same OS. +Thus, this approach works best only for statically lined / header only use. + +## Motivation + +In certain scenarios it may be of benefit to compile the OpenTelemetry SDK from +source using standard library container classes (`std::map`, `std::string_view`, +`std::span`, `std::variant`) instead of OpenTelemetry `nostd::` analogs (which +were backported to C++11 and designed as ABI-stable). This PR also can be used +as a foundation for alternate approach - to also allow bindings to [abseil](https://github.com/abseil/abseil-cpp) +classes. That is in environments that would rather prefer `Abseil` classes +over the standard lib or `nostd`. + +The approach is to provide totally opaque (from SDK code / SDK developer +perspective) mapping / aliasing from `nostd::` classes back to their `std::` +counterparts, and that is only done in environments where this is possible. + +We continue fully supporting both models and run CI for both. + +## Pros and Cons + +### Using trusted/certified Standard Library + +Using standard library implementation classes in customer code and on API +surface instead of `nostd` classes. Certain environments would prefer to have +**standard** instead of non-standard classes due to security, performance, +stability and debug'ability considerations. For example, Visual Studio IDE +provides 1st class Debug experience for Standard containers, plus additional +runtime-checks for Debug builds that use Standard containers. + +### Minimizing binary size + +No need to marshal types from standard to `nostd`, then back to standard +library means less code involved and less memcpy. We use Standard classes +used elsewhere in the app. We can subsequently improve the process by avoiding +`KeyValueIterable` transform (and, thus, unnecessary memcpy) when we know +that the incoming types does not need to be 'transferred' across ABI boundary. +This is the case for statically linked executables and when SDK is implemented +as 'header-only' library. + +### Avoiding unnecessary extra memcpy (perf improvements) + +No need to transform from 'native' standard library types, e.g. `std::map` via +`KeyValueIterable` means we can bypass that transformation process, if and when +we know that the ABI compatibility is not a requirement in certain environment. +ETA perf improvement is 1.5%-3% better perf since an extra transform, memcpy, +iteration for-each key-value is avoided. + +### ABI stability + +Obviously this approach does not work in environment where ABI stability +guarantee must be provided, e.g. for dynamically loadable OpenTelemetry SDK +module and plugins for products such as NGINX, Envoy, etc. + +## Scope of changes needed to implement the feature + +### Separate flavors of SDK build + +Supported build flavors: + +- `nostd` - OpenTelemetry backport of classes for C++11. Not using STD Lib. +- `stl` - Standard Library. Best be compiled with C++20 compaitlbe compiler. + C++17 may be used with additional dependencies, e.g. MS-GSL or Abseil. +- `absl` - TODO: this should allow using Abseil C++ lirary only (no MS-GSL). + +### Test setup + +Tests to validate that all OpenTelemetry functionality is working the same +identical way irrespective of what C++ runtime / STL library it is compiled +with. + +### Implementation Details + +Feature allows to alias from `nostd::` to `std::` classes for C++17 and above. + +Consistent handling of `std::variant` across various OS: + +- backport of a few missing variant features, e.g. `std::get` and `std::visit` + for older version of Mac OS X. Patches that enable proper + handling of `std::visit` and `std::variant` irrespective of OS version + to resolve [this quirk](https://stackoverflow.com/questions/52310835/xcode-10-call-to-unavailable-function-stdvisit). + +- ability to optionally borrow implementation of C++20 `gsl::span` from + [Microsoft Guidelines Support Library](https://github.com/microsoft/GSL). + This is not necessary for C++20 and above compilers. + +- ability to use Abseil `absl::variant` for Visual Studio 2015 + +- set of tools to locally build the SDK with both options across various OS + and compilers, including vs2015 (C++11), vs2017 (C++17), vs2019 (C++20), + ubuntu-18.xx (C++17), ubuntu-20.xx/gcc-9 (C++20), Mac OS X (C++17 and above). diff --git a/examples/batch/CMakeLists.txt b/examples/batch/CMakeLists.txt index d1146d59b3..41654aeb93 100644 --- a/examples/batch/CMakeLists.txt +++ b/examples/batch/CMakeLists.txt @@ -2,5 +2,6 @@ include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include) add_executable(batch_span_processor_example main.cc) -target_link_libraries(batch_span_processor_example ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_exporter_ostream_span opentelemetry_trace) +target_link_libraries( + batch_span_processor_example ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} + opentelemetry_exporter_ostream_span opentelemetry_trace) diff --git a/examples/metrics_simple/CMakeLists.txt b/examples/metrics_simple/CMakeLists.txt index 4269318871..add3a153ce 100644 --- a/examples/metrics_simple/CMakeLists.txt +++ b/examples/metrics_simple/CMakeLists.txt @@ -3,4 +3,4 @@ include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include) add_executable(simple_metrics main.cc) target_link_libraries( simple_metrics ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics - opentelemetry_exporter_ostream_metrics) + ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_metrics) diff --git a/examples/otlp/CMakeLists.txt b/examples/otlp/CMakeLists.txt index 23dc75fe6d..02eaa2c49d 100644 --- a/examples/otlp/CMakeLists.txt +++ b/examples/otlp/CMakeLists.txt @@ -4,8 +4,9 @@ include_directories(${CMAKE_SOURCE_DIR}/exporters/otlp/include) add_library(otlp_foo_library foo_library/foo_library.cc) target_link_libraries(otlp_foo_library ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_api) + ${CORE_RUNTIME_LIBS} opentelemetry_api) add_executable(example_otlp main.cc) -target_link_libraries(example_otlp ${CMAKE_THREAD_LIBS_INIT} otlp_foo_library - opentelemetry_trace opentelemetry_exporter_otprotocol) +target_link_libraries( + example_otlp ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} otlp_foo_library + opentelemetry_trace opentelemetry_exporter_otprotocol) diff --git a/examples/plugin/plugin/tracer.cc b/examples/plugin/plugin/tracer.cc index 14703c7064..512af5669d 100644 --- a/examples/plugin/plugin/tracer.cc +++ b/examples/plugin/plugin/tracer.cc @@ -1,73 +1,72 @@ -#include "tracer.h" -#include "opentelemetry/context/runtime_context.h" -#include "opentelemetry/nostd/unique_ptr.h" - -#include -#include - -namespace nostd = opentelemetry::nostd; -namespace common = opentelemetry::common; -namespace core = opentelemetry::core; -namespace trace = opentelemetry::trace; -namespace context = opentelemetry::context; - -namespace -{ -class Span final : public trace::Span -{ -public: - Span(std::shared_ptr &&tracer, - nostd::string_view name, - const opentelemetry::common::KeyValueIterable & /*attributes*/, - const trace::StartSpanOptions & /*options*/) noexcept - : tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()} - { - std::cout << "StartSpan: " << name << "\n"; - } - - ~Span() { std::cout << "~Span\n"; } - - // opentelemetry::trace::Span - void SetAttribute(nostd::string_view /*name*/, - const common::AttributeValue & /*value*/) noexcept override - {} - - void AddEvent(nostd::string_view /*name*/) noexcept override {} - - void AddEvent(nostd::string_view /*name*/, core::SystemTimestamp /*timestamp*/) noexcept override - {} - - void AddEvent(nostd::string_view /*name*/, - core::SystemTimestamp /*timestamp*/, - const common::KeyValueIterable & /*attributes*/) noexcept override - {} - - void SetStatus(trace::CanonicalCode /*code*/, - nostd::string_view /*description*/) noexcept override - {} - - void UpdateName(nostd::string_view /*name*/) noexcept override {} - - void End(const trace::EndSpanOptions & /*options*/) noexcept override {} - - bool IsRecording() const noexcept override { return true; } - - trace::SpanContext GetContext() const noexcept override { return span_context_; } - -private: - std::shared_ptr tracer_; - std::string name_; - trace::SpanContext span_context_; -}; -} // namespace - -Tracer::Tracer(nostd::string_view /*output*/) {} - -nostd::shared_ptr Tracer::StartSpan( - nostd::string_view name, - const opentelemetry::common::KeyValueIterable &attributes, - const trace::StartSpanOptions &options) noexcept -{ - return nostd::shared_ptr{ - new (std::nothrow) Span{this->shared_from_this(), name, attributes, options}}; -} +#include "tracer.h" +#include "opentelemetry/nostd/unique_ptr.h" + +#include +#include + +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace core = opentelemetry::core; +namespace trace = opentelemetry::trace; +namespace context = opentelemetry::context; + +namespace +{ +class Span final : public trace::Span +{ +public: + Span(std::shared_ptr &&tracer, + nostd::string_view name, + const opentelemetry::common::KeyValueIterable & /*attributes*/, + const trace::StartSpanOptions & /*options*/) noexcept + : tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()} + { + std::cout << "StartSpan: " << name << "\n"; + } + + ~Span() { std::cout << "~Span\n"; } + + // opentelemetry::trace::Span + void SetAttribute(nostd::string_view /*name*/, + const common::AttributeValue & /*value*/) noexcept override + {} + + void AddEvent(nostd::string_view /*name*/) noexcept override {} + + void AddEvent(nostd::string_view /*name*/, core::SystemTimestamp /*timestamp*/) noexcept override + {} + + void AddEvent(nostd::string_view /*name*/, + core::SystemTimestamp /*timestamp*/, + const common::KeyValueIterable & /*attributes*/) noexcept override + {} + + void SetStatus(trace::CanonicalCode /*code*/, + nostd::string_view /*description*/) noexcept override + {} + + void UpdateName(nostd::string_view /*name*/) noexcept override {} + + void End(const trace::EndSpanOptions & /*options*/) noexcept override {} + + bool IsRecording() const noexcept override { return true; } + + trace::SpanContext GetContext() const noexcept override { return span_context_; } + +private: + std::shared_ptr tracer_; + std::string name_; + trace::SpanContext span_context_; +}; +} // namespace + +Tracer::Tracer(nostd::string_view /*output*/) {} + +nostd::shared_ptr Tracer::StartSpan( + nostd::string_view name, + const opentelemetry::common::KeyValueIterable &attributes, + const trace::StartSpanOptions &options) noexcept +{ + return nostd::shared_ptr{ + new (std::nothrow) Span{this->shared_from_this(), name, attributes, options}}; +} diff --git a/exporters/memory/CMakeLists.txt b/exporters/memory/CMakeLists.txt index aa8d334bd0..2739596fd5 100644 --- a/exporters/memory/CMakeLists.txt +++ b/exporters/memory/CMakeLists.txt @@ -17,8 +17,12 @@ if(BUILD_TESTING) in_memory_span_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_in_memory) - gtest_add_tests(TARGET in_memory_span_data_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_data_test) - gtest_add_tests(TARGET in_memory_span_exporter_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_exporter_test) + gtest_add_tests( + TARGET in_memory_span_data_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_data_test) + gtest_add_tests( + TARGET in_memory_span_exporter_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_exporter_test) endif() diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index 4818dfd5e2..c307de7244 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -9,14 +9,18 @@ if(BUILD_TESTING) target_link_libraries( ostream_span_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_exporter_ostream_span) + ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_span) target_link_libraries( ostream_metrics_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_exporter_ostream_metrics) + ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_metrics) - gtest_add_tests(TARGET ostream_metrics_test TEST_PREFIX exporter. TEST_LIST - ostream_metrics_test) - gtest_add_tests(TARGET ostream_span_test TEST_PREFIX exporter. TEST_LIST - ostream_span_test) + gtest_add_tests( + TARGET ostream_metrics_test + TEST_PREFIX exporter. + TEST_LIST ostream_metrics_test) + gtest_add_tests( + TARGET ostream_span_test + TEST_PREFIX exporter. + TEST_LIST ostream_span_test) endif() # BUILD_TESTING diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 27ee7de956..d1bc535763 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -9,6 +9,8 @@ if(BUILD_TESTING) target_link_libraries( recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_otprotocol protobuf::libprotobuf) - gtest_add_tests(TARGET recordable_test TEST_PREFIX exporter. TEST_LIST - recordable_test) + gtest_add_tests( + TARGET recordable_test + TEST_PREFIX exporter. + TEST_LIST recordable_test) endif() # BUILD_TESTING diff --git a/exporters/prometheus/test/CMakeLists.txt b/exporters/prometheus/test/CMakeLists.txt index c57f900347..4168c6d3e4 100644 --- a/exporters/prometheus/test/CMakeLists.txt +++ b/exporters/prometheus/test/CMakeLists.txt @@ -3,6 +3,8 @@ foreach(testname prometheus_collector_test prometheus_exporter_utils_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} prometheus_exporter prometheus-cpp::pull) - gtest_add_tests(TARGET ${testname} TEST_PREFIX exporter. TEST_LIST - ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX exporter. + TEST_LIST ${testname}) endforeach() diff --git a/ext/test/zpages/CMakeLists.txt b/ext/test/zpages/CMakeLists.txt index 34c3637316..c7d0d837c8 100644 --- a/ext/test/zpages/CMakeLists.txt +++ b/ext/test/zpages/CMakeLists.txt @@ -4,5 +4,8 @@ foreach(testname tracez_processor_test tracez_data_aggregator_test target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_zpages) - gtest_add_tests(TARGET ${testname} TEST_PREFIX ext. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX ext. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/include/opentelemetry/sdk/common/empty_attributes.h b/sdk/include/opentelemetry/sdk/common/empty_attributes.h index d030d2d118..743b85e7c4 100644 --- a/sdk/include/opentelemetry/sdk/common/empty_attributes.h +++ b/sdk/include/opentelemetry/sdk/common/empty_attributes.h @@ -8,6 +8,8 @@ OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { + +#if 0 /** * Maintain a static empty array of pairs that represents empty (default) attributes. * This helps to avoid constructing a new empty container every time a call is made @@ -23,5 +25,11 @@ static const opentelemetry::common::KeyValueIterableView #include #include #include "opentelemetry/common/attribute_value.h" @@ -21,6 +22,9 @@ using SpanDataAttributeValue = nostd::variant, +#endif std::vector, std::vector, std::vector, @@ -37,17 +41,23 @@ struct AttributeConverter SpanDataAttributeValue operator()(bool v) { return SpanDataAttributeValue(v); } SpanDataAttributeValue operator()(int32_t v) { return SpanDataAttributeValue(v); } SpanDataAttributeValue operator()(uint32_t v) { return SpanDataAttributeValue(v); } - /*SpanDataAttributeValue operator()(int v) - { - return SpanDataAttributeValue(static_cast(v)); - }*/ SpanDataAttributeValue operator()(int64_t v) { return SpanDataAttributeValue(v); } SpanDataAttributeValue operator()(uint64_t v) { return SpanDataAttributeValue(v); } SpanDataAttributeValue operator()(double v) { return SpanDataAttributeValue(v); } SpanDataAttributeValue operator()(nostd::string_view v) { - return SpanDataAttributeValue(std::string(v)); + return SpanDataAttributeValue(std::string(v.data(), v.size())); + } + SpanDataAttributeValue operator()(const char *s) + { + return SpanDataAttributeValue(std::string(s)); } +#ifdef HAVE_SPAN_BYTE + SpanDataAttributeValue operator()(nostd::span v) + { + return convertSpan(v); + } +#endif SpanDataAttributeValue operator()(nostd::span v) { return convertSpan(v); } SpanDataAttributeValue operator()(nostd::span v) { @@ -74,12 +84,7 @@ struct AttributeConverter template SpanDataAttributeValue convertSpan(nostd::span vals) { - std::vector copy; - for (auto &val : vals) - { - copy.push_back(T(val)); - } - + const std::vector copy(vals.begin(), vals.end()); return SpanDataAttributeValue(std::move(copy)); } }; diff --git a/sdk/include/opentelemetry/sdk/trace/span_data.h b/sdk/include/opentelemetry/sdk/trace/span_data.h index 6fde43c342..8787f5fce2 100644 --- a/sdk/include/opentelemetry/sdk/trace/span_data.h +++ b/sdk/include/opentelemetry/sdk/trace/span_data.h @@ -12,6 +12,8 @@ #include "opentelemetry/trace/span_id.h" #include "opentelemetry/trace/trace_id.h" +#include + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { @@ -194,7 +196,10 @@ class SpanData final : public Recordable status_desc_ = std::string(description); } - void SetName(nostd::string_view name) noexcept override { name_ = std::string(name); } + void SetName(nostd::string_view name) noexcept override + { + name_ = std::string(name.data(), name.length()); + } void SetStartTime(opentelemetry::core::SystemTimestamp start_time) noexcept override { diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index 6581ad46be..abffd0ca47 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -54,7 +54,12 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider private: opentelemetry::sdk::AtomicSharedPtr processor_; +#if 0 + // TODO: pros and cons of exposing this as `std::shared_ptr` vs keeping `nostd::shared_ptr` ? std::shared_ptr tracer_; +#else + opentelemetry::nostd::shared_ptr tracer_; +#endif const std::shared_ptr sampler_; }; } // namespace trace diff --git a/sdk/src/common/BUILD b/sdk/src/common/BUILD index a8981b4d55..44f37073bb 100644 --- a/sdk/src/common/BUILD +++ b/sdk/src/common/BUILD @@ -1,29 +1,32 @@ -# Copyright 2020, OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -package(default_visibility = ["//visibility:public"]) - -cc_library( - name = "random", - srcs = ["random.cc"], - hdrs = [ - "fast_random_number_generator.h", - "random.h", - ], - include_prefix = "src/common", - deps = [ - "//api", - "//sdk/src/common/platform:fork", - ], -) +# Copyright 2020, OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "random", + srcs = [ + "core.cc", + "random.cc", + ], + hdrs = [ + "fast_random_number_generator.h", + "random.h", + ], + include_prefix = "src/common", + deps = [ + "//api", + "//sdk/src/common/platform:fork", + ], +) diff --git a/sdk/src/common/CMakeLists.txt b/sdk/src/common/CMakeLists.txt index 042a857539..4a47500a73 100644 --- a/sdk/src/common/CMakeLists.txt +++ b/sdk/src/common/CMakeLists.txt @@ -1,4 +1,4 @@ -set(COMMON_SRCS random.cc) +set(COMMON_SRCS random.cc core.cc) if(WIN32) list(APPEND COMMON_SRCS platform/fork_windows.cc) else() @@ -6,4 +6,5 @@ else() endif() add_library(opentelemetry_common ${COMMON_SRCS}) -target_link_libraries(opentelemetry_common Threads::Threads) +target_link_libraries(opentelemetry_common Threads::Threads + ${CORE_RUNTIME_LIBS}) diff --git a/sdk/src/common/core.cc b/sdk/src/common/core.cc new file mode 100644 index 0000000000..c7cb0219dc --- /dev/null +++ b/sdk/src/common/core.cc @@ -0,0 +1,12 @@ +#include "opentelemetry/nostd/variant.h" +#include "opentelemetry/version.h" + +#if defined(HAVE_ABSEIL) +namespace absl +{ +namespace variant_internal +{ +void __cdecl ThrowBadVariantAccess(){/* TODO: std::terminate or re-throw? */}; +} +} // namespace absl +#endif diff --git a/sdk/src/trace/CMakeLists.txt b/sdk/src/trace/CMakeLists.txt index e4d6bdc5ed..97f4f3d3b3 100644 --- a/sdk/src/trace/CMakeLists.txt +++ b/sdk/src/trace/CMakeLists.txt @@ -3,4 +3,5 @@ add_library( tracer_provider.cc tracer.cc span.cc batch_span_processor.cc samplers/parent.cc samplers/trace_id_ratio.cc) -target_link_libraries(opentelemetry_trace opentelemetry_common) +target_link_libraries(opentelemetry_trace opentelemetry_common + ${CORE_RUNTIME_LIBS}) diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index 8f05436b4c..604191d365 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -1,39 +1,40 @@ -#include "opentelemetry/sdk/trace/tracer_provider.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace trace -{ -TracerProvider::TracerProvider(std::shared_ptr processor, - std::shared_ptr sampler) noexcept - : processor_{processor}, tracer_(new Tracer(std::move(processor), sampler)), sampler_(sampler) -{} - -opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( - nostd::string_view library_name, - nostd::string_view library_version) noexcept -{ - return opentelemetry::nostd::shared_ptr(tracer_); -} - -void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept -{ - processor_.store(processor); - - auto sdkTracer = static_cast(tracer_.get()); - sdkTracer->SetProcessor(processor); -} - -std::shared_ptr TracerProvider::GetProcessor() const noexcept -{ - return processor_.load(); -} - -std::shared_ptr TracerProvider::GetSampler() const noexcept -{ - return sampler_; -} -} // namespace trace -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE +#include "opentelemetry/sdk/trace/tracer_provider.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +TracerProvider::TracerProvider(std::shared_ptr processor, + std::shared_ptr sampler) noexcept + : processor_{processor}, tracer_(new Tracer(std::move(processor), sampler)), sampler_(sampler) +{} + +opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( + nostd::string_view library_name, + nostd::string_view library_version) noexcept +{ + // TODO: do we have to transform this at all, if we can keep it nostd::shared_ptr at source? + return tracer_; +} + +void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept +{ + processor_.store(processor); + + auto sdkTracer = static_cast(tracer_.get()); + sdkTracer->SetProcessor(processor); +} + +std::shared_ptr TracerProvider::GetProcessor() const noexcept +{ + return processor_.load(); +} + +std::shared_ptr TracerProvider::GetSampler() const noexcept +{ + return sampler_; +} +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/test/common/CMakeLists.txt b/sdk/test/common/CMakeLists.txt index 7a181c90c4..f1028bf6d8 100644 --- a/sdk/test/common/CMakeLists.txt +++ b/sdk/test/common/CMakeLists.txt @@ -4,8 +4,11 @@ foreach(testname add_executable(${testname} "${testname}.cc") target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_common opentelemetry_trace) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + ${CORE_RUNTIME_LIBS} opentelemetry_common opentelemetry_trace) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() add_executable(random_fork_test random_fork_test.cc) @@ -13,9 +16,11 @@ target_link_libraries(random_fork_test opentelemetry_common) add_test(random_fork_test random_fork_test) add_executable(random_benchmark random_benchmark.cc) -target_link_libraries(random_benchmark benchmark::benchmark - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) +target_link_libraries( + random_benchmark benchmark::benchmark ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) add_executable(circular_buffer_benchmark circular_buffer_benchmark.cc) -target_link_libraries(circular_buffer_benchmark benchmark::benchmark - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) +target_link_libraries( + circular_buffer_benchmark benchmark::benchmark ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index e518dbdd1e..dbab882a46 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -11,7 +11,11 @@ foreach( metric_instrument_test controller_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) - gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/trace/CMakeLists.txt b/sdk/test/trace/CMakeLists.txt index 79599495b6..1798386884 100644 --- a/sdk/test/trace/CMakeLists.txt +++ b/sdk/test/trace/CMakeLists.txt @@ -12,12 +12,20 @@ foreach( attribute_utils_test) add_executable(${testname} "${testname}.cc") target_link_libraries( - ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_common opentelemetry_trace opentelemetry_exporter_in_memory) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + ${testname} + ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ${CORE_RUNTIME_LIBS} + opentelemetry_common + opentelemetry_trace + opentelemetry_exporter_in_memory) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() add_executable(sampler_benchmark sampler_benchmark.cc) target_link_libraries( sampler_benchmark benchmark::benchmark ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_trace opentelemetry_exporter_in_memory) + ${CORE_RUNTIME_LIBS} opentelemetry_trace opentelemetry_exporter_in_memory) diff --git a/tools/build-all.sh b/tools/build-all.sh new file mode 100644 index 0000000000..8ebedd8983 --- /dev/null +++ b/tools/build-all.sh @@ -0,0 +1,6 @@ +#!/bin/sh +cd .. +mkdir -p out +cd out +cmake .. +make diff --git a/tools/build-benchmark.cmd b/tools/build-benchmark.cmd new file mode 100644 index 0000000000..39b9f180d9 --- /dev/null +++ b/tools/build-benchmark.cmd @@ -0,0 +1,35 @@ +@echo off +set VS_TOOLS_VERSION=vs2019 +set CMAKE_GEN="Visual Studio 16 2019" +echo Building Google Benchmark (test only dependency)... +@setlocal ENABLEEXTENSIONS + +echo Auto-detecting Visual Studio version... +call "%~dp0\vcvars.cmd" + +pushd "%~dp0\.." +set "ROOT=%CD%" + +set MAXCPUCOUNT=%NUMBER_OF_PROCESSORS% +set platform= + +if not exist "%ROOT%\third_party\benchmark\" ( + echo "Google Benchmark library is not available, skipping benchmark build." + call skip_the_build +) + +cd "%ROOT%\third_party\benchmark\" +set "GOOGLETEST_PATH=%ROOT%\third_party\googletest" +if not exist "build" ( + mkdir build +) +cd build + +REM By default we generate the project for the older Visual Studio 2017 even if we have newer version installed +cmake ../ -G %CMAKE_GEN% -Ax64 -DBENCHMARK_ENABLE_TESTING=OFF +set SOLUTION=%ROOT%\third_party\benchmark\build\benchmark.sln +msbuild %SOLUTION% /maxcpucount:%MAXCPUCOUNT% /p:Configuration=Debug /p:Platform=x64 +msbuild %SOLUTION% /maxcpucount:%MAXCPUCOUNT% /p:Configuration=Release /p:Platform=x64 +popd + +:skip_the_build diff --git a/tools/build-gtest.sh b/tools/build-gtest.sh new file mode 100644 index 0000000000..d2573b885a --- /dev/null +++ b/tools/build-gtest.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +if [ "$1" == "ios" ]; then + IOS_BUILD="YES" + # Skip building tests on iOS as there is no way to run them + BUILD_TESTS="OFF" +else + IOS_BUILD="NO" + BUILD_TESTS="ON" +fi + +pushd `dirname $0`/.. +cd third_party/googletest +set -evx +env | sort +rm -rf build +mkdir -p build || true +cd build +cmake -Dgtest_build_samples=OFF \ + -Dgmock_build_samples=OFF \ + -Dgtest_build_tests=OFF \ + -Dgmock_build_tests=OFF \ + -DCMAKE_CXX_FLAGS="-fPIC $CXX_FLAGS" \ + -DBUILD_IOS=$IOS_BUILD \ + -DCMAKE_CXX_STANDARD=17 \ + .. +make +make install +popd diff --git a/tools/build-vs2015.cmd b/tools/build-vs2015.cmd new file mode 100644 index 0000000000..a80ca66409 --- /dev/null +++ b/tools/build-vs2015.cmd @@ -0,0 +1,6 @@ +set "VS_TOOLS_VERSION=vs2015" +REM Ref. https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2014%202015.html +set "CMAKE_GEN=Visual Studio 14 2015 Win64" +cd %~dp0 +call setup-buildtools.cmd +call build.cmd -DWITH_ABSEIL:BOOL=ON diff --git a/tools/build-vs2017.cmd b/tools/build-vs2017.cmd new file mode 100644 index 0000000000..be4322892c --- /dev/null +++ b/tools/build-vs2017.cmd @@ -0,0 +1,5 @@ +set "VS_TOOLS_VERSION=vs2017" +set "CMAKE_GEN=Visual Studio 15 2017 Win64" +cd %~dp0 +call setup-buildtools.cmd +call build.cmd diff --git a/tools/build-vs2019.cmd b/tools/build-vs2019.cmd new file mode 100644 index 0000000000..554c291a31 --- /dev/null +++ b/tools/build-vs2019.cmd @@ -0,0 +1,5 @@ +set "VS_TOOLS_VERSION=vs2019" +set "CMAKE_GEN=Visual Studio 16 2019" +cd %~dp0 +call setup-buildtools.cmd +call build.cmd diff --git a/tools/build.cmd b/tools/build.cmd new file mode 100644 index 0000000000..e49bc14289 --- /dev/null +++ b/tools/build.cmd @@ -0,0 +1,74 @@ +@echo off +REM Currently we require Visual Studio 2019 for C++20 build targeting Release/x64. +REM +REM TODO: allow specifying compiler version as argument. +REM +REM Supported versions for nostd build: +REM - vs2015 (C++11) +REM - vs2017 (C++14) +REM - vs2019 (C++20) +REM +REM Supported versions for STL build: +REM - vs2017 (C++14) +REM - vs2019 (C++20) +REM + +if "%VS_TOOLS_VERSION%" == "" set "VS_TOOLS_VERSION=vs2019" +if "%CMAKE_GEN%" == "" set "CMAKE_GEN=Visual Studio 16 2019" + +pushd %~dp0 +setlocal enableextensions +setlocal enabledelayedexpansion +set "ROOT=%~dp0\.." + +REM Use preinstalled vcpkg if installed or use our local +if "%VCPKG_INSTALLATION_ROOT%" neq "" ( + set "VCPKG_CMAKE=%VCPKG_INSTALLATION_ROOT%\scripts\buildsystems\vcpkg.cmake" +) else ( + set "VCPKG_CMAKE=%CD%\vcpkg\scripts\buildsystems\vcpkg.cmake" +) + +REM ******************************************************************** +REM Setup compiler environment +REM ******************************************************************** +call "%~dp0\vcvars.cmd" + + +REM ******************************************************************** +REM Use cmake +REM ******************************************************************** +set "PATH=%PATH%;C:\Program Files\CMake\bin\" + +REM ******************************************************************** +REM Build with nostd implementation +REM ******************************************************************** +set CONFIG=-DWITH_STL:BOOL=OFF %* +set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\nostd" +call :build_config + +REM ******************************************************************** +REM Build with STL implementation - only for vs2017+ +REM ******************************************************************** +if "%VS_TOOLS_VERSION%" neq "vs2015" ( + set CONFIG=-DWITH_STL:BOOL=ON + set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\stl" + call :build_config +) + +popd +REM ******************************************************************** + + +REM ******************************************************************** +REM Function that allows to build given build configuration +REM ******************************************************************** +:build_config +REM TODO: consider rmdir for clean builds +if not exist "%OUTDIR%" mkdir "%OUTDIR%" +cd "%OUTDIR%" +REM Optional platform specification parameter below: -Ax64 +cmake %ROOT% -G "%CMAKE_GEN%" -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +set "SOLUTION=%OUTDIR%\opentelemetry-cpp.sln" +REM TODO: allow building [Release|Debug]x[Win32|x64|ARM|ARM64] +msbuild "%SOLUTION%" /p:Configuration=Release /p:Platform=x64 /p:VcpkgEnabled=true +exit /b 0 diff --git a/tools/build.sh b/tools/build.sh new file mode 100644 index 0000000000..fda44d9208 --- /dev/null +++ b/tools/build.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +export PATH=/usr/local/bin:$PATH + +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +cd $WORKSPACE_ROOT +echo "Current directory is `pwd`" + +export NOROOT=$NOROOT + +if [ "$1" == "clean" ]; then + rm -f CMakeCache.txt *.cmake + rm -rf out + rm -rf .buildtools +# make clean +fi + +if [ "$1" == "noroot" ] || [ "$2" == "noroot" ]; then +export NOROOT=true +fi + +if [ "$1" == "release" ] || [ "$2" == "release" ]; then +BUILD_TYPE="release" +else +BUILD_TYPE="debug" +fi + +# Set target MacOS minver +export MACOSX_DEPLOYMENT_TARGET=10.10 + +# Install build tools +FILE=.buildtools +OS_NAME=`uname -a` +if [ ! -f $FILE ]; then +case "$OS_NAME" in + *Darwin*) tools/setup-buildtools-mac.sh ;; + *Linux*) [[ -z "$NOROOT" ]] && sudo tools/setup-buildtools.sh || echo "No root: skipping build tools installation." ;; + *) echo "WARNING: unsupported OS $OS_NAME , skipping build tools installation.." +esac +# Assume that the build tools have been successfully installed +echo > $FILE +fi + +# TODO: fix compiler-version reporting +if [ -f /usr/bin/gcc ]; then +echo "gcc version: `gcc --version`" +COMPILER_NAME=gcc-`gcc -dumpversion` +fi + +if [ -f /usr/bin/clang ]; then +echo "clang version: `clang --version`" +COMPILER_NAME=clang-`clang -dumpversion` +fi + +# TODO: do we need to build and install Google Test? +# tools/build-gtest.sh + +# +# Do the build for both configurations: WITH_STL=OFF and WITH_STL=ON +# +function build_configuration { + BUILD_CONFIG=$1 + BUILD_OPTIONS=$2 + + echo "Build configuration: $BUILD_CONFIG" + cd $WORKSPACE_ROOT + OUTDIR=out/$COMPILER_NAME/$BUILD_CONFIG + mkdir -p $OUTDIR + cmake -B $OUTDIR $BUILD_OPTIONS + cd $OUTDIR + make +} + +build_configuration nostd '-DWITH_STL:BOOL=OFF' +build_configuration stl '-DWITH_STL:BOOL=ON' diff --git a/tools/download.cmd b/tools/download.cmd new file mode 100644 index 0000000000..97f546863b --- /dev/null +++ b/tools/download.cmd @@ -0,0 +1,3 @@ +@REM This script allows to download a file to local machine. First argument is URL +set "PATH=C:\Windows;C:\Windows\System32;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\bin" +@powershell -File Download.ps1 %1 diff --git a/tools/download.ps1 b/tools/download.ps1 new file mode 100644 index 0000000000..c759601aea --- /dev/null +++ b/tools/download.ps1 @@ -0,0 +1,4 @@ +$url=$args[0] +$arr=$args[0].Split("/") +$fileName=$arr[$arr.Count-1] +Invoke-WebRequest -Uri $url -OutFile $fileName -UseBasicParsing diff --git a/tools/format.sh b/tools/format.sh index 7d5249d5e3..6fc4a4ae42 100755 --- a/tools/format.sh +++ b/tools/format.sh @@ -6,7 +6,7 @@ fi set -e -FIND="find . -name .git -prune -o -name _deps -prune -o -name .build -prune -o" +FIND="find . -name third_party -prune -o -name tools -prune -o -name .git -prune -o -name _deps -prune -o -name .build -prune -o" # GNU syntax. SED=(sed -i) diff --git a/tools/install-vs-addons.cmd b/tools/install-vs-addons.cmd new file mode 100644 index 0000000000..e4c866be33 --- /dev/null +++ b/tools/install-vs-addons.cmd @@ -0,0 +1,39 @@ +set "PATH=C:\Windows;C:\Windows\System32;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\bin" +cd %~dp0 +call powershell -File .\install_llvm-win64.ps1 + +REM Download Visual Studio LLVM extension required for clang build to succeed +call download.cmd https://llvmextensions.gallerycdn.vsassets.io/extensions/llvmextensions/llvm-toolchain/1.0.363769/1560930595399/llvm.vsix + +REM Install optional components required for ARM build - vs2017-BuildTools +IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" ( +"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^ + -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" -q ^ + --add Microsoft.VisualStudio.Component.VC.ATL ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 +"%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\Common7\IDE\VSIXInstaller.exe" /q /a llvm.vsix +) + +REM Install optional components required for ARM build - vs2017-Enterprise +IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" ( +"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^ + -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" -q ^ + --add Microsoft.VisualStudio.Component.VC.ATL ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 +"%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VSIXInstaller.exe" /q /a llvm.vsix +) + +REM Install optional components required for ARM build - vs2019-Enterprise +IF EXIST %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise ( +"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe" ^ + -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise" -q ^ + --add Microsoft.VisualStudio.Component.VC.ATL ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 +"%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VSIXInstaller.exe" /q /a llvm.vsix +) + +REM Ignore failures if components have been already installed +EXIT /b 0 diff --git a/tools/install_llvm-win32.ps1 b/tools/install_llvm-win32.ps1 new file mode 100644 index 0000000000..89b697f400 --- /dev/null +++ b/tools/install_llvm-win32.ps1 @@ -0,0 +1,8 @@ +$llvmVersion = "10.0.0" +Write-Host "Installing LLVM $llvmVersion ..." -ForegroundColor Cyan +Write-Host "Downloading..." +$exePath = "$env:temp\LLVM-$llvmVersion-win32.exe" +(New-Object Net.WebClient).DownloadFile("https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvmVersion/LLVM-$llvmVersion-win32.exe", $exePath) +Write-Host "Installing..." +cmd /c start /wait $exePath /S +Write-Host "Installed" -ForegroundColor Green diff --git a/tools/install_llvm-win64.ps1 b/tools/install_llvm-win64.ps1 new file mode 100644 index 0000000000..d4a2379fa2 --- /dev/null +++ b/tools/install_llvm-win64.ps1 @@ -0,0 +1,8 @@ +$llvmVersion = "10.0.0" +Write-Host "Installing LLVM $llvmVersion ..." -ForegroundColor Cyan +Write-Host "Downloading..." +$exePath = "$env:temp\LLVM-$llvmVersion-win64.exe" +(New-Object Net.WebClient).DownloadFile("https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvmVersion/LLVM-$llvmVersion-win64.exe", $exePath) +Write-Host "Installing..." +cmd /c start /wait $exePath /S +Write-Host "Installed" -ForegroundColor Green diff --git a/tools/ports/benchmark/CONTROL b/tools/ports/benchmark/CONTROL new file mode 100644 index 0000000000..62b80dffae --- /dev/null +++ b/tools/ports/benchmark/CONTROL @@ -0,0 +1,5 @@ +Source: benchmark +Version: 1.5.1 +Homepage: https://github.com/google/benchmark +Description: A library to support the benchmarking of functions, similar to unit-tests. +Supports: !uwp \ No newline at end of file diff --git a/tools/ports/benchmark/portfile.cmake b/tools/ports/benchmark/portfile.cmake new file mode 100644 index 0000000000..e89fafca6c --- /dev/null +++ b/tools/ports/benchmark/portfile.cmake @@ -0,0 +1,49 @@ +if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + message(FATAL_ERROR "${PORT} does not currently support UWP") +endif() + +if (VCPKG_PLATFORM_TOOLSET STREQUAL "v140") + # set(CMAKE_C_COMPILER_WORKS 1) + # set(CMAKE_CXX_COMPILER_WORKS 1) + set(CMAKE_C_COMPILER cl.exe) + set(CMAKE_CXX_COMPILER cl.exe) + set(MSVC_TOOLSET_VERSION 140) + # set(VCPKG_VISUAL_STUDIO_PATH "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0") + # set(VCPKG_PLATFORM_TOOLSET v140) +else() + # Make sure vs2019 compiled binaries are compat with vs2017 + set(VCPKG_CXX_FLAGS "/Zc:__cplusplus /d2FH4-") + set(VCPKG_C_FLAGS "/Zc:__cplusplus /d2FH4-") + set(PREFER PREFER_NINJA) +endif() + +include(vcpkg_common_functions) + +vcpkg_check_linkage(ONLY_STATIC_LIBRARY) + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO google/benchmark + HEAD_REF master +) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + ${PREFER} + OPTIONS + -DBENCHMARK_ENABLE_TESTING=OFF + -DCMAKE_DEBUG_POSTFIX=d +) + +vcpkg_install_cmake() + +vcpkg_copy_pdbs() + +vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/benchmark) + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share) + +# Handle copyright +file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/benchmark) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/benchmark/LICENSE ${CURRENT_PACKAGES_DIR}/share/benchmark/copyright) diff --git a/tools/setup-buildtools-mac.sh b/tools/setup-buildtools-mac.sh index aee85a456f..ee14680409 100644 --- a/tools/setup-buildtools-mac.sh +++ b/tools/setup-buildtools-mac.sh @@ -24,8 +24,10 @@ sudo chown -R $(whoami) /usr/local/var/homebrew sudo chown -R $(whoami) /usr/local/etc/bash_completion.d /usr/local/include /usr/local/lib/pkgconfig /usr/local/share/aclocal /usr/local/share/locale /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew/locks brew install cmake +brew install coreutils brew install wget brew install clang-format brew install google-benchmark brew tap nlohmann/json brew install nlohmann-json +./tools/build-gtest.sh diff --git a/tools/setup-buildtools.cmd b/tools/setup-buildtools.cmd new file mode 100644 index 0000000000..830c650c07 --- /dev/null +++ b/tools/setup-buildtools.cmd @@ -0,0 +1,50 @@ +@echo off +set "PATH=%PATH%;%~dp0;%~dp0\vcpkg" +pushd %~dp0 + +REM Fail if chocolatey is not installed +where /Q choco +if ERRORLEVEL 1 ( + echo This script requires chocolatey. Installation instructions: https://chocolatey.org/docs/installation + exit -1 +) + +REM Print current Visual Studio installations detected +where /Q vswhere +if ERRORLEVEL 0 ( + echo Visual Studio installations detected: + vswhere -property installationPath +) + +REM Install tools needed for building stuff +choco install -y cmake +choco install -y svn +choco install -y git +choco install -y llvm +choco install -y zip + +REM Try to autodetect Visual Studio +call "%~dp0\vcvars.cmd" +if "%TOOLS_VS_NOTFOUND%" == "1" ( + REM Cannot detect MSBuild path + REM TODO: no command line tools.. + REM TODO: use MSBuild from vswhere? +) + +where /Q vcpkg.exe +if ERRORLEVEL 1 ( + REM Build our own vcpkg from source + pushd .\vcpkg + call bootstrap-vcpkg.bat + popd +) + +REM Install it +vcpkg install gtest:x64-windows +vcpkg install --head --overlay-ports=%~dp0\ports benchmark:x64-windows +vcpkg install ms-gsl:x64-windows +vcpkg install nlohmann-json:x64-windows +vcpkg install abseil:x64-windows +vcpkg integrate install +popd +exit /b 0 diff --git a/tools/setup-buildtools.sh b/tools/setup-buildtools.sh index f118e16070..a5fe2c5f0c 100644 --- a/tools/setup-buildtools.sh +++ b/tools/setup-buildtools.sh @@ -22,13 +22,6 @@ yum -y install devtoolset-7-valgrind yum-config-manager --enable rhel-server-rhscl-7-rpms -if [ `gcc --version | grep 7` == "" ]; then -echo "*********************************************************" -echo "*** Please make sure you start the build with gcc-7 ***" -echo "*** > scl enable devtoolset-7 ./build.sh ***" -echo "*********************************************************" -exit 3 -fi if [ `cmake --version | grep 3` == "" ]; then yum -y remove cmake @@ -59,7 +52,13 @@ apt-get install -qq libsqlite3-dev #apt install libsqlite3-dev apt-get install -qq wget apt-get install -qq clang-format +apt-get install -qq gtest +apt-get install -qq libgtest-dev +apt-get install -qq libbenchmark-dev +apt-get install -qq nlohmann-json-dev fi ## Change owner from root to current dir owner chown -R `stat . -c %u:%g` * + +./tools/build-gtest.sh diff --git a/tools/vcvars.cmd b/tools/vcvars.cmd new file mode 100644 index 0000000000..1b8215fcbb --- /dev/null +++ b/tools/vcvars.cmd @@ -0,0 +1,86 @@ +@echo off +REM +REM Make sure to enable the 'Visual C++ ATL' components for all platforms during the setup. +REM +REM This build script auto-detects and configures Visual Studio in the following order: +REM 1. Visual Studio 2017 Enterprise +REM 2. Visual Studio 2017 BuildTools +REM 3. Visual Studio 2019 Enterprise +REM 4. Visual Studio 2019 Community +REM 5. Visual Studio 2019 BuildTools +REM + +REM 1st parameter - Visual Studio version +if "%1" neq "" ( + goto %1 +) + +if "%VS_TOOLS_VERSION%" neq "" ( + goto %VS_TOOLS_VERSION% +) + +REM vs2017 Enterprise +:vs2017 +:vs2017_enterprise +set TOOLS_VS2017_ENTERPRISE="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2017_ENTERPRISE% ( + echo Building with vs2017 Enterprise... + call %TOOLS_VS2017_ENTERPRISE% + goto tools_configured +) + +REM vs2017 BuildTools +:vs2017_buildtools +set TOOLS_VS2017="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2017% ( + echo Building with vs2017 BuildTools... + call %TOOLS_VS2017% + goto tools_configured +) + +REM vs2019 Enterprise +:vs2019 +:vs2019_enterprise +set TOOLS_VS2019_ENTERPRISE="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2019_ENTERPRISE% ( + echo Building with vs2019 Enterprise... + call %TOOLS_VS2019_ENTERPRISE% + goto tools_configured +) + +REM vs2019 Community +:vs2019_community +set TOOLS_VS2019_COMMUNITY="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2019_COMMUNITY% ( + echo Building with vs2019 Community... + call %TOOLS_VS2019_COMMUNITY% + goto tools_configured +) + +REM vs2019 BuildTools +:vs2019_buildtools +set TOOLS_VS2019="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2019% ( + echo Building with vs2019 BuildTools... + call %TOOLS_VS2019% + goto tools_configured +) + +REM vs2015 +:vs2015 +set TOOLS_VS2015="%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat" +if exist %TOOLS_VS2015% ( + echo Building with vs2015 BuildTools... + call %TOOLS_VS2015% + set "VCPKG_VISUAL_STUDIO_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0" + set VCPKG_PLATFORM_TOOLSET=v140 + goto tools_configured +) + +echo WARNING:********************************************* +echo WARNING: cannot auto-detect Visual Studio version !!! +echo WARNING:********************************************* +set TOOLS_VS_NOTFOUND=1 +exit /b 0 + +:tools_configured From 65f184e131164ea68fba534a781f08801ebde837 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 26 Oct 2020 15:15:59 -0700 Subject: [PATCH 02/54] Format using older format tools that are running in CI --- .github/workflows/ci.yml | 640 +++++++++++----------- .gitmodules | 20 +- CMakeLists.txt | 2 +- api/test/context/CMakeLists.txt | 5 +- api/test/core/CMakeLists.txt | 6 +- api/test/metrics/CMakeLists.txt | 5 +- api/test/nostd/BUILD | 158 +++--- api/test/nostd/CMakeLists.txt | 5 +- api/test/nostd/shared_ptr_test.cc | 408 +++++++------- api/test/nostd/span_test.cc | 492 ++++++++--------- api/test/nostd/string_view_test.cc | 430 +++++++-------- api/test/plugin/CMakeLists.txt | 6 +- api/test/trace/CMakeLists.txt | 6 +- api/test/trace/propagation/CMakeLists.txt | 5 +- docs/abi-compatibility.md | 70 +-- docs/building-with-stdlib.md | 204 +++---- examples/plugin/plugin/tracer.cc | 144 ++--- exporters/memory/CMakeLists.txt | 12 +- exporters/ostream/CMakeLists.txt | 12 +- exporters/otlp/CMakeLists.txt | 6 +- exporters/prometheus/test/CMakeLists.txt | 6 +- ext/test/zpages/CMakeLists.txt | 5 +- sdk/src/common/BUILD | 64 +-- sdk/src/common/core.cc | 24 +- sdk/src/trace/tracer_provider.cc | 80 +-- sdk/test/common/CMakeLists.txt | 5 +- sdk/test/metrics/CMakeLists.txt | 5 +- sdk/test/trace/CMakeLists.txt | 5 +- 28 files changed, 1394 insertions(+), 1436 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aaaf635f14..8f8cd06a70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,320 +1,320 @@ -name: CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - cmake_test: - name: CMake test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - - name: run tests - run: ./ci/do_ci.sh cmake.test - - name: run prometheus exporter tests - run: ./ci/do_ci.sh cmake.exporter.prometheus.test - - cmake_gcc_48_test: - name: CMake gcc 4.8 - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_gcc48.sh - - name: setup cmake - run: | - sudo CC=/usr/bin/gcc-4.8 CXX=/usr/bin/g++-4.8 ./ci/setup_cmake.sh - - name: run tests - run: ./ci/do_ci.sh cmake.legacy.test - env: - CC: /usr/bin/gcc-4.8 - CXX: /usr/bin/g++-4.8 - - cmake_test_cxx20: - name: CMake C++20 test - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/setup_cmake.sh - - name: run tests - run: ./ci/do_ci.sh cmake.c++20.test - - cmake_posix: - name: Build on ${{ matrix.os }} ${{ matrix.config }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - config: [release] - os: [ubuntu-18.04, ubuntu-20.04, macos-latest] - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: build - run: tools/build.sh ${{ matrix.config }} - - # TODO #1: add vs2015 - # TODO #2: consolidate cmake_[vs2015|vs2017|vs2019] into one matrix build - cmake_windows_vs2017: - name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - arch: [x64] - config: [release] - os: [windows-2016] - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: Setup build tools - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\setup-buildtools.cmd - - name: Build - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\build-vs2017.cmd ${{ matrix.config }} - - cmake_windows_vs2019: - name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - arch: [x64] - config: [release] - os: [windows-2019] - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: Setup build tools - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\setup-buildtools.cmd - - name: Build - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\build-vs2017.cmd ${{ matrix.config }} - - plugin_test: - name: Plugin -> CMake - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - - name: run tests - run: ./ci/do_ci.sh cmake.test_example_plugin - - gcc_48_test: - name: Legacy Bazel - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - sudo ./ci/install_gcc48.sh - - name: run tests - run: ./ci/do_ci.sh bazel.legacy.test - env: - CC: /usr/bin/gcc-4.8 - - bazel_test: - name: Bazel - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.test - - bazel_valgrind: - name: Bazel valgrind - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.valgrind - - bazel_noexcept: - name: Bazel noexcept - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.noexcept - - bazel_asan: - name: Bazel asan config - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.asan - - bazel_tsan: - name: Bazel tsan config - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: ./ci/do_ci.sh bazel.tsan - - bazel_osx: - name: Bazel on MacOS - runs-on: macos-latest - steps: - - uses: actions/checkout@v2 - - name: run tests - run: ./ci/do_ci.sh bazel.test - - benchmark: - name: Benchmark - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_bazelisk.sh - - name: run tests - run: | - env BENCHMARK_DIR=/benchmark - ./ci/do_ci.sh benchmark - - name: Upload benchmark results - uses: actions/upload-artifact@v2 - with: - name: benchmark_reports - path: /home/runner/benchmark - - format: - name: Format - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: sudo ./ci/install_format_tools.sh - - name: run tests - run: ./ci/do_ci.sh format - - windows: - name: CMake -> exporter proto - runs-on: windows-2019 - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: setup - run: | - ./ci/setup_windows_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - ./ci/install_windows_protobuf.ps1 - - name: run cmake test - run: ./ci/do_ci.ps1 cmake.test - - name: run otprotocol test - run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.test - - windows_bazel: - name: Bazel Windows - runs-on: windows-2019 - steps: - - uses: actions/checkout@v2 - - name: setup - run: ./ci/install_windows_bazelisk.ps1 - - name: run tests - run: ./ci/do_ci.ps1 bazel.build - - windows_plugin_test: - name: Plugin -> CMake Windows - runs-on: windows-2019 - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: setup - run: | - ./ci/setup_windows_cmake.ps1 - ./ci/setup_windows_ci_environment.ps1 - - name: run tests - run: ./ci/do_ci.ps1 cmake.test_example_plugin - - code_coverage: - name: Code coverage - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: setup - run: | - sudo ./ci/setup_cmake.sh - sudo ./ci/setup_ci_environment.sh - - name: run tests and generate report - run: ./ci/do_ci.sh code.coverage - - name: upload report - uses: codecov/codecov-action@v1 - with: - file: /home/runner/build/coverage.info - - docfx_check: - name: DocFX check - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - name: install docfx - run: choco install docfx -y - - name: run ./ci/docfx.cmd - shell: cmd - run: ./ci/docfx.cmd +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + cmake_test: + name: CMake test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + - name: run tests + run: ./ci/do_ci.sh cmake.test + - name: run prometheus exporter tests + run: ./ci/do_ci.sh cmake.exporter.prometheus.test + + cmake_gcc_48_test: + name: CMake gcc 4.8 + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_gcc48.sh + - name: setup cmake + run: | + sudo CC=/usr/bin/gcc-4.8 CXX=/usr/bin/g++-4.8 ./ci/setup_cmake.sh + - name: run tests + run: ./ci/do_ci.sh cmake.legacy.test + env: + CC: /usr/bin/gcc-4.8 + CXX: /usr/bin/g++-4.8 + + cmake_test_cxx20: + name: CMake C++20 test + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_ci_environment.sh + sudo ./ci/setup_cmake.sh + - name: run tests + run: ./ci/do_ci.sh cmake.c++20.test + + cmake_posix: + name: Build on ${{ matrix.os }} ${{ matrix.config }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + config: [release] + os: [ubuntu-18.04, ubuntu-20.04, macos-latest] + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: build + run: tools/build.sh ${{ matrix.config }} + + # TODO #1: add vs2015 + # TODO #2: consolidate cmake_[vs2015|vs2017|vs2019] into one matrix build + cmake_windows_vs2017: + name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + arch: [x64] + config: [release] + os: [windows-2016] + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: 'true' + - name: Setup build tools + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\setup-buildtools.cmd + - name: Build + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\build-vs2017.cmd ${{ matrix.config }} + + cmake_windows_vs2019: + name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + arch: [x64] + config: [release] + os: [windows-2019] + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: 'true' + - name: Setup build tools + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\setup-buildtools.cmd + - name: Build + run: | + cd "$Env:GITHUB_WORKSPACE" + .\tools\build-vs2017.cmd ${{ matrix.config }} + + plugin_test: + name: Plugin -> CMake + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + - name: run tests + run: ./ci/do_ci.sh cmake.test_example_plugin + + gcc_48_test: + name: Legacy Bazel + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + sudo ./ci/install_gcc48.sh + - name: run tests + run: ./ci/do_ci.sh bazel.legacy.test + env: + CC: /usr/bin/gcc-4.8 + + bazel_test: + name: Bazel + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.test + + bazel_valgrind: + name: Bazel valgrind + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.valgrind + + bazel_noexcept: + name: Bazel noexcept + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.noexcept + + bazel_asan: + name: Bazel asan config + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.asan + + bazel_tsan: + name: Bazel tsan config + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.tsan + + bazel_osx: + name: Bazel on MacOS + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: run tests + run: ./ci/do_ci.sh bazel.test + + benchmark: + name: Benchmark + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: | + env BENCHMARK_DIR=/benchmark + ./ci/do_ci.sh benchmark + - name: Upload benchmark results + uses: actions/upload-artifact@v2 + with: + name: benchmark_reports + path: /home/runner/benchmark + + format: + name: Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: sudo ./ci/install_format_tools.sh + - name: run tests + run: ./ci/do_ci.sh format + + windows: + name: CMake -> exporter proto + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + ./ci/setup_windows_cmake.ps1 + ./ci/setup_windows_ci_environment.ps1 + ./ci/install_windows_protobuf.ps1 + - name: run cmake test + run: ./ci/do_ci.ps1 cmake.test + - name: run otprotocol test + run: ./ci/do_ci.ps1 cmake.exporter.otprotocol.test + + windows_bazel: + name: Bazel Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + - name: setup + run: ./ci/install_windows_bazelisk.ps1 + - name: run tests + run: ./ci/do_ci.ps1 bazel.build + + windows_plugin_test: + name: Plugin -> CMake Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + - name: setup + run: | + ./ci/setup_windows_cmake.ps1 + ./ci/setup_windows_ci_environment.ps1 + - name: run tests + run: ./ci/do_ci.ps1 cmake.test_example_plugin + + code_coverage: + name: Code coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup + run: | + sudo ./ci/setup_cmake.sh + sudo ./ci/setup_ci_environment.sh + - name: run tests and generate report + run: ./ci/do_ci.sh code.coverage + - name: upload report + uses: codecov/codecov-action@v1 + with: + file: /home/runner/build/coverage.info + + docfx_check: + name: DocFX check + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: install docfx + run: choco install docfx -y + - name: run ./ci/docfx.cmd + shell: cmd + run: ./ci/docfx.cmd diff --git a/.gitmodules b/.gitmodules index 5744efc614..e1d94ec89a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,22 +1,22 @@ -[submodule "third_party/prometheus-cpp"] - path = third_party/prometheus-cpp - url = https://github.com/jupp0r/prometheus-cpp.git - +[submodule "third_party/prometheus-cpp"] + path = third_party/prometheus-cpp + url = https://github.com/jupp0r/prometheus-cpp.git + [submodule "tools/vcpkg"] path = tools/vcpkg url = https://github.com/Microsoft/vcpkg - branch = master - + branch = master + [submodule "third_party/ms-gsl"] path = third_party/ms-gsl url = https://github.com/microsoft/GSL - branch = master - + branch = master + [submodule "third_party/googletest"] path = third_party/googletest url = https://github.com/google/googletest - branch = master - + branch = master + [submodule "third_party/benchmark"] path = third_party/benchmark url = https://github.com/google/benchmark diff --git a/CMakeLists.txt b/CMakeLists.txt index 313657d5fb..428128565e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(WITH_STL) set(CMAKE_CXX_STANDARD 20) # Guidelines Support Library path. Used if we are not on not get C++20. - # + # # TODO: respect WITH_ABSEIL as alternate implementation of std::span set(GSL_DIR third_party/ms-gsl) include_directories(${GSL_DIR}/include) diff --git a/api/test/context/CMakeLists.txt b/api/test/context/CMakeLists.txt index 2c9da11191..15d91c689b 100644 --- a/api/test/context/CMakeLists.txt +++ b/api/test/context/CMakeLists.txt @@ -5,8 +5,5 @@ foreach(testname context_test runtime_context_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX context. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX context. TEST_LIST ${testname}) endforeach() diff --git a/api/test/core/CMakeLists.txt b/api/test/core/CMakeLists.txt index 0d59831bb4..79d3a1e331 100644 --- a/api/test/core/CMakeLists.txt +++ b/api/test/core/CMakeLists.txt @@ -4,7 +4,5 @@ add_executable(timestamp_test timestamp_test.cc) target_link_libraries( timestamp_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) -gtest_add_tests( - TARGET timestamp_test - TEST_PREFIX trace. - TEST_LIST timestamp_test) +gtest_add_tests(TARGET timestamp_test TEST_PREFIX trace. TEST_LIST + timestamp_test) diff --git a/api/test/metrics/CMakeLists.txt b/api/test/metrics/CMakeLists.txt index f20a46c094..b73b772ce3 100644 --- a/api/test/metrics/CMakeLists.txt +++ b/api/test/metrics/CMakeLists.txt @@ -3,8 +3,5 @@ foreach(testname noop_instrument_test meter_provider_test noop_metrics_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX metrics. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) endforeach() diff --git a/api/test/nostd/BUILD b/api/test/nostd/BUILD index 107512108c..c42d2b9255 100644 --- a/api/test/nostd/BUILD +++ b/api/test/nostd/BUILD @@ -1,79 +1,79 @@ -cc_test( - name = "function_ref_test", - srcs = [ - "function_ref_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "string_view_test", - srcs = [ - "string_view_test.cc", - ], - deps = [ - "//api", - "@com_github_google_benchmark//:benchmark", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "variant_test", - srcs = [ - "variant_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "unique_ptr_test", - srcs = [ - "unique_ptr_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "utility_test", - srcs = [ - "utility_test.cc", - ], - deps = [ - "//api", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "span_test", - srcs = [ - "span_test.cc", - ], - deps = [ - "//api", - "@com_github_google_benchmark//:benchmark", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "shared_ptr_test", - srcs = [ - "shared_ptr_test.cc", - ], - deps = [ - "//api", - "@com_github_google_benchmark//:benchmark", - "@com_google_googletest//:gtest_main", - ], -) +cc_test( + name = "function_ref_test", + srcs = [ + "function_ref_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "string_view_test", + srcs = [ + "string_view_test.cc", + ], + deps = [ + "//api", + "@com_github_google_benchmark//:benchmark", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "variant_test", + srcs = [ + "variant_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "unique_ptr_test", + srcs = [ + "unique_ptr_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "utility_test", + srcs = [ + "utility_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "span_test", + srcs = [ + "span_test.cc", + ], + deps = [ + "//api", + "@com_github_google_benchmark//:benchmark", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "shared_ptr_test", + srcs = [ + "shared_ptr_test.cc", + ], + deps = [ + "//api", + "@com_github_google_benchmark//:benchmark", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index 096da4b48b..dc683c6483 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -6,8 +6,5 @@ foreach(testname function_ref_test string_view_test unique_ptr_test target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} benchmark::benchmark ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX nostd. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX nostd. TEST_LIST ${testname}) endforeach() diff --git a/api/test/nostd/shared_ptr_test.cc b/api/test/nostd/shared_ptr_test.cc index a453a18456..ffc9816f5b 100644 --- a/api/test/nostd/shared_ptr_test.cc +++ b/api/test/nostd/shared_ptr_test.cc @@ -1,204 +1,204 @@ -#include "opentelemetry/nostd/shared_ptr.h" - -#include -#include -#include - -using opentelemetry::nostd::shared_ptr; - -class A -{ -public: - explicit A(bool &destructed) noexcept : destructed_{destructed} { destructed_ = false; } - - ~A() { destructed_ = true; } - -private: - bool &destructed_; -}; - -class B -{ -public: - int f() const { return 123; } -}; - -class C -{ -public: - virtual ~C() {} -}; - -class D : public C -{ -public: - virtual ~D() {} -}; - -TEST(SharedPtrTest, DefaultConstruction) -{ - shared_ptr ptr1; - EXPECT_EQ(ptr1.get(), nullptr); - - shared_ptr ptr2{nullptr}; - EXPECT_EQ(ptr2.get(), nullptr); -} - -TEST(SharedPtrTest, ExplicitConstruction) -{ - auto c = new C(); - shared_ptr ptr1{c}; - EXPECT_EQ(ptr1.get(), c); - - auto d = new D(); - shared_ptr ptr2{d}; - EXPECT_EQ(ptr2.get(), d); -} - -TEST(SharedPtrTest, MoveConstruction) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - shared_ptr ptr2{std::move(ptr1)}; - EXPECT_EQ(ptr1.get(), nullptr); - EXPECT_EQ(ptr2.get(), value); -} - -TEST(SharedPtrTest, MoveConstructionFromDifferentType) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - shared_ptr ptr2{std::move(ptr1)}; - EXPECT_EQ(ptr1.get(), nullptr); - EXPECT_EQ(ptr2.get(), value); -} - -TEST(SharedPtrTest, MoveConstructionFromStdSharedPtr) -{ - auto value = new int{123}; - std::shared_ptr ptr1{value}; - shared_ptr ptr2{std::move(ptr1)}; - EXPECT_EQ(ptr1.get(), nullptr); - EXPECT_EQ(ptr2.get(), value); -} - -TEST(SharedPtrTest, Destruction) -{ - bool was_destructed; - shared_ptr{new A{was_destructed}}; - EXPECT_TRUE(was_destructed); -} - -TEST(SharedPtrTest, Assignment) -{ - auto value = new int{123}; - shared_ptr ptr1; - - ptr1 = shared_ptr(value); - EXPECT_EQ(ptr1.get(), value); - - ptr1 = nullptr; - EXPECT_EQ(ptr1.get(), nullptr); - - auto value2 = new int{234}; - const shared_ptr ptr2 = shared_ptr(value2); - ptr1 = ptr2; - EXPECT_EQ(ptr1.get(), value2); - - auto value3 = new int{345}; - std::shared_ptr ptr3(value3); - ptr1 = ptr3; - EXPECT_EQ(ptr1.get(), value3); -} - -TEST(SharedPtrTest, BoolConversionOpertor) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - - EXPECT_TRUE(ptr1); - EXPECT_FALSE(shared_ptr{}); -} - -TEST(SharedPtrTest, PointerOperators) -{ - auto value = new int{123}; - shared_ptr ptr1{value}; - - EXPECT_EQ(&*ptr1, value); - EXPECT_EQ( - shared_ptr { new B }->f(), 123); -} - -TEST(SharedPtrTest, Swap) -{ - auto value1 = new int{123}; - shared_ptr ptr1{value1}; - - auto value2 = new int{456}; - shared_ptr ptr2{value2}; - ptr1.swap(ptr2); - - EXPECT_EQ(ptr1.get(), value2); - EXPECT_EQ(ptr2.get(), value1); -} - -TEST(SharedPtrTest, Comparison) -{ - shared_ptr ptr1{new int{123}}; - shared_ptr ptr2{new int{456}}; - shared_ptr ptr3{}; - - EXPECT_EQ(ptr1, ptr1); - EXPECT_NE(ptr1, ptr2); - - EXPECT_NE(ptr1, nullptr); - EXPECT_NE(nullptr, ptr1); - - EXPECT_EQ(ptr3, nullptr); - EXPECT_EQ(nullptr, ptr3); -} - -static void SharedPtrTest_Sort(size_t size = 10) -{ - std::vector> nums; - - for (int i = size; i > 0; i--) - { - nums.push_back(shared_ptr(new int(i))); - } - - auto nums2 = nums; - - std::sort(nums.begin(), nums.end(), - [](shared_ptr a, shared_ptr b) { return *a < *b; }); - - EXPECT_NE(nums, nums2); - - std::reverse(nums2.begin(), nums2.end()); - - EXPECT_EQ(nums, nums2); -} - -TEST(SharedPtrTest, Sort) -{ - SharedPtrTest_Sort(); -} - -static void SharedPtrTestSort(benchmark::State &state) -{ - for (auto _ : state) - { - SharedPtrTest_Sort(10000); - } -} -BENCHMARK(SharedPtrTestSort); - -TEST(SharedPtr, PerfTests) -{ - // Run all benchmarks - int argc = 0; - const char *argv[] = {""}; - ::benchmark::Initialize(&argc, (char **)(argv)); - ::benchmark::RunSpecifiedBenchmarks(); -} +#include "opentelemetry/nostd/shared_ptr.h" + +#include +#include +#include + +using opentelemetry::nostd::shared_ptr; + +class A +{ +public: + explicit A(bool &destructed) noexcept : destructed_{destructed} { destructed_ = false; } + + ~A() { destructed_ = true; } + +private: + bool &destructed_; +}; + +class B +{ +public: + int f() const { return 123; } +}; + +class C +{ +public: + virtual ~C() {} +}; + +class D : public C +{ +public: + virtual ~D() {} +}; + +TEST(SharedPtrTest, DefaultConstruction) +{ + shared_ptr ptr1; + EXPECT_EQ(ptr1.get(), nullptr); + + shared_ptr ptr2{nullptr}; + EXPECT_EQ(ptr2.get(), nullptr); +} + +TEST(SharedPtrTest, ExplicitConstruction) +{ + auto c = new C(); + shared_ptr ptr1{c}; + EXPECT_EQ(ptr1.get(), c); + + auto d = new D(); + shared_ptr ptr2{d}; + EXPECT_EQ(ptr2.get(), d); +} + +TEST(SharedPtrTest, MoveConstruction) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + shared_ptr ptr2{std::move(ptr1)}; + EXPECT_EQ(ptr1.get(), nullptr); + EXPECT_EQ(ptr2.get(), value); +} + +TEST(SharedPtrTest, MoveConstructionFromDifferentType) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + shared_ptr ptr2{std::move(ptr1)}; + EXPECT_EQ(ptr1.get(), nullptr); + EXPECT_EQ(ptr2.get(), value); +} + +TEST(SharedPtrTest, MoveConstructionFromStdSharedPtr) +{ + auto value = new int{123}; + std::shared_ptr ptr1{value}; + shared_ptr ptr2{std::move(ptr1)}; + EXPECT_EQ(ptr1.get(), nullptr); + EXPECT_EQ(ptr2.get(), value); +} + +TEST(SharedPtrTest, Destruction) +{ + bool was_destructed; + shared_ptr{new A{was_destructed}}; + EXPECT_TRUE(was_destructed); +} + +TEST(SharedPtrTest, Assignment) +{ + auto value = new int{123}; + shared_ptr ptr1; + + ptr1 = shared_ptr(value); + EXPECT_EQ(ptr1.get(), value); + + ptr1 = nullptr; + EXPECT_EQ(ptr1.get(), nullptr); + + auto value2 = new int{234}; + const shared_ptr ptr2 = shared_ptr(value2); + ptr1 = ptr2; + EXPECT_EQ(ptr1.get(), value2); + + auto value3 = new int{345}; + std::shared_ptr ptr3(value3); + ptr1 = ptr3; + EXPECT_EQ(ptr1.get(), value3); +} + +TEST(SharedPtrTest, BoolConversionOpertor) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + + EXPECT_TRUE(ptr1); + EXPECT_FALSE(shared_ptr{}); +} + +TEST(SharedPtrTest, PointerOperators) +{ + auto value = new int{123}; + shared_ptr ptr1{value}; + + EXPECT_EQ(&*ptr1, value); + EXPECT_EQ( + shared_ptr { new B }->f(), 123); +} + +TEST(SharedPtrTest, Swap) +{ + auto value1 = new int{123}; + shared_ptr ptr1{value1}; + + auto value2 = new int{456}; + shared_ptr ptr2{value2}; + ptr1.swap(ptr2); + + EXPECT_EQ(ptr1.get(), value2); + EXPECT_EQ(ptr2.get(), value1); +} + +TEST(SharedPtrTest, Comparison) +{ + shared_ptr ptr1{new int{123}}; + shared_ptr ptr2{new int{456}}; + shared_ptr ptr3{}; + + EXPECT_EQ(ptr1, ptr1); + EXPECT_NE(ptr1, ptr2); + + EXPECT_NE(ptr1, nullptr); + EXPECT_NE(nullptr, ptr1); + + EXPECT_EQ(ptr3, nullptr); + EXPECT_EQ(nullptr, ptr3); +} + +static void SharedPtrTest_Sort(size_t size = 10) +{ + std::vector> nums; + + for (int i = size; i > 0; i--) + { + nums.push_back(shared_ptr(new int(i))); + } + + auto nums2 = nums; + + std::sort(nums.begin(), nums.end(), + [](shared_ptr a, shared_ptr b) { return *a < *b; }); + + EXPECT_NE(nums, nums2); + + std::reverse(nums2.begin(), nums2.end()); + + EXPECT_EQ(nums, nums2); +} + +TEST(SharedPtrTest, Sort) +{ + SharedPtrTest_Sort(); +} + +static void SharedPtrTestSort(benchmark::State &state) +{ + for (auto _ : state) + { + SharedPtrTest_Sort(10000); + } +} +BENCHMARK(SharedPtrTestSort); + +TEST(SharedPtr, PerfTests) +{ + // Run all benchmarks + int argc = 0; + const char *argv[] = {""}; + ::benchmark::Initialize(&argc, (char **)(argv)); + ::benchmark::RunSpecifiedBenchmarks(); +} diff --git a/api/test/nostd/span_test.cc b/api/test/nostd/span_test.cc index f3a68167d9..6d484bccad 100644 --- a/api/test/nostd/span_test.cc +++ b/api/test/nostd/span_test.cc @@ -1,246 +1,246 @@ -#include "opentelemetry/nostd/span.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -using opentelemetry::nostd::span; - -TEST(SpanTest, DefaultConstruction) -{ - span s1; - EXPECT_EQ(s1.data(), nullptr); - EXPECT_EQ(s1.size(), 0); - EXPECT_TRUE(s1.empty()); - - span s2; - EXPECT_EQ(s2.data(), nullptr); - EXPECT_EQ(s2.size(), 0); - EXPECT_TRUE(s2.empty()); - - EXPECT_FALSE((std::is_default_constructible>::value)); -} - -TEST(SpanTest, Assignment) -{ - std::array array1 = {1, 2, 3}; - std::array array2 = {1, 2, 3}; - span s1{array1.data(), array1.size()}; - span s2{array1.data(), array1.size()}; - - span s3; - s3 = s1; - EXPECT_EQ(s3.data(), array1.data()); - EXPECT_EQ(s3.size(), array1.size()); - - span s4{array2}; - s4 = s2; - EXPECT_EQ(s4.data(), array1.data()); - EXPECT_EQ(s4.size(), array1.size()); -} - -TEST(SpanTest, PointerCountConstruction) -{ - std::array array = {1, 2, 3}; - - span s1{array.data(), array.size()}; - EXPECT_EQ(s1.data(), array.data()); - EXPECT_EQ(s1.size(), array.size()); - - span s2{array.data(), array.size()}; - EXPECT_EQ(s2.data(), array.data()); - EXPECT_EQ(s2.size(), array.size()); - -#ifndef HAVE_CPP_STDLIB - /* This test is not supposed to fail with STL. Why is this invalid construct? */ - EXPECT_DEATH((span{array.data(), array.size()}), ".*"); -#endif -} - -TEST(SpanTest, RangeConstruction) -{ - int array[] = {1, 2, 3}; - - span s1{std::begin(array), std::end(array)}; - EXPECT_EQ(s1.data(), array); - EXPECT_EQ(s1.size(), 3); - - span s2{std::begin(array), std::end(array)}; - EXPECT_EQ(s2.data(), array); - EXPECT_EQ(s2.size(), 3); - -#ifndef HAVE_CPP_STDLIB - /* This test is not supposed to fail with STL. Why is this invalid construct? */ - EXPECT_DEATH((span{std::begin(array), std::end(array)}), ".*"); -#endif -} - -TEST(SpanTest, ArrayConstruction) -{ - int array1[] = {1, 2, 3}; - std::array array2 = {1, 2, 3}; - - span s1{array1}; - EXPECT_EQ(s1.data(), array1); - EXPECT_EQ(s1.size(), 3); - - span s2{array2}; - EXPECT_EQ(s2.data(), array2.data()); - EXPECT_EQ(s2.size(), array2.size()); - - span s3{array1}; - EXPECT_EQ(s3.data(), array1); - EXPECT_EQ(s3.size(), 3); - - span s4{array2}; - EXPECT_EQ(s4.data(), array2.data()); - EXPECT_EQ(s4.size(), array2.size()); - - EXPECT_FALSE((std::is_constructible, int(&)[3]>::value)); -} - -TEST(SpanTest, ContainerConstruction) -{ - std::vector v = {1, 2, 3}; - - span s1{v}; - EXPECT_EQ(s1.data(), v.data()); - EXPECT_EQ(s1.size(), v.size()); - - span s2{v.data(), 3}; - - EXPECT_EQ(s2.data(), v.data()); - EXPECT_EQ(s2.size(), v.size()); - -#ifndef HAVE_CPP_STDLIB - /* This test is not supposed to fail with STL. Why is this invalid construct? */ - EXPECT_DEATH((span{v.data(), 3}), ".*"); -#endif - - EXPECT_FALSE((std::is_constructible, std::vector>::value)); - EXPECT_FALSE((std::is_constructible, std::list>::value)); -} - -TEST(SpanTest, OtherSpanConstruction) -{ - std::array array = {1, 2, 3}; - span s1{array.data(), array.size()}; - span s2{array.data(), array.size()}; - - span s3{s1}; - EXPECT_EQ(s3.data(), array.data()); - EXPECT_EQ(s3.size(), array.size()); - - span s4{s2}; - EXPECT_EQ(s4.data(), array.data()); - EXPECT_EQ(s4.size(), array.size()); - - span s5{s1}; - EXPECT_EQ(s5.data(), array.data()); - EXPECT_EQ(s5.size(), array.size()); - - EXPECT_FALSE((std::is_constructible, span>::value)); - EXPECT_FALSE((std::is_constructible, span>::value)); - - span s6{s2}; - EXPECT_EQ(s6.data(), array.data()); - EXPECT_EQ(s6.size(), array.size()); - - span s7{s2}; - EXPECT_EQ(s7.data(), array.data()); - EXPECT_EQ(s7.size(), array.size()); - - EXPECT_FALSE((std::is_constructible, span>::value)); - EXPECT_FALSE((std::is_constructible, span>::value)); -} - -TEST(SpanTest, BracketOperator) -{ - std::array array = {1, 2}; - - span s1{array.data(), array.size()}; - EXPECT_EQ(s1[0], 1); - EXPECT_EQ(s1[1], 2); - - span s2{array.data(), array.size()}; - EXPECT_EQ(s2[0], 1); - EXPECT_EQ(s2[1], 2); -} - -TEST(SpanTest, Iteration) -{ - std::array array = {1, 2, 3}; - - span s1{array.data(), array.size()}; - EXPECT_EQ(std::distance(s1.begin(), s1.end()), array.size()); - EXPECT_TRUE(std::equal(s1.begin(), s1.end(), array.begin())); - - span s2{array.data(), array.size()}; - EXPECT_EQ(std::distance(s2.begin(), s2.end()), array.size()); - EXPECT_TRUE(std::equal(s2.begin(), s2.end(), array.begin())); -} - -static void SpanIterator(benchmark::State &state) -{ - constexpr size_t aSize = 100000; - std::array array{}; - for (size_t i = 0; i < aSize; i++) - { - array[i] = i; - } - span s1{array.data(), array.size()}; - for (auto _ : state) - { - size_t i = 0; - for (auto item : s1) - { - EXPECT_EQ(item, i); - i++; - } - } -} -BENCHMARK(SpanIterator); - -static void SpanConstructor(benchmark::State &state) -{ - constexpr size_t aSize = 1000000; - auto *aInt16 = new std::array{}; - auto *aInt32 = new std::array{}; - auto *aInt64 = new std::array{}; - for (size_t i = 0; i < aSize; i++) - { - (*aInt16)[i] = i; - (*aInt32)[i] = i; - (*aInt64)[i] = i; - } - size_t j = aSize; - for (auto _ : state) - { - benchmark::DoNotOptimize([&] { - span s1{aInt16->data(), aInt16->size()}; - span s2{aInt32->data(), aInt32->size()}; - span s3{aInt64->data(), aInt64->size()}; - }); - } - delete aInt16; - delete aInt32; - delete aInt64; -} -BENCHMARK(SpanConstructor); - -TEST(SpanTest, PerfTests) -{ - // Run all benchmarks - int argc = 0; - const char *argv[] = {""}; - ::benchmark::Initialize(&argc, (char **)(argv)); - ::benchmark::RunSpecifiedBenchmarks(); -} +#include "opentelemetry/nostd/span.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +using opentelemetry::nostd::span; + +TEST(SpanTest, DefaultConstruction) +{ + span s1; + EXPECT_EQ(s1.data(), nullptr); + EXPECT_EQ(s1.size(), 0); + EXPECT_TRUE(s1.empty()); + + span s2; + EXPECT_EQ(s2.data(), nullptr); + EXPECT_EQ(s2.size(), 0); + EXPECT_TRUE(s2.empty()); + + EXPECT_FALSE((std::is_default_constructible>::value)); +} + +TEST(SpanTest, Assignment) +{ + std::array array1 = {1, 2, 3}; + std::array array2 = {1, 2, 3}; + span s1{array1.data(), array1.size()}; + span s2{array1.data(), array1.size()}; + + span s3; + s3 = s1; + EXPECT_EQ(s3.data(), array1.data()); + EXPECT_EQ(s3.size(), array1.size()); + + span s4{array2}; + s4 = s2; + EXPECT_EQ(s4.data(), array1.data()); + EXPECT_EQ(s4.size(), array1.size()); +} + +TEST(SpanTest, PointerCountConstruction) +{ + std::array array = {1, 2, 3}; + + span s1{array.data(), array.size()}; + EXPECT_EQ(s1.data(), array.data()); + EXPECT_EQ(s1.size(), array.size()); + + span s2{array.data(), array.size()}; + EXPECT_EQ(s2.data(), array.data()); + EXPECT_EQ(s2.size(), array.size()); + +#ifndef HAVE_CPP_STDLIB + /* This test is not supposed to fail with STL. Why is this invalid construct? */ + EXPECT_DEATH((span{array.data(), array.size()}), ".*"); +#endif +} + +TEST(SpanTest, RangeConstruction) +{ + int array[] = {1, 2, 3}; + + span s1{std::begin(array), std::end(array)}; + EXPECT_EQ(s1.data(), array); + EXPECT_EQ(s1.size(), 3); + + span s2{std::begin(array), std::end(array)}; + EXPECT_EQ(s2.data(), array); + EXPECT_EQ(s2.size(), 3); + +#ifndef HAVE_CPP_STDLIB + /* This test is not supposed to fail with STL. Why is this invalid construct? */ + EXPECT_DEATH((span{std::begin(array), std::end(array)}), ".*"); +#endif +} + +TEST(SpanTest, ArrayConstruction) +{ + int array1[] = {1, 2, 3}; + std::array array2 = {1, 2, 3}; + + span s1{array1}; + EXPECT_EQ(s1.data(), array1); + EXPECT_EQ(s1.size(), 3); + + span s2{array2}; + EXPECT_EQ(s2.data(), array2.data()); + EXPECT_EQ(s2.size(), array2.size()); + + span s3{array1}; + EXPECT_EQ(s3.data(), array1); + EXPECT_EQ(s3.size(), 3); + + span s4{array2}; + EXPECT_EQ(s4.data(), array2.data()); + EXPECT_EQ(s4.size(), array2.size()); + + EXPECT_FALSE((std::is_constructible, int(&)[3]>::value)); +} + +TEST(SpanTest, ContainerConstruction) +{ + std::vector v = {1, 2, 3}; + + span s1{v}; + EXPECT_EQ(s1.data(), v.data()); + EXPECT_EQ(s1.size(), v.size()); + + span s2{v.data(), 3}; + + EXPECT_EQ(s2.data(), v.data()); + EXPECT_EQ(s2.size(), v.size()); + +#ifndef HAVE_CPP_STDLIB + /* This test is not supposed to fail with STL. Why is this invalid construct? */ + EXPECT_DEATH((span{v.data(), 3}), ".*"); +#endif + + EXPECT_FALSE((std::is_constructible, std::vector>::value)); + EXPECT_FALSE((std::is_constructible, std::list>::value)); +} + +TEST(SpanTest, OtherSpanConstruction) +{ + std::array array = {1, 2, 3}; + span s1{array.data(), array.size()}; + span s2{array.data(), array.size()}; + + span s3{s1}; + EXPECT_EQ(s3.data(), array.data()); + EXPECT_EQ(s3.size(), array.size()); + + span s4{s2}; + EXPECT_EQ(s4.data(), array.data()); + EXPECT_EQ(s4.size(), array.size()); + + span s5{s1}; + EXPECT_EQ(s5.data(), array.data()); + EXPECT_EQ(s5.size(), array.size()); + + EXPECT_FALSE((std::is_constructible, span>::value)); + EXPECT_FALSE((std::is_constructible, span>::value)); + + span s6{s2}; + EXPECT_EQ(s6.data(), array.data()); + EXPECT_EQ(s6.size(), array.size()); + + span s7{s2}; + EXPECT_EQ(s7.data(), array.data()); + EXPECT_EQ(s7.size(), array.size()); + + EXPECT_FALSE((std::is_constructible, span>::value)); + EXPECT_FALSE((std::is_constructible, span>::value)); +} + +TEST(SpanTest, BracketOperator) +{ + std::array array = {1, 2}; + + span s1{array.data(), array.size()}; + EXPECT_EQ(s1[0], 1); + EXPECT_EQ(s1[1], 2); + + span s2{array.data(), array.size()}; + EXPECT_EQ(s2[0], 1); + EXPECT_EQ(s2[1], 2); +} + +TEST(SpanTest, Iteration) +{ + std::array array = {1, 2, 3}; + + span s1{array.data(), array.size()}; + EXPECT_EQ(std::distance(s1.begin(), s1.end()), array.size()); + EXPECT_TRUE(std::equal(s1.begin(), s1.end(), array.begin())); + + span s2{array.data(), array.size()}; + EXPECT_EQ(std::distance(s2.begin(), s2.end()), array.size()); + EXPECT_TRUE(std::equal(s2.begin(), s2.end(), array.begin())); +} + +static void SpanIterator(benchmark::State &state) +{ + constexpr size_t aSize = 100000; + std::array array{}; + for (size_t i = 0; i < aSize; i++) + { + array[i] = i; + } + span s1{array.data(), array.size()}; + for (auto _ : state) + { + size_t i = 0; + for (auto item : s1) + { + EXPECT_EQ(item, i); + i++; + } + } +} +BENCHMARK(SpanIterator); + +static void SpanConstructor(benchmark::State &state) +{ + constexpr size_t aSize = 1000000; + auto *aInt16 = new std::array{}; + auto *aInt32 = new std::array{}; + auto *aInt64 = new std::array{}; + for (size_t i = 0; i < aSize; i++) + { + (*aInt16)[i] = i; + (*aInt32)[i] = i; + (*aInt64)[i] = i; + } + size_t j = aSize; + for (auto _ : state) + { + benchmark::DoNotOptimize([&] { + span s1{aInt16->data(), aInt16->size()}; + span s2{aInt32->data(), aInt32->size()}; + span s3{aInt64->data(), aInt64->size()}; + }); + } + delete aInt16; + delete aInt32; + delete aInt64; +} +BENCHMARK(SpanConstructor); + +TEST(SpanTest, PerfTests) +{ + // Run all benchmarks + int argc = 0; + const char *argv[] = {""}; + ::benchmark::Initialize(&argc, (char **)(argv)); + ::benchmark::RunSpecifiedBenchmarks(); +} diff --git a/api/test/nostd/string_view_test.cc b/api/test/nostd/string_view_test.cc index 74985e385f..01cbd29ce6 100644 --- a/api/test/nostd/string_view_test.cc +++ b/api/test/nostd/string_view_test.cc @@ -1,215 +1,215 @@ -#include "opentelemetry/nostd/string_view.h" - -#include - -#include -#include -#include -#include - -using opentelemetry::nostd::string_view; - -TEST(StringViewTest, DefaultConstruction) -{ - string_view ref; - EXPECT_EQ(ref.data(), nullptr); - EXPECT_EQ(ref.length(), 0); -} - -TEST(StringViewTest, CStringInitialization) -{ - const char *val = "hello world"; - - string_view ref(val); - - EXPECT_EQ(ref.data(), val); - EXPECT_EQ(ref.length(), std::strlen(val)); -} - -TEST(StringViewTest, StdStringInitialization) -{ - const std::string val = "hello world"; - - string_view ref(val); - - EXPECT_EQ(ref.data(), val.data()); - EXPECT_EQ(ref.length(), val.size()); -} - -TEST(StringViewTest, Copy) -{ - const std::string val = "hello world"; - - string_view ref(val); - string_view cpy(ref); - - EXPECT_EQ(cpy.data(), val); - EXPECT_EQ(cpy.length(), val.length()); - EXPECT_EQ(cpy, val); -} - -TEST(StringViewTest, Accessor) -{ - string_view s = "abc123"; - EXPECT_EQ(s.data(), &s[0]); - EXPECT_EQ(s.data() + 1, &s[1]); -} - -TEST(StringViewTest, ExplicitStdStringConversion) -{ - std::string s = static_cast(string_view{"abc"}); - EXPECT_EQ(s, "abc"); -} - -TEST(StringViewTest, SubstrPortion) -{ - string_view s = "abc123"; - EXPECT_EQ("123", s.substr(3)); - EXPECT_EQ("12", s.substr(3, 2)); -} - -TEST(StringViewTest, SubstrOutOfRange) -{ - string_view s = "abc123"; -#if __EXCEPTIONS || defined(HAVE_STDLIB_CPP) - EXPECT_THROW(s.substr(10), std::out_of_range); -#else - EXPECT_DEATH({ s.substr(10); }, ""); -#endif -} - -TEST(StringViewTest, Compare) -{ - string_view s1 = "aaa"; - string_view s2 = "bbb"; - string_view s3 = "aaa"; - - // Equals - EXPECT_EQ(s1, s3); - EXPECT_EQ(s1, s1); - - // Less then - EXPECT_LT(s1, s2); - - // Greater then - EXPECT_GT(s2, s1); -} - -TEST(StringViewTest, MapKeyOrdering) -{ - std::map m = {{"bbb", 2}, {"aaa", 1}, {"ccc", 3}}; - size_t i = 1; - for (const auto &kv : m) - { - EXPECT_EQ(kv.second, i); - i++; - } -} - -static void StringViewSubStr(benchmark::State &state) -{ - std::string s = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - for (auto _ : state) - { - string_view sv = s; - auto oneSv = sv.substr(0, 5); - auto twoSv = sv.substr(6, 5); - auto threeSv = sv.substr(12, 5); - auto fourSv = sv.substr(18, 11); - auto fiveSv = sv.substr(30, 5); - benchmark::DoNotOptimize(oneSv); - benchmark::DoNotOptimize(twoSv); - benchmark::DoNotOptimize(threeSv); - benchmark::DoNotOptimize(fourSv); - benchmark::DoNotOptimize(fiveSv); - } -} -BENCHMARK(StringViewSubStr); - -static void StringViewMaps(benchmark::State &state) -{ - std::map m; - std::string txt; - size_t i = 0; - for (auto _ : state) - { - i %= 200; // up to 200 key-value pairs in this collection - m[string_view(std::to_string(i))] = string_view(std::to_string(i)); - i += 1; - }; -} -BENCHMARK(StringViewMaps); - -static void StringViewFromCString(benchmark::State &state) -{ - std::string s = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - for (auto _ : state) - { - string_view sv(s.c_str()); - // scan thru string_view - for (const auto &c : sv) - ; - }; -} -BENCHMARK(StringViewFromCString); - -static void StringViewToString(benchmark::State &state) -{ - string_view s = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - std::string txt; - for (auto _ : state) - { - txt = std::string(s.data(), s.length()); - }; -} -BENCHMARK(StringViewToString); - -static void StringViewExplode(benchmark::State &state) -{ - for (auto _ : state) - { - string_view sv = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - std::string s; - for (size_t i = 0; i < 5; i++) - { - s += std::string(sv.data(), sv.length()); - sv = s; - string_view sv2 = s; - if (sv == sv2) - ; // FIXME: Warning C4390 ';' : empty controlled statement found; is this the intent ? - } - }; -} -BENCHMARK(StringViewExplode); - -static void StringViewVector(benchmark::State &state) -{ - std::vector v; - for (auto _ : state) - { - string_view sv = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - v.push_back(sv); - if (v.size() > 10000) - v.clear(); - } -} -BENCHMARK(StringViewVector); - -TEST(StringView, PerfTests) -{ - // Run all benchmarks - int argc = 0; - const char *argv[] = {""}; - ::benchmark::Initialize(&argc, (char **)(argv)); - ::benchmark::RunSpecifiedBenchmarks(); -} +#include "opentelemetry/nostd/string_view.h" + +#include + +#include +#include +#include +#include + +using opentelemetry::nostd::string_view; + +TEST(StringViewTest, DefaultConstruction) +{ + string_view ref; + EXPECT_EQ(ref.data(), nullptr); + EXPECT_EQ(ref.length(), 0); +} + +TEST(StringViewTest, CStringInitialization) +{ + const char *val = "hello world"; + + string_view ref(val); + + EXPECT_EQ(ref.data(), val); + EXPECT_EQ(ref.length(), std::strlen(val)); +} + +TEST(StringViewTest, StdStringInitialization) +{ + const std::string val = "hello world"; + + string_view ref(val); + + EXPECT_EQ(ref.data(), val.data()); + EXPECT_EQ(ref.length(), val.size()); +} + +TEST(StringViewTest, Copy) +{ + const std::string val = "hello world"; + + string_view ref(val); + string_view cpy(ref); + + EXPECT_EQ(cpy.data(), val); + EXPECT_EQ(cpy.length(), val.length()); + EXPECT_EQ(cpy, val); +} + +TEST(StringViewTest, Accessor) +{ + string_view s = "abc123"; + EXPECT_EQ(s.data(), &s[0]); + EXPECT_EQ(s.data() + 1, &s[1]); +} + +TEST(StringViewTest, ExplicitStdStringConversion) +{ + std::string s = static_cast(string_view{"abc"}); + EXPECT_EQ(s, "abc"); +} + +TEST(StringViewTest, SubstrPortion) +{ + string_view s = "abc123"; + EXPECT_EQ("123", s.substr(3)); + EXPECT_EQ("12", s.substr(3, 2)); +} + +TEST(StringViewTest, SubstrOutOfRange) +{ + string_view s = "abc123"; +#if __EXCEPTIONS || defined(HAVE_STDLIB_CPP) + EXPECT_THROW(s.substr(10), std::out_of_range); +#else + EXPECT_DEATH({ s.substr(10); }, ""); +#endif +} + +TEST(StringViewTest, Compare) +{ + string_view s1 = "aaa"; + string_view s2 = "bbb"; + string_view s3 = "aaa"; + + // Equals + EXPECT_EQ(s1, s3); + EXPECT_EQ(s1, s1); + + // Less then + EXPECT_LT(s1, s2); + + // Greater then + EXPECT_GT(s2, s1); +} + +TEST(StringViewTest, MapKeyOrdering) +{ + std::map m = {{"bbb", 2}, {"aaa", 1}, {"ccc", 3}}; + size_t i = 1; + for (const auto &kv : m) + { + EXPECT_EQ(kv.second, i); + i++; + } +} + +static void StringViewSubStr(benchmark::State &state) +{ + std::string s = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + for (auto _ : state) + { + string_view sv = s; + auto oneSv = sv.substr(0, 5); + auto twoSv = sv.substr(6, 5); + auto threeSv = sv.substr(12, 5); + auto fourSv = sv.substr(18, 11); + auto fiveSv = sv.substr(30, 5); + benchmark::DoNotOptimize(oneSv); + benchmark::DoNotOptimize(twoSv); + benchmark::DoNotOptimize(threeSv); + benchmark::DoNotOptimize(fourSv); + benchmark::DoNotOptimize(fiveSv); + } +} +BENCHMARK(StringViewSubStr); + +static void StringViewMaps(benchmark::State &state) +{ + std::map m; + std::string txt; + size_t i = 0; + for (auto _ : state) + { + i %= 200; // up to 200 key-value pairs in this collection + m[string_view(std::to_string(i))] = string_view(std::to_string(i)); + i += 1; + }; +} +BENCHMARK(StringViewMaps); + +static void StringViewFromCString(benchmark::State &state) +{ + std::string s = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + for (auto _ : state) + { + string_view sv(s.c_str()); + // scan thru string_view + for (const auto &c : sv) + ; + }; +} +BENCHMARK(StringViewFromCString); + +static void StringViewToString(benchmark::State &state) +{ + string_view s = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + std::string txt; + for (auto _ : state) + { + txt = std::string(s.data(), s.length()); + }; +} +BENCHMARK(StringViewToString); + +static void StringViewExplode(benchmark::State &state) +{ + for (auto _ : state) + { + string_view sv = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + std::string s; + for (size_t i = 0; i < 5; i++) + { + s += std::string(sv.data(), sv.length()); + sv = s; + string_view sv2 = s; + if (sv == sv2) + ; // FIXME: Warning C4390 ';' : empty controlled statement found; is this the intent ? + } + }; +} +BENCHMARK(StringViewExplode); + +static void StringViewVector(benchmark::State &state) +{ + std::vector v; + for (auto _ : state) + { + string_view sv = + "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " + "performance."; + v.push_back(sv); + if (v.size() > 10000) + v.clear(); + } +} +BENCHMARK(StringViewVector); + +TEST(StringView, PerfTests) +{ + // Run all benchmarks + int argc = 0; + const char *argv[] = {""}; + ::benchmark::Initialize(&argc, (char **)(argv)); + ::benchmark::RunSpecifiedBenchmarks(); +} diff --git a/api/test/plugin/CMakeLists.txt b/api/test/plugin/CMakeLists.txt index 29a75b6b84..114f26ab7a 100644 --- a/api/test/plugin/CMakeLists.txt +++ b/api/test/plugin/CMakeLists.txt @@ -5,7 +5,5 @@ target_link_libraries( dynamic_load_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) target_link_libraries(dynamic_load_test ${CMAKE_DL_LIBS}) -gtest_add_tests( - TARGET dynamic_load_test - TEST_PREFIX plugin. - TEST_LIST dynamic_load_test) +gtest_add_tests(TARGET dynamic_load_test TEST_PREFIX plugin. TEST_LIST + dynamic_load_test) diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index 6c69883b2c..afa698b6ef 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -13,10 +13,8 @@ foreach( target_link_libraries( api_${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET api_${testname} - TEST_PREFIX trace. - TEST_LIST api_${testname}) + gtest_add_tests(TARGET api_${testname} TEST_PREFIX trace. TEST_LIST + api_${testname}) endforeach() add_executable(span_id_benchmark span_id_benchmark.cc) diff --git a/api/test/trace/propagation/CMakeLists.txt b/api/test/trace/propagation/CMakeLists.txt index 8f13cd68de..66330d7993 100644 --- a/api/test/trace/propagation/CMakeLists.txt +++ b/api/test/trace/propagation/CMakeLists.txt @@ -3,8 +3,5 @@ foreach(testname http_text_format_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX trace. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) endforeach() diff --git a/docs/abi-compatibility.md b/docs/abi-compatibility.md index 6b5158bcd7..53936de0bd 100644 --- a/docs/abi-compatibility.md +++ b/docs/abi-compatibility.md @@ -1,35 +1,35 @@ -# Windows - -## Visual Studio 2015, 2017, 2019 - -The Microsoft C++ (MSVC) compiler toolsets in Visual Studio 2013 and earlier don't guarantee binary compatibility across versions. You can't link object files, static libraries, dynamic libraries, and executables built by different versions. The ABIs, object formats, and runtime libraries are incompatible. - -We've changed this behavior in Visual Studio 2015, 2017, and 2019. The runtime libraries and apps compiled by any of these versions of the compiler are binary-compatible. It's reflected in the C++ toolset major number, which is 14 for all three versions. (The toolset version is v140 for Visual Studio 2015, v141 for 2017, and v142 for 2019). Say you have third-party libraries built by Visual Studio 2015. You can still use them in an application built by Visual Studio 2017 or 2019. There's no need to recompile with a matching toolset. The latest version of the Microsoft Visual C++ Redistributable package (the Redistributable) works for all of them. - -There are three important restrictions on binary compatibility: - -- You can mix binaries built by different versions of the toolset. However, you must use a toolset at least as recent as the most recent binary to link your app. Here's an example: you can link an app compiled using the 2017 toolset to a static library compiled using 2019, if they're linked using the 2019 toolset. - -- The Redistributable your app uses has a similar binary-compatibility restriction. When you mix binaries built by different supported versions of the toolset, the Redistributable version must be at least as new as the latest toolset used by any app component. - -- Static libraries or object files compiled using the /GL (Whole program optimization) compiler switch aren't binary-compatible across versions. All object files and libraries compiled using /GL must use exactly the same toolset for the compile and the final link. - -[Reference](https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2019) - -## Breaking Compatibility - -### Exceptions - -- [__CxxFrameHandler4](https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/) - static library built with Visual Studio 2019 wont link to executable compiled with Visual Studio 2017 - -### Release vs Debug libraries on Windows - -- [\_SECURE_SCL](https://docs.microsoft.com/en-us/cpp/standard-library/secure-scl?view=vs-2019) - checked iterators (old) - -- [\_ITERATOR_DEBUG_LEVEL](https://docs.microsoft.com/en-us/cpp/standard-library/iterator-debug-level?view=vs-2019) - checked iterators (new) - -### Spectre Mitigation - -- [Runtime Libraries for Spectre Mitigation](https://docs.microsoft.com/en-us/cpp/build/reference/qspectre?view=vs-2019) - -- [New Spectre Mitigations in Visual Studio 2019](https://devblogs.microsoft.com/cppblog/more-spectre-mitigations-in-msvc/) +# Windows + +## Visual Studio 2015, 2017, 2019 + +The Microsoft C++ (MSVC) compiler toolsets in Visual Studio 2013 and earlier don't guarantee binary compatibility across versions. You can't link object files, static libraries, dynamic libraries, and executables built by different versions. The ABIs, object formats, and runtime libraries are incompatible. + +We've changed this behavior in Visual Studio 2015, 2017, and 2019. The runtime libraries and apps compiled by any of these versions of the compiler are binary-compatible. It's reflected in the C++ toolset major number, which is 14 for all three versions. (The toolset version is v140 for Visual Studio 2015, v141 for 2017, and v142 for 2019). Say you have third-party libraries built by Visual Studio 2015. You can still use them in an application built by Visual Studio 2017 or 2019. There's no need to recompile with a matching toolset. The latest version of the Microsoft Visual C++ Redistributable package (the Redistributable) works for all of them. + +There are three important restrictions on binary compatibility: + +- You can mix binaries built by different versions of the toolset. However, you must use a toolset at least as recent as the most recent binary to link your app. Here's an example: you can link an app compiled using the 2017 toolset to a static library compiled using 2019, if they're linked using the 2019 toolset. + +- The Redistributable your app uses has a similar binary-compatibility restriction. When you mix binaries built by different supported versions of the toolset, the Redistributable version must be at least as new as the latest toolset used by any app component. + +- Static libraries or object files compiled using the /GL (Whole program optimization) compiler switch aren't binary-compatible across versions. All object files and libraries compiled using /GL must use exactly the same toolset for the compile and the final link. + +[Reference](https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2019) + +## Breaking Compatibility + +### Exceptions + +- [__CxxFrameHandler4](https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/) - static library built with Visual Studio 2019 wont link to executable compiled with Visual Studio 2017 + +### Release vs Debug libraries on Windows + +- [\_SECURE_SCL](https://docs.microsoft.com/en-us/cpp/standard-library/secure-scl?view=vs-2019) - checked iterators (old) + +- [\_ITERATOR_DEBUG_LEVEL](https://docs.microsoft.com/en-us/cpp/standard-library/iterator-debug-level?view=vs-2019) - checked iterators (new) + +### Spectre Mitigation + +- [Runtime Libraries for Spectre Mitigation](https://docs.microsoft.com/en-us/cpp/build/reference/qspectre?view=vs-2019) + +- [New Spectre Mitigations in Visual Studio 2019](https://devblogs.microsoft.com/cppblog/more-spectre-mitigations-in-msvc/) diff --git a/docs/building-with-stdlib.md b/docs/building-with-stdlib.md index dafb977080..4031be90d2 100644 --- a/docs/building-with-stdlib.md +++ b/docs/building-with-stdlib.md @@ -1,102 +1,102 @@ -# Building with Standard C++ Library - -Standard Library build flavor works best for statically linking the SDK in a -process (environment where ABI compat is not a requirement), or for -"header-only" implementation of SDK. - -Proposed approach cannot be employed for shared libs in environments where -ABI compatibility is required: - -- OpenTelemetry SDK binary compiled with compiler A + STL B -- may not be ABI compatible with the main executable compiled with compiler - C + STL D on a same OS. -Thus, this approach works best only for statically lined / header only use. - -## Motivation - -In certain scenarios it may be of benefit to compile the OpenTelemetry SDK from -source using standard library container classes (`std::map`, `std::string_view`, -`std::span`, `std::variant`) instead of OpenTelemetry `nostd::` analogs (which -were backported to C++11 and designed as ABI-stable). This PR also can be used -as a foundation for alternate approach - to also allow bindings to [abseil](https://github.com/abseil/abseil-cpp) -classes. That is in environments that would rather prefer `Abseil` classes -over the standard lib or `nostd`. - -The approach is to provide totally opaque (from SDK code / SDK developer -perspective) mapping / aliasing from `nostd::` classes back to their `std::` -counterparts, and that is only done in environments where this is possible. - -We continue fully supporting both models and run CI for both. - -## Pros and Cons - -### Using trusted/certified Standard Library - -Using standard library implementation classes in customer code and on API -surface instead of `nostd` classes. Certain environments would prefer to have -**standard** instead of non-standard classes due to security, performance, -stability and debug'ability considerations. For example, Visual Studio IDE -provides 1st class Debug experience for Standard containers, plus additional -runtime-checks for Debug builds that use Standard containers. - -### Minimizing binary size - -No need to marshal types from standard to `nostd`, then back to standard -library means less code involved and less memcpy. We use Standard classes -used elsewhere in the app. We can subsequently improve the process by avoiding -`KeyValueIterable` transform (and, thus, unnecessary memcpy) when we know -that the incoming types does not need to be 'transferred' across ABI boundary. -This is the case for statically linked executables and when SDK is implemented -as 'header-only' library. - -### Avoiding unnecessary extra memcpy (perf improvements) - -No need to transform from 'native' standard library types, e.g. `std::map` via -`KeyValueIterable` means we can bypass that transformation process, if and when -we know that the ABI compatibility is not a requirement in certain environment. -ETA perf improvement is 1.5%-3% better perf since an extra transform, memcpy, -iteration for-each key-value is avoided. - -### ABI stability - -Obviously this approach does not work in environment where ABI stability -guarantee must be provided, e.g. for dynamically loadable OpenTelemetry SDK -module and plugins for products such as NGINX, Envoy, etc. - -## Scope of changes needed to implement the feature - -### Separate flavors of SDK build - -Supported build flavors: - -- `nostd` - OpenTelemetry backport of classes for C++11. Not using STD Lib. -- `stl` - Standard Library. Best be compiled with C++20 compaitlbe compiler. - C++17 may be used with additional dependencies, e.g. MS-GSL or Abseil. -- `absl` - TODO: this should allow using Abseil C++ lirary only (no MS-GSL). - -### Test setup - -Tests to validate that all OpenTelemetry functionality is working the same -identical way irrespective of what C++ runtime / STL library it is compiled -with. - -### Implementation Details - -Feature allows to alias from `nostd::` to `std::` classes for C++17 and above. - -Consistent handling of `std::variant` across various OS: - -- backport of a few missing variant features, e.g. `std::get` and `std::visit` - for older version of Mac OS X. Patches that enable proper - handling of `std::visit` and `std::variant` irrespective of OS version - to resolve [this quirk](https://stackoverflow.com/questions/52310835/xcode-10-call-to-unavailable-function-stdvisit). - -- ability to optionally borrow implementation of C++20 `gsl::span` from - [Microsoft Guidelines Support Library](https://github.com/microsoft/GSL). - This is not necessary for C++20 and above compilers. - -- ability to use Abseil `absl::variant` for Visual Studio 2015 - -- set of tools to locally build the SDK with both options across various OS - and compilers, including vs2015 (C++11), vs2017 (C++17), vs2019 (C++20), - ubuntu-18.xx (C++17), ubuntu-20.xx/gcc-9 (C++20), Mac OS X (C++17 and above). +# Building with Standard C++ Library + +Standard Library build flavor works best for statically linking the SDK in a +process (environment where ABI compat is not a requirement), or for +"header-only" implementation of SDK. + +Proposed approach cannot be employed for shared libs in environments where +ABI compatibility is required: + +- OpenTelemetry SDK binary compiled with compiler A + STL B +- may not be ABI compatible with the main executable compiled with compiler + C + STL D on a same OS. +Thus, this approach works best only for statically lined / header only use. + +## Motivation + +In certain scenarios it may be of benefit to compile the OpenTelemetry SDK from +source using standard library container classes (`std::map`, `std::string_view`, +`std::span`, `std::variant`) instead of OpenTelemetry `nostd::` analogs (which +were backported to C++11 and designed as ABI-stable). This PR also can be used +as a foundation for alternate approach - to also allow bindings to [abseil](https://github.com/abseil/abseil-cpp) +classes. That is in environments that would rather prefer `Abseil` classes +over the standard lib or `nostd`. + +The approach is to provide totally opaque (from SDK code / SDK developer +perspective) mapping / aliasing from `nostd::` classes back to their `std::` +counterparts, and that is only done in environments where this is possible. + +We continue fully supporting both models and run CI for both. + +## Pros and Cons + +### Using trusted/certified Standard Library + +Using standard library implementation classes in customer code and on API +surface instead of `nostd` classes. Certain environments would prefer to have +**standard** instead of non-standard classes due to security, performance, +stability and debug'ability considerations. For example, Visual Studio IDE +provides 1st class Debug experience for Standard containers, plus additional +runtime-checks for Debug builds that use Standard containers. + +### Minimizing binary size + +No need to marshal types from standard to `nostd`, then back to standard +library means less code involved and less memcpy. We use Standard classes +used elsewhere in the app. We can subsequently improve the process by avoiding +`KeyValueIterable` transform (and, thus, unnecessary memcpy) when we know +that the incoming types does not need to be 'transferred' across ABI boundary. +This is the case for statically linked executables and when SDK is implemented +as 'header-only' library. + +### Avoiding unnecessary extra memcpy (perf improvements) + +No need to transform from 'native' standard library types, e.g. `std::map` via +`KeyValueIterable` means we can bypass that transformation process, if and when +we know that the ABI compatibility is not a requirement in certain environment. +ETA perf improvement is 1.5%-3% better perf since an extra transform, memcpy, +iteration for-each key-value is avoided. + +### ABI stability + +Obviously this approach does not work in environment where ABI stability +guarantee must be provided, e.g. for dynamically loadable OpenTelemetry SDK +module and plugins for products such as NGINX, Envoy, etc. + +## Scope of changes needed to implement the feature + +### Separate flavors of SDK build + +Supported build flavors: + +- `nostd` - OpenTelemetry backport of classes for C++11. Not using STD Lib. +- `stl` - Standard Library. Best be compiled with C++20 compaitlbe compiler. + C++17 may be used with additional dependencies, e.g. MS-GSL or Abseil. +- `absl` - TODO: this should allow using Abseil C++ lirary only (no MS-GSL). + +### Test setup + +Tests to validate that all OpenTelemetry functionality is working the same +identical way irrespective of what C++ runtime / STL library it is compiled +with. + +### Implementation Details + +Feature allows to alias from `nostd::` to `std::` classes for C++17 and above. + +Consistent handling of `std::variant` across various OS: + +- backport of a few missing variant features, e.g. `std::get` and `std::visit` + for older version of Mac OS X. Patches that enable proper + handling of `std::visit` and `std::variant` irrespective of OS version + to resolve [this quirk](https://stackoverflow.com/questions/52310835/xcode-10-call-to-unavailable-function-stdvisit). + +- ability to optionally borrow implementation of C++20 `gsl::span` from + [Microsoft Guidelines Support Library](https://github.com/microsoft/GSL). + This is not necessary for C++20 and above compilers. + +- ability to use Abseil `absl::variant` for Visual Studio 2015 + +- set of tools to locally build the SDK with both options across various OS + and compilers, including vs2015 (C++11), vs2017 (C++17), vs2019 (C++20), + ubuntu-18.xx (C++17), ubuntu-20.xx/gcc-9 (C++20), Mac OS X (C++17 and above). diff --git a/examples/plugin/plugin/tracer.cc b/examples/plugin/plugin/tracer.cc index 512af5669d..0b6fb1b903 100644 --- a/examples/plugin/plugin/tracer.cc +++ b/examples/plugin/plugin/tracer.cc @@ -1,72 +1,72 @@ -#include "tracer.h" -#include "opentelemetry/nostd/unique_ptr.h" - -#include -#include - -namespace nostd = opentelemetry::nostd; -namespace common = opentelemetry::common; -namespace core = opentelemetry::core; -namespace trace = opentelemetry::trace; -namespace context = opentelemetry::context; - -namespace -{ -class Span final : public trace::Span -{ -public: - Span(std::shared_ptr &&tracer, - nostd::string_view name, - const opentelemetry::common::KeyValueIterable & /*attributes*/, - const trace::StartSpanOptions & /*options*/) noexcept - : tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()} - { - std::cout << "StartSpan: " << name << "\n"; - } - - ~Span() { std::cout << "~Span\n"; } - - // opentelemetry::trace::Span - void SetAttribute(nostd::string_view /*name*/, - const common::AttributeValue & /*value*/) noexcept override - {} - - void AddEvent(nostd::string_view /*name*/) noexcept override {} - - void AddEvent(nostd::string_view /*name*/, core::SystemTimestamp /*timestamp*/) noexcept override - {} - - void AddEvent(nostd::string_view /*name*/, - core::SystemTimestamp /*timestamp*/, - const common::KeyValueIterable & /*attributes*/) noexcept override - {} - - void SetStatus(trace::CanonicalCode /*code*/, - nostd::string_view /*description*/) noexcept override - {} - - void UpdateName(nostd::string_view /*name*/) noexcept override {} - - void End(const trace::EndSpanOptions & /*options*/) noexcept override {} - - bool IsRecording() const noexcept override { return true; } - - trace::SpanContext GetContext() const noexcept override { return span_context_; } - -private: - std::shared_ptr tracer_; - std::string name_; - trace::SpanContext span_context_; -}; -} // namespace - -Tracer::Tracer(nostd::string_view /*output*/) {} - -nostd::shared_ptr Tracer::StartSpan( - nostd::string_view name, - const opentelemetry::common::KeyValueIterable &attributes, - const trace::StartSpanOptions &options) noexcept -{ - return nostd::shared_ptr{ - new (std::nothrow) Span{this->shared_from_this(), name, attributes, options}}; -} +#include "tracer.h" +#include "opentelemetry/nostd/unique_ptr.h" + +#include +#include + +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace core = opentelemetry::core; +namespace trace = opentelemetry::trace; +namespace context = opentelemetry::context; + +namespace +{ +class Span final : public trace::Span +{ +public: + Span(std::shared_ptr &&tracer, + nostd::string_view name, + const opentelemetry::common::KeyValueIterable & /*attributes*/, + const trace::StartSpanOptions & /*options*/) noexcept + : tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()} + { + std::cout << "StartSpan: " << name << "\n"; + } + + ~Span() { std::cout << "~Span\n"; } + + // opentelemetry::trace::Span + void SetAttribute(nostd::string_view /*name*/, + const common::AttributeValue & /*value*/) noexcept override + {} + + void AddEvent(nostd::string_view /*name*/) noexcept override {} + + void AddEvent(nostd::string_view /*name*/, core::SystemTimestamp /*timestamp*/) noexcept override + {} + + void AddEvent(nostd::string_view /*name*/, + core::SystemTimestamp /*timestamp*/, + const common::KeyValueIterable & /*attributes*/) noexcept override + {} + + void SetStatus(trace::CanonicalCode /*code*/, + nostd::string_view /*description*/) noexcept override + {} + + void UpdateName(nostd::string_view /*name*/) noexcept override {} + + void End(const trace::EndSpanOptions & /*options*/) noexcept override {} + + bool IsRecording() const noexcept override { return true; } + + trace::SpanContext GetContext() const noexcept override { return span_context_; } + +private: + std::shared_ptr tracer_; + std::string name_; + trace::SpanContext span_context_; +}; +} // namespace + +Tracer::Tracer(nostd::string_view /*output*/) {} + +nostd::shared_ptr Tracer::StartSpan( + nostd::string_view name, + const opentelemetry::common::KeyValueIterable &attributes, + const trace::StartSpanOptions &options) noexcept +{ + return nostd::shared_ptr{ + new (std::nothrow) Span{this->shared_from_this(), name, attributes, options}}; +} diff --git a/exporters/memory/CMakeLists.txt b/exporters/memory/CMakeLists.txt index 2739596fd5..aa8d334bd0 100644 --- a/exporters/memory/CMakeLists.txt +++ b/exporters/memory/CMakeLists.txt @@ -17,12 +17,8 @@ if(BUILD_TESTING) in_memory_span_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_in_memory) - gtest_add_tests( - TARGET in_memory_span_data_test - TEST_PREFIX exporter. - TEST_LIST in_memory_span_data_test) - gtest_add_tests( - TARGET in_memory_span_exporter_test - TEST_PREFIX exporter. - TEST_LIST in_memory_span_exporter_test) + gtest_add_tests(TARGET in_memory_span_data_test TEST_PREFIX exporter. + TEST_LIST in_memory_span_data_test) + gtest_add_tests(TARGET in_memory_span_exporter_test TEST_PREFIX exporter. + TEST_LIST in_memory_span_exporter_test) endif() diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index c307de7244..88cb70a326 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -15,12 +15,8 @@ if(BUILD_TESTING) ostream_metrics_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_metrics) - gtest_add_tests( - TARGET ostream_metrics_test - TEST_PREFIX exporter. - TEST_LIST ostream_metrics_test) - gtest_add_tests( - TARGET ostream_span_test - TEST_PREFIX exporter. - TEST_LIST ostream_span_test) + gtest_add_tests(TARGET ostream_metrics_test TEST_PREFIX exporter. TEST_LIST + ostream_metrics_test) + gtest_add_tests(TARGET ostream_span_test TEST_PREFIX exporter. TEST_LIST + ostream_span_test) endif() # BUILD_TESTING diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index d1bc535763..27ee7de956 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -9,8 +9,6 @@ if(BUILD_TESTING) target_link_libraries( recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_otprotocol protobuf::libprotobuf) - gtest_add_tests( - TARGET recordable_test - TEST_PREFIX exporter. - TEST_LIST recordable_test) + gtest_add_tests(TARGET recordable_test TEST_PREFIX exporter. TEST_LIST + recordable_test) endif() # BUILD_TESTING diff --git a/exporters/prometheus/test/CMakeLists.txt b/exporters/prometheus/test/CMakeLists.txt index 4168c6d3e4..c57f900347 100644 --- a/exporters/prometheus/test/CMakeLists.txt +++ b/exporters/prometheus/test/CMakeLists.txt @@ -3,8 +3,6 @@ foreach(testname prometheus_collector_test prometheus_exporter_utils_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} prometheus_exporter prometheus-cpp::pull) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX exporter. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX exporter. TEST_LIST + ${testname}) endforeach() diff --git a/ext/test/zpages/CMakeLists.txt b/ext/test/zpages/CMakeLists.txt index c7d0d837c8..34c3637316 100644 --- a/ext/test/zpages/CMakeLists.txt +++ b/ext/test/zpages/CMakeLists.txt @@ -4,8 +4,5 @@ foreach(testname tracez_processor_test tracez_data_aggregator_test target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_zpages) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX ext. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX ext. TEST_LIST ${testname}) endforeach() diff --git a/sdk/src/common/BUILD b/sdk/src/common/BUILD index 44f37073bb..b0724c3810 100644 --- a/sdk/src/common/BUILD +++ b/sdk/src/common/BUILD @@ -1,32 +1,32 @@ -# Copyright 2020, OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -package(default_visibility = ["//visibility:public"]) - -cc_library( - name = "random", - srcs = [ - "core.cc", - "random.cc", - ], - hdrs = [ - "fast_random_number_generator.h", - "random.h", - ], - include_prefix = "src/common", - deps = [ - "//api", - "//sdk/src/common/platform:fork", - ], -) +# Copyright 2020, OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "random", + srcs = [ + "core.cc", + "random.cc", + ], + hdrs = [ + "fast_random_number_generator.h", + "random.h", + ], + include_prefix = "src/common", + deps = [ + "//api", + "//sdk/src/common/platform:fork", + ], +) diff --git a/sdk/src/common/core.cc b/sdk/src/common/core.cc index c7cb0219dc..a8db9a0448 100644 --- a/sdk/src/common/core.cc +++ b/sdk/src/common/core.cc @@ -1,12 +1,12 @@ -#include "opentelemetry/nostd/variant.h" -#include "opentelemetry/version.h" - -#if defined(HAVE_ABSEIL) -namespace absl -{ -namespace variant_internal -{ -void __cdecl ThrowBadVariantAccess(){/* TODO: std::terminate or re-throw? */}; -} -} // namespace absl -#endif +#include "opentelemetry/nostd/variant.h" +#include "opentelemetry/version.h" + +#if defined(HAVE_ABSEIL) +namespace absl +{ +namespace variant_internal +{ +void __cdecl ThrowBadVariantAccess(){/* TODO: std::terminate or re-throw? */}; +} +} // namespace absl +#endif diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index 604191d365..e2dd5f69e0 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -1,40 +1,40 @@ -#include "opentelemetry/sdk/trace/tracer_provider.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace trace -{ -TracerProvider::TracerProvider(std::shared_ptr processor, - std::shared_ptr sampler) noexcept - : processor_{processor}, tracer_(new Tracer(std::move(processor), sampler)), sampler_(sampler) -{} - -opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( - nostd::string_view library_name, - nostd::string_view library_version) noexcept -{ - // TODO: do we have to transform this at all, if we can keep it nostd::shared_ptr at source? - return tracer_; -} - -void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept -{ - processor_.store(processor); - - auto sdkTracer = static_cast(tracer_.get()); - sdkTracer->SetProcessor(processor); -} - -std::shared_ptr TracerProvider::GetProcessor() const noexcept -{ - return processor_.load(); -} - -std::shared_ptr TracerProvider::GetSampler() const noexcept -{ - return sampler_; -} -} // namespace trace -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE +#include "opentelemetry/sdk/trace/tracer_provider.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +TracerProvider::TracerProvider(std::shared_ptr processor, + std::shared_ptr sampler) noexcept + : processor_{processor}, tracer_(new Tracer(std::move(processor), sampler)), sampler_(sampler) +{} + +opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( + nostd::string_view library_name, + nostd::string_view library_version) noexcept +{ + // TODO: do we have to transform this at all, if we can keep it nostd::shared_ptr at source? + return tracer_; +} + +void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept +{ + processor_.store(processor); + + auto sdkTracer = static_cast(tracer_.get()); + sdkTracer->SetProcessor(processor); +} + +std::shared_ptr TracerProvider::GetProcessor() const noexcept +{ + return processor_.load(); +} + +std::shared_ptr TracerProvider::GetSampler() const noexcept +{ + return sampler_; +} +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/test/common/CMakeLists.txt b/sdk/test/common/CMakeLists.txt index f1028bf6d8..17e37f2a2f 100644 --- a/sdk/test/common/CMakeLists.txt +++ b/sdk/test/common/CMakeLists.txt @@ -5,10 +5,7 @@ foreach(testname target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} opentelemetry_common opentelemetry_trace) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX trace. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) endforeach() add_executable(random_fork_test random_fork_test.cc) diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index dbab882a46..8991c10f49 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -14,8 +14,5 @@ foreach( target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX metrics. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/trace/CMakeLists.txt b/sdk/test/trace/CMakeLists.txt index 1798386884..0dab8e9d6e 100644 --- a/sdk/test/trace/CMakeLists.txt +++ b/sdk/test/trace/CMakeLists.txt @@ -19,10 +19,7 @@ foreach( opentelemetry_common opentelemetry_trace opentelemetry_exporter_in_memory) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX trace. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) endforeach() add_executable(sampler_benchmark sampler_benchmark.cc) From c9be76b60212b49da064704221af400cc5fff447 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 26 Oct 2020 16:44:17 -0700 Subject: [PATCH 03/54] - Fix build issues with Ubuntu 18.04 and older CMake - Add deps as submodules --- CMakeLists.txt | 9 +++++++-- third_party/benchmark | 1 + third_party/googletest | 1 + third_party/ms-gsl | 1 + tools/build.sh | 5 +++-- tools/format.sh | 2 +- tools/vcpkg | 1 + 7 files changed, 15 insertions(+), 5 deletions(-) create mode 160000 third_party/benchmark create mode 160000 third_party/googletest create mode 160000 third_party/ms-gsl create mode 160000 tools/vcpkg diff --git a/CMakeLists.txt b/CMakeLists.txt index 428128565e..436621c785 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,8 +31,13 @@ if(WITH_STL) # Require at least C++17. C++20 is needed to avoid gsl::span add_definitions(-DHAVE_CPP_STDLIB -DHAVE_GSL) - # Ask for 20, but may get C++17 - set(CMAKE_CXX_STANDARD 20) + if(CMAKE_MINOR_VERSION VERSION_LESS "3.18") + # Ask for 20, may get anything below + set(CMAKE_CXX_STANDARD 20) + else() + # Ask for 17, may get anything below + set(CMAKE_CXX_STANDARD 17) + endif() # Guidelines Support Library path. Used if we are not on not get C++20. # diff --git a/third_party/benchmark b/third_party/benchmark new file mode 160000 index 0000000000..dce3322a54 --- /dev/null +++ b/third_party/benchmark @@ -0,0 +1 @@ +Subproject commit dce3322a549650d18f50b5f1428a5942327ab6a5 diff --git a/third_party/googletest b/third_party/googletest new file mode 160000 index 0000000000..a6dfd3aca7 --- /dev/null +++ b/third_party/googletest @@ -0,0 +1 @@ +Subproject commit a6dfd3aca7f2f91f95fc7ab650c95a48420d513d diff --git a/third_party/ms-gsl b/third_party/ms-gsl new file mode 160000 index 0000000000..6f4529395c --- /dev/null +++ b/third_party/ms-gsl @@ -0,0 +1 @@ +Subproject commit 6f4529395c5b7c2d661812257cd6780c67e54afa diff --git a/tools/build.sh b/tools/build.sh index fda44d9208..aa9b5c7f7c 100644 --- a/tools/build.sh +++ b/tools/build.sh @@ -67,9 +67,10 @@ function build_configuration { cd $WORKSPACE_ROOT OUTDIR=out/$COMPILER_NAME/$BUILD_CONFIG mkdir -p $OUTDIR - cmake -B $OUTDIR $BUILD_OPTIONS - cd $OUTDIR + pushd $OUTDIR + cmake $BUILD_OPTIONS $WORKSPACE_ROOT make + popd } build_configuration nostd '-DWITH_STL:BOOL=OFF' diff --git a/tools/format.sh b/tools/format.sh index 6fc4a4ae42..2e9ad3fb54 100755 --- a/tools/format.sh +++ b/tools/format.sh @@ -6,7 +6,7 @@ fi set -e -FIND="find . -name third_party -prune -o -name tools -prune -o -name .git -prune -o -name _deps -prune -o -name .build -prune -o" +FIND="find . -name third_party -prune -o -name tools -prune -o -name .git -prune -o -name _deps -prune -o -name .build -prune -o -name out -prune -o" # GNU syntax. SED=(sed -i) diff --git a/tools/vcpkg b/tools/vcpkg new file mode 160000 index 0000000000..e9f8cc67a5 --- /dev/null +++ b/tools/vcpkg @@ -0,0 +1 @@ +Subproject commit e9f8cc67a5e5541973e53ac03f88adb45cc1b21b From c3efe3cea4c9f75f34c1a2f0feb4b3d8318a0d56 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 26 Oct 2020 16:57:42 -0700 Subject: [PATCH 04/54] Modify file permissions to +x --- tools/build-all.sh | 0 tools/build-gtest.sh | 0 tools/build.sh | 0 tools/git-cl.sh | 0 tools/setup-buildtools-mac.sh | 0 tools/setup-buildtools.sh | 0 tools/setup-devenv.sh | 0 7 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/build-all.sh mode change 100644 => 100755 tools/build-gtest.sh mode change 100644 => 100755 tools/build.sh mode change 100644 => 100755 tools/git-cl.sh mode change 100644 => 100755 tools/setup-buildtools-mac.sh mode change 100644 => 100755 tools/setup-buildtools.sh mode change 100644 => 100755 tools/setup-devenv.sh diff --git a/tools/build-all.sh b/tools/build-all.sh old mode 100644 new mode 100755 diff --git a/tools/build-gtest.sh b/tools/build-gtest.sh old mode 100644 new mode 100755 diff --git a/tools/build.sh b/tools/build.sh old mode 100644 new mode 100755 diff --git a/tools/git-cl.sh b/tools/git-cl.sh old mode 100644 new mode 100755 diff --git a/tools/setup-buildtools-mac.sh b/tools/setup-buildtools-mac.sh old mode 100644 new mode 100755 diff --git a/tools/setup-buildtools.sh b/tools/setup-buildtools.sh old mode 100644 new mode 100755 diff --git a/tools/setup-devenv.sh b/tools/setup-devenv.sh old mode 100644 new mode 100755 From bbbf85095ac8000a692fec4660a8200a671cad6e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 26 Oct 2020 21:47:59 -0700 Subject: [PATCH 05/54] Collection of build tools (no code changes) --- .gitignore | 6 ++ .gitmodules | 19 ++++++ ci/do_ci.sh | 1 + third_party/benchmark | 1 + third_party/googletest | 1 + third_party/ms-gsl | 1 + tools/build-benchmark.cmd | 35 +++++++++++ tools/build-gtest.sh | 28 +++++++++ tools/build-vs2015.cmd | 6 ++ tools/build-vs2017.cmd | 5 ++ tools/build-vs2019.cmd | 5 ++ tools/build.cmd | 74 ++++++++++++++++++++++++ tools/build.sh | 74 ++++++++++++++++++++++++ tools/download.cmd | 3 + tools/download.ps1 | 4 ++ tools/format.sh | 2 +- tools/git-cl.sh | 0 tools/install-vs-addons.cmd | 39 +++++++++++++ tools/install_llvm-win32.ps1 | 8 +++ tools/install_llvm-win64.ps1 | 8 +++ tools/ports/benchmark/CONTROL | 5 ++ tools/ports/benchmark/portfile.cmake | 49 ++++++++++++++++ tools/setup-buildtools-mac.sh | 3 + tools/setup-buildtools.cmd | 50 ++++++++++++++++ tools/setup-buildtools.sh | 13 ++--- tools/setup-devenv.sh | 0 tools/vcpkg | 1 + tools/vcvars.cmd | 86 ++++++++++++++++++++++++++++ 28 files changed, 519 insertions(+), 8 deletions(-) create mode 160000 third_party/benchmark create mode 160000 third_party/googletest create mode 160000 third_party/ms-gsl create mode 100644 tools/build-benchmark.cmd create mode 100755 tools/build-gtest.sh create mode 100644 tools/build-vs2015.cmd create mode 100644 tools/build-vs2017.cmd create mode 100644 tools/build-vs2019.cmd create mode 100644 tools/build.cmd create mode 100755 tools/build.sh create mode 100644 tools/download.cmd create mode 100644 tools/download.ps1 mode change 100644 => 100755 tools/git-cl.sh create mode 100644 tools/install-vs-addons.cmd create mode 100644 tools/install_llvm-win32.ps1 create mode 100644 tools/install_llvm-win64.ps1 create mode 100644 tools/ports/benchmark/CONTROL create mode 100644 tools/ports/benchmark/portfile.cmake mode change 100644 => 100755 tools/setup-buildtools-mac.sh create mode 100644 tools/setup-buildtools.cmd mode change 100644 => 100755 tools/setup-buildtools.sh mode change 100644 => 100755 tools/setup-devenv.sh create mode 160000 tools/vcpkg create mode 100644 tools/vcvars.cmd diff --git a/.gitignore b/.gitignore index ae5b7926b2..360c37e288 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,9 @@ # Bazel files /bazel-* + +# Output directories +/out +/out.* +# Indicator that the tools were deployed +.buildtools diff --git a/.gitmodules b/.gitmodules index 94dac0ba74..e1d94ec89a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,22 @@ [submodule "third_party/prometheus-cpp"] path = third_party/prometheus-cpp url = https://github.com/jupp0r/prometheus-cpp.git + +[submodule "tools/vcpkg"] + path = tools/vcpkg + url = https://github.com/Microsoft/vcpkg + branch = master + +[submodule "third_party/ms-gsl"] + path = third_party/ms-gsl + url = https://github.com/microsoft/GSL + branch = master + +[submodule "third_party/googletest"] + path = third_party/googletest + url = https://github.com/google/googletest + branch = master + +[submodule "third_party/benchmark"] + path = third_party/benchmark + url = https://github.com/google/benchmark diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 4790daabf5..5f64601521 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -156,6 +156,7 @@ elif [[ "$1" == "format" ]]; then if [[ ! -z "$CHANGED" ]]; then echo "The following files have changes:" echo "$CHANGED" + git diff exit 1 fi exit 0 diff --git a/third_party/benchmark b/third_party/benchmark new file mode 160000 index 0000000000..dce3322a54 --- /dev/null +++ b/third_party/benchmark @@ -0,0 +1 @@ +Subproject commit dce3322a549650d18f50b5f1428a5942327ab6a5 diff --git a/third_party/googletest b/third_party/googletest new file mode 160000 index 0000000000..a6dfd3aca7 --- /dev/null +++ b/third_party/googletest @@ -0,0 +1 @@ +Subproject commit a6dfd3aca7f2f91f95fc7ab650c95a48420d513d diff --git a/third_party/ms-gsl b/third_party/ms-gsl new file mode 160000 index 0000000000..6f4529395c --- /dev/null +++ b/third_party/ms-gsl @@ -0,0 +1 @@ +Subproject commit 6f4529395c5b7c2d661812257cd6780c67e54afa diff --git a/tools/build-benchmark.cmd b/tools/build-benchmark.cmd new file mode 100644 index 0000000000..39b9f180d9 --- /dev/null +++ b/tools/build-benchmark.cmd @@ -0,0 +1,35 @@ +@echo off +set VS_TOOLS_VERSION=vs2019 +set CMAKE_GEN="Visual Studio 16 2019" +echo Building Google Benchmark (test only dependency)... +@setlocal ENABLEEXTENSIONS + +echo Auto-detecting Visual Studio version... +call "%~dp0\vcvars.cmd" + +pushd "%~dp0\.." +set "ROOT=%CD%" + +set MAXCPUCOUNT=%NUMBER_OF_PROCESSORS% +set platform= + +if not exist "%ROOT%\third_party\benchmark\" ( + echo "Google Benchmark library is not available, skipping benchmark build." + call skip_the_build +) + +cd "%ROOT%\third_party\benchmark\" +set "GOOGLETEST_PATH=%ROOT%\third_party\googletest" +if not exist "build" ( + mkdir build +) +cd build + +REM By default we generate the project for the older Visual Studio 2017 even if we have newer version installed +cmake ../ -G %CMAKE_GEN% -Ax64 -DBENCHMARK_ENABLE_TESTING=OFF +set SOLUTION=%ROOT%\third_party\benchmark\build\benchmark.sln +msbuild %SOLUTION% /maxcpucount:%MAXCPUCOUNT% /p:Configuration=Debug /p:Platform=x64 +msbuild %SOLUTION% /maxcpucount:%MAXCPUCOUNT% /p:Configuration=Release /p:Platform=x64 +popd + +:skip_the_build diff --git a/tools/build-gtest.sh b/tools/build-gtest.sh new file mode 100755 index 0000000000..d2573b885a --- /dev/null +++ b/tools/build-gtest.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +if [ "$1" == "ios" ]; then + IOS_BUILD="YES" + # Skip building tests on iOS as there is no way to run them + BUILD_TESTS="OFF" +else + IOS_BUILD="NO" + BUILD_TESTS="ON" +fi + +pushd `dirname $0`/.. +cd third_party/googletest +set -evx +env | sort +rm -rf build +mkdir -p build || true +cd build +cmake -Dgtest_build_samples=OFF \ + -Dgmock_build_samples=OFF \ + -Dgtest_build_tests=OFF \ + -Dgmock_build_tests=OFF \ + -DCMAKE_CXX_FLAGS="-fPIC $CXX_FLAGS" \ + -DBUILD_IOS=$IOS_BUILD \ + -DCMAKE_CXX_STANDARD=17 \ + .. +make +make install +popd diff --git a/tools/build-vs2015.cmd b/tools/build-vs2015.cmd new file mode 100644 index 0000000000..a80ca66409 --- /dev/null +++ b/tools/build-vs2015.cmd @@ -0,0 +1,6 @@ +set "VS_TOOLS_VERSION=vs2015" +REM Ref. https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2014%202015.html +set "CMAKE_GEN=Visual Studio 14 2015 Win64" +cd %~dp0 +call setup-buildtools.cmd +call build.cmd -DWITH_ABSEIL:BOOL=ON diff --git a/tools/build-vs2017.cmd b/tools/build-vs2017.cmd new file mode 100644 index 0000000000..be4322892c --- /dev/null +++ b/tools/build-vs2017.cmd @@ -0,0 +1,5 @@ +set "VS_TOOLS_VERSION=vs2017" +set "CMAKE_GEN=Visual Studio 15 2017 Win64" +cd %~dp0 +call setup-buildtools.cmd +call build.cmd diff --git a/tools/build-vs2019.cmd b/tools/build-vs2019.cmd new file mode 100644 index 0000000000..554c291a31 --- /dev/null +++ b/tools/build-vs2019.cmd @@ -0,0 +1,5 @@ +set "VS_TOOLS_VERSION=vs2019" +set "CMAKE_GEN=Visual Studio 16 2019" +cd %~dp0 +call setup-buildtools.cmd +call build.cmd diff --git a/tools/build.cmd b/tools/build.cmd new file mode 100644 index 0000000000..e49bc14289 --- /dev/null +++ b/tools/build.cmd @@ -0,0 +1,74 @@ +@echo off +REM Currently we require Visual Studio 2019 for C++20 build targeting Release/x64. +REM +REM TODO: allow specifying compiler version as argument. +REM +REM Supported versions for nostd build: +REM - vs2015 (C++11) +REM - vs2017 (C++14) +REM - vs2019 (C++20) +REM +REM Supported versions for STL build: +REM - vs2017 (C++14) +REM - vs2019 (C++20) +REM + +if "%VS_TOOLS_VERSION%" == "" set "VS_TOOLS_VERSION=vs2019" +if "%CMAKE_GEN%" == "" set "CMAKE_GEN=Visual Studio 16 2019" + +pushd %~dp0 +setlocal enableextensions +setlocal enabledelayedexpansion +set "ROOT=%~dp0\.." + +REM Use preinstalled vcpkg if installed or use our local +if "%VCPKG_INSTALLATION_ROOT%" neq "" ( + set "VCPKG_CMAKE=%VCPKG_INSTALLATION_ROOT%\scripts\buildsystems\vcpkg.cmake" +) else ( + set "VCPKG_CMAKE=%CD%\vcpkg\scripts\buildsystems\vcpkg.cmake" +) + +REM ******************************************************************** +REM Setup compiler environment +REM ******************************************************************** +call "%~dp0\vcvars.cmd" + + +REM ******************************************************************** +REM Use cmake +REM ******************************************************************** +set "PATH=%PATH%;C:\Program Files\CMake\bin\" + +REM ******************************************************************** +REM Build with nostd implementation +REM ******************************************************************** +set CONFIG=-DWITH_STL:BOOL=OFF %* +set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\nostd" +call :build_config + +REM ******************************************************************** +REM Build with STL implementation - only for vs2017+ +REM ******************************************************************** +if "%VS_TOOLS_VERSION%" neq "vs2015" ( + set CONFIG=-DWITH_STL:BOOL=ON + set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\stl" + call :build_config +) + +popd +REM ******************************************************************** + + +REM ******************************************************************** +REM Function that allows to build given build configuration +REM ******************************************************************** +:build_config +REM TODO: consider rmdir for clean builds +if not exist "%OUTDIR%" mkdir "%OUTDIR%" +cd "%OUTDIR%" +REM Optional platform specification parameter below: -Ax64 +cmake %ROOT% -G "%CMAKE_GEN%" -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +set "SOLUTION=%OUTDIR%\opentelemetry-cpp.sln" +REM TODO: allow building [Release|Debug]x[Win32|x64|ARM|ARM64] +msbuild "%SOLUTION%" /p:Configuration=Release /p:Platform=x64 /p:VcpkgEnabled=true +exit /b 0 diff --git a/tools/build.sh b/tools/build.sh new file mode 100755 index 0000000000..3a25c5bc3f --- /dev/null +++ b/tools/build.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +export PATH=/usr/local/bin:$PATH + +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +cd $WORKSPACE_ROOT +echo "Current directory is `pwd`" + +export NOROOT=$NOROOT + +if [ "$1" == "clean" ]; then + rm -f CMakeCache.txt *.cmake + rm -rf out + rm -rf .buildtools +# make clean +fi + +if [ "$1" == "noroot" ] || [ "$2" == "noroot" ]; then +export NOROOT=true +fi + +if [ "$1" == "release" ] || [ "$2" == "release" ]; then +BUILD_TYPE="release" +else +BUILD_TYPE="debug" +fi + +# Set target MacOS minver +export MACOSX_DEPLOYMENT_TARGET=10.10 + +# Install build tools +FILE=.buildtools +OS_NAME=`uname -a` +if [ ! -f $FILE ]; then +case "$OS_NAME" in + *Darwin*) tools/setup-buildtools-mac.sh ;; + *Linux*) [[ -z "$NOROOT" ]] && sudo tools/setup-buildtools.sh || echo "No root: skipping build tools installation." ;; + *) echo "WARNING: unsupported OS $OS_NAME , skipping build tools installation.." +esac +# Assume that the build tools have been successfully installed +echo > $FILE +fi + +# TODO: fix compiler-version reporting +if [ -f /usr/bin/gcc ]; then +echo "gcc version: `gcc --version`" +COMPILER_NAME=gcc-`gcc -dumpversion` +fi + +if [ -f /usr/bin/clang ]; then +echo "clang version: `clang --version`" +COMPILER_NAME=clang-`clang -dumpversion` +fi + +# TODO: build and install Google Test from source if necessary + +function build_configuration { + BUILD_CONFIG=$1 + BUILD_OPTIONS=$2 + + echo "Build configuration: $BUILD_CONFIG" + cd $WORKSPACE_ROOT + OUTDIR=out/$COMPILER_NAME/$BUILD_CONFIG + mkdir -p $OUTDIR + pushd $OUTDIR + cmake $BUILD_OPTIONS $WORKSPACE_ROOT + make + popd +} + +# Example +build_configuration nostd '-DWITH_MY_OPTION:BOOL=OFF' + diff --git a/tools/download.cmd b/tools/download.cmd new file mode 100644 index 0000000000..97f546863b --- /dev/null +++ b/tools/download.cmd @@ -0,0 +1,3 @@ +@REM This script allows to download a file to local machine. First argument is URL +set "PATH=C:\Windows;C:\Windows\System32;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\bin" +@powershell -File Download.ps1 %1 diff --git a/tools/download.ps1 b/tools/download.ps1 new file mode 100644 index 0000000000..c759601aea --- /dev/null +++ b/tools/download.ps1 @@ -0,0 +1,4 @@ +$url=$args[0] +$arr=$args[0].Split("/") +$fileName=$arr[$arr.Count-1] +Invoke-WebRequest -Uri $url -OutFile $fileName -UseBasicParsing diff --git a/tools/format.sh b/tools/format.sh index 7d5249d5e3..2e9ad3fb54 100755 --- a/tools/format.sh +++ b/tools/format.sh @@ -6,7 +6,7 @@ fi set -e -FIND="find . -name .git -prune -o -name _deps -prune -o -name .build -prune -o" +FIND="find . -name third_party -prune -o -name tools -prune -o -name .git -prune -o -name _deps -prune -o -name .build -prune -o -name out -prune -o" # GNU syntax. SED=(sed -i) diff --git a/tools/git-cl.sh b/tools/git-cl.sh old mode 100644 new mode 100755 diff --git a/tools/install-vs-addons.cmd b/tools/install-vs-addons.cmd new file mode 100644 index 0000000000..e4c866be33 --- /dev/null +++ b/tools/install-vs-addons.cmd @@ -0,0 +1,39 @@ +set "PATH=C:\Windows;C:\Windows\System32;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\bin" +cd %~dp0 +call powershell -File .\install_llvm-win64.ps1 + +REM Download Visual Studio LLVM extension required for clang build to succeed +call download.cmd https://llvmextensions.gallerycdn.vsassets.io/extensions/llvmextensions/llvm-toolchain/1.0.363769/1560930595399/llvm.vsix + +REM Install optional components required for ARM build - vs2017-BuildTools +IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" ( +"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^ + -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" -q ^ + --add Microsoft.VisualStudio.Component.VC.ATL ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 +"%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\Common7\IDE\VSIXInstaller.exe" /q /a llvm.vsix +) + +REM Install optional components required for ARM build - vs2017-Enterprise +IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" ( +"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^ + -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" -q ^ + --add Microsoft.VisualStudio.Component.VC.ATL ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 +"%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VSIXInstaller.exe" /q /a llvm.vsix +) + +REM Install optional components required for ARM build - vs2019-Enterprise +IF EXIST %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise ( +"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe" ^ + -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise" -q ^ + --add Microsoft.VisualStudio.Component.VC.ATL ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ + --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 +"%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VSIXInstaller.exe" /q /a llvm.vsix +) + +REM Ignore failures if components have been already installed +EXIT /b 0 diff --git a/tools/install_llvm-win32.ps1 b/tools/install_llvm-win32.ps1 new file mode 100644 index 0000000000..89b697f400 --- /dev/null +++ b/tools/install_llvm-win32.ps1 @@ -0,0 +1,8 @@ +$llvmVersion = "10.0.0" +Write-Host "Installing LLVM $llvmVersion ..." -ForegroundColor Cyan +Write-Host "Downloading..." +$exePath = "$env:temp\LLVM-$llvmVersion-win32.exe" +(New-Object Net.WebClient).DownloadFile("https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvmVersion/LLVM-$llvmVersion-win32.exe", $exePath) +Write-Host "Installing..." +cmd /c start /wait $exePath /S +Write-Host "Installed" -ForegroundColor Green diff --git a/tools/install_llvm-win64.ps1 b/tools/install_llvm-win64.ps1 new file mode 100644 index 0000000000..d4a2379fa2 --- /dev/null +++ b/tools/install_llvm-win64.ps1 @@ -0,0 +1,8 @@ +$llvmVersion = "10.0.0" +Write-Host "Installing LLVM $llvmVersion ..." -ForegroundColor Cyan +Write-Host "Downloading..." +$exePath = "$env:temp\LLVM-$llvmVersion-win64.exe" +(New-Object Net.WebClient).DownloadFile("https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvmVersion/LLVM-$llvmVersion-win64.exe", $exePath) +Write-Host "Installing..." +cmd /c start /wait $exePath /S +Write-Host "Installed" -ForegroundColor Green diff --git a/tools/ports/benchmark/CONTROL b/tools/ports/benchmark/CONTROL new file mode 100644 index 0000000000..62b80dffae --- /dev/null +++ b/tools/ports/benchmark/CONTROL @@ -0,0 +1,5 @@ +Source: benchmark +Version: 1.5.1 +Homepage: https://github.com/google/benchmark +Description: A library to support the benchmarking of functions, similar to unit-tests. +Supports: !uwp \ No newline at end of file diff --git a/tools/ports/benchmark/portfile.cmake b/tools/ports/benchmark/portfile.cmake new file mode 100644 index 0000000000..e89fafca6c --- /dev/null +++ b/tools/ports/benchmark/portfile.cmake @@ -0,0 +1,49 @@ +if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + message(FATAL_ERROR "${PORT} does not currently support UWP") +endif() + +if (VCPKG_PLATFORM_TOOLSET STREQUAL "v140") + # set(CMAKE_C_COMPILER_WORKS 1) + # set(CMAKE_CXX_COMPILER_WORKS 1) + set(CMAKE_C_COMPILER cl.exe) + set(CMAKE_CXX_COMPILER cl.exe) + set(MSVC_TOOLSET_VERSION 140) + # set(VCPKG_VISUAL_STUDIO_PATH "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0") + # set(VCPKG_PLATFORM_TOOLSET v140) +else() + # Make sure vs2019 compiled binaries are compat with vs2017 + set(VCPKG_CXX_FLAGS "/Zc:__cplusplus /d2FH4-") + set(VCPKG_C_FLAGS "/Zc:__cplusplus /d2FH4-") + set(PREFER PREFER_NINJA) +endif() + +include(vcpkg_common_functions) + +vcpkg_check_linkage(ONLY_STATIC_LIBRARY) + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO google/benchmark + HEAD_REF master +) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + ${PREFER} + OPTIONS + -DBENCHMARK_ENABLE_TESTING=OFF + -DCMAKE_DEBUG_POSTFIX=d +) + +vcpkg_install_cmake() + +vcpkg_copy_pdbs() + +vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/benchmark) + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share) + +# Handle copyright +file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/benchmark) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/benchmark/LICENSE ${CURRENT_PACKAGES_DIR}/share/benchmark/copyright) diff --git a/tools/setup-buildtools-mac.sh b/tools/setup-buildtools-mac.sh old mode 100644 new mode 100755 index aee85a456f..cf3090237e --- a/tools/setup-buildtools-mac.sh +++ b/tools/setup-buildtools-mac.sh @@ -24,8 +24,11 @@ sudo chown -R $(whoami) /usr/local/var/homebrew sudo chown -R $(whoami) /usr/local/etc/bash_completion.d /usr/local/include /usr/local/lib/pkgconfig /usr/local/share/aclocal /usr/local/share/locale /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew/locks brew install cmake +brew install coreutils brew install wget brew install clang-format brew install google-benchmark brew tap nlohmann/json brew install nlohmann-json +brew install abseil +./tools/build-gtest.sh diff --git a/tools/setup-buildtools.cmd b/tools/setup-buildtools.cmd new file mode 100644 index 0000000000..830c650c07 --- /dev/null +++ b/tools/setup-buildtools.cmd @@ -0,0 +1,50 @@ +@echo off +set "PATH=%PATH%;%~dp0;%~dp0\vcpkg" +pushd %~dp0 + +REM Fail if chocolatey is not installed +where /Q choco +if ERRORLEVEL 1 ( + echo This script requires chocolatey. Installation instructions: https://chocolatey.org/docs/installation + exit -1 +) + +REM Print current Visual Studio installations detected +where /Q vswhere +if ERRORLEVEL 0 ( + echo Visual Studio installations detected: + vswhere -property installationPath +) + +REM Install tools needed for building stuff +choco install -y cmake +choco install -y svn +choco install -y git +choco install -y llvm +choco install -y zip + +REM Try to autodetect Visual Studio +call "%~dp0\vcvars.cmd" +if "%TOOLS_VS_NOTFOUND%" == "1" ( + REM Cannot detect MSBuild path + REM TODO: no command line tools.. + REM TODO: use MSBuild from vswhere? +) + +where /Q vcpkg.exe +if ERRORLEVEL 1 ( + REM Build our own vcpkg from source + pushd .\vcpkg + call bootstrap-vcpkg.bat + popd +) + +REM Install it +vcpkg install gtest:x64-windows +vcpkg install --head --overlay-ports=%~dp0\ports benchmark:x64-windows +vcpkg install ms-gsl:x64-windows +vcpkg install nlohmann-json:x64-windows +vcpkg install abseil:x64-windows +vcpkg integrate install +popd +exit /b 0 diff --git a/tools/setup-buildtools.sh b/tools/setup-buildtools.sh old mode 100644 new mode 100755 index f118e16070..a5fe2c5f0c --- a/tools/setup-buildtools.sh +++ b/tools/setup-buildtools.sh @@ -22,13 +22,6 @@ yum -y install devtoolset-7-valgrind yum-config-manager --enable rhel-server-rhscl-7-rpms -if [ `gcc --version | grep 7` == "" ]; then -echo "*********************************************************" -echo "*** Please make sure you start the build with gcc-7 ***" -echo "*** > scl enable devtoolset-7 ./build.sh ***" -echo "*********************************************************" -exit 3 -fi if [ `cmake --version | grep 3` == "" ]; then yum -y remove cmake @@ -59,7 +52,13 @@ apt-get install -qq libsqlite3-dev #apt install libsqlite3-dev apt-get install -qq wget apt-get install -qq clang-format +apt-get install -qq gtest +apt-get install -qq libgtest-dev +apt-get install -qq libbenchmark-dev +apt-get install -qq nlohmann-json-dev fi ## Change owner from root to current dir owner chown -R `stat . -c %u:%g` * + +./tools/build-gtest.sh diff --git a/tools/setup-devenv.sh b/tools/setup-devenv.sh old mode 100644 new mode 100755 diff --git a/tools/vcpkg b/tools/vcpkg new file mode 160000 index 0000000000..e9f8cc67a5 --- /dev/null +++ b/tools/vcpkg @@ -0,0 +1 @@ +Subproject commit e9f8cc67a5e5541973e53ac03f88adb45cc1b21b diff --git a/tools/vcvars.cmd b/tools/vcvars.cmd new file mode 100644 index 0000000000..1b8215fcbb --- /dev/null +++ b/tools/vcvars.cmd @@ -0,0 +1,86 @@ +@echo off +REM +REM Make sure to enable the 'Visual C++ ATL' components for all platforms during the setup. +REM +REM This build script auto-detects and configures Visual Studio in the following order: +REM 1. Visual Studio 2017 Enterprise +REM 2. Visual Studio 2017 BuildTools +REM 3. Visual Studio 2019 Enterprise +REM 4. Visual Studio 2019 Community +REM 5. Visual Studio 2019 BuildTools +REM + +REM 1st parameter - Visual Studio version +if "%1" neq "" ( + goto %1 +) + +if "%VS_TOOLS_VERSION%" neq "" ( + goto %VS_TOOLS_VERSION% +) + +REM vs2017 Enterprise +:vs2017 +:vs2017_enterprise +set TOOLS_VS2017_ENTERPRISE="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2017_ENTERPRISE% ( + echo Building with vs2017 Enterprise... + call %TOOLS_VS2017_ENTERPRISE% + goto tools_configured +) + +REM vs2017 BuildTools +:vs2017_buildtools +set TOOLS_VS2017="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2017% ( + echo Building with vs2017 BuildTools... + call %TOOLS_VS2017% + goto tools_configured +) + +REM vs2019 Enterprise +:vs2019 +:vs2019_enterprise +set TOOLS_VS2019_ENTERPRISE="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2019_ENTERPRISE% ( + echo Building with vs2019 Enterprise... + call %TOOLS_VS2019_ENTERPRISE% + goto tools_configured +) + +REM vs2019 Community +:vs2019_community +set TOOLS_VS2019_COMMUNITY="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2019_COMMUNITY% ( + echo Building with vs2019 Community... + call %TOOLS_VS2019_COMMUNITY% + goto tools_configured +) + +REM vs2019 BuildTools +:vs2019_buildtools +set TOOLS_VS2019="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" +if exist %TOOLS_VS2019% ( + echo Building with vs2019 BuildTools... + call %TOOLS_VS2019% + goto tools_configured +) + +REM vs2015 +:vs2015 +set TOOLS_VS2015="%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat" +if exist %TOOLS_VS2015% ( + echo Building with vs2015 BuildTools... + call %TOOLS_VS2015% + set "VCPKG_VISUAL_STUDIO_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0" + set VCPKG_PLATFORM_TOOLSET=v140 + goto tools_configured +) + +echo WARNING:********************************************* +echo WARNING: cannot auto-detect Visual Studio version !!! +echo WARNING:********************************************* +set TOOLS_VS_NOTFOUND=1 +exit /b 0 + +:tools_configured From 7c46e02a5083669d76c855aa87dffe186d8935fe Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 13 Nov 2020 19:16:41 -0800 Subject: [PATCH 06/54] Add docker files for developer build --- docker/ubuntu14.04/Dockerfile | 29 +++++++++++++++++++++++++ docker/ubuntu16.04/Dockerfile | 31 ++++++++++++++++++++++++++ docker/ubuntu18.04/Dockerfile | 30 +++++++++++++++++++++++++ docker/ubuntu20.04/Dockerfile | 30 +++++++++++++++++++++++++ tools/build-docker.cmd | 41 +++++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+) create mode 100644 docker/ubuntu14.04/Dockerfile create mode 100644 docker/ubuntu16.04/Dockerfile create mode 100644 docker/ubuntu18.04/Dockerfile create mode 100644 docker/ubuntu20.04/Dockerfile create mode 100644 tools/build-docker.cmd diff --git a/docker/ubuntu14.04/Dockerfile b/docker/ubuntu14.04/Dockerfile new file mode 100644 index 0000000000..b2add385c2 --- /dev/null +++ b/docker/ubuntu14.04/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:14.04 +ENV DEBIAN_FRONTEND noninteractive + +## Update cache and upgrade image +RUN apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade + +## Build environment packages +RUN apt-get install -qq -y --ignore-missing \ + apt-utils \ + automake \ + build-essential \ + bzip2 \ + cmake \ + curl \ + git \ + libcurl4-openssl-dev \ + libssl-dev \ + make \ + pkg-config \ + python \ + sudo \ + tar \ + zip \ + unzip \ + wget \ + zlib1g-dev + +# ENTRYPOINT bash +CMD /bin/bash diff --git a/docker/ubuntu16.04/Dockerfile b/docker/ubuntu16.04/Dockerfile new file mode 100644 index 0000000000..abe3506fa9 --- /dev/null +++ b/docker/ubuntu16.04/Dockerfile @@ -0,0 +1,31 @@ +FROM ubuntu:16.04 +ENV DEBIAN_FRONTEND noninteractive + +## Update cache and upgrade image +RUN apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade + +## Build environment packages +RUN apt-get install -qq -y --ignore-missing \ + apt-utils \ + automake \ + build-essential \ + bzip2 \ + cmake \ + curl \ + git \ + libcurl4-openssl-dev \ + libsqlite3-dev \ + libssl-dev \ + libtool-bin \ + make \ + pkg-config \ + python \ + sudo \ + tar \ + zip \ + unzip \ + wget \ + zlib1g-dev + +# ENTRYPOINT bash +CMD /bin/bash diff --git a/docker/ubuntu18.04/Dockerfile b/docker/ubuntu18.04/Dockerfile new file mode 100644 index 0000000000..0b618de972 --- /dev/null +++ b/docker/ubuntu18.04/Dockerfile @@ -0,0 +1,30 @@ +FROM ubuntu:18.04 +ENV DEBIAN_FRONTEND noninteractive + +## Update cache and upgrade image +RUN apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade + +## Build environment packages +RUN apt-get install -qq -y --ignore-missing \ + apt-utils \ + automake \ + build-essential \ + bzip2 \ + cmake \ + curl \ + git \ + libcurl4-openssl-dev \ + libssl-dev \ + libtool-bin \ + make \ + pkg-config \ + python \ + sudo \ + tar \ + zip \ + unzip \ + wget \ + zlib1g-dev + +# ENTRYPOINT bash +CMD /bin/bash diff --git a/docker/ubuntu20.04/Dockerfile b/docker/ubuntu20.04/Dockerfile new file mode 100644 index 0000000000..5f0f40a2a7 --- /dev/null +++ b/docker/ubuntu20.04/Dockerfile @@ -0,0 +1,30 @@ +FROM ubuntu:20.04 +ENV DEBIAN_FRONTEND noninteractive + +## Update cache and upgrade image +RUN apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade + +## Build environment packages +RUN apt-get install -qq -y --ignore-missing \ + apt-utils \ + automake \ + build-essential \ + bzip2 \ + cmake \ + curl \ + git \ + libcurl4-openssl-dev \ + libssl-dev \ + libtool-bin \ + make \ + pkg-config \ + python \ + sudo \ + tar \ + zip \ + unzip \ + wget \ + zlib1g-dev + +# ENTRYPOINT bash +CMD /bin/bash diff --git a/tools/build-docker.cmd b/tools/build-docker.cmd new file mode 100644 index 0000000000..39c4e49d56 --- /dev/null +++ b/tools/build-docker.cmd @@ -0,0 +1,41 @@ +@echo off +pushd %~dp0 +if "%~1"=="" goto help + +WHERE choco >NUL 2>NUL +IF %ERRORLEVEL% NEQ 0 call tools\setup-choco.cmd + +WHERE docker >NUL 2>NUL +IF "%ERRORLEVEL%"=="0" goto docker_ok +choco install -y docker-desktop +choco install -y docker-cli +:docker_ok + +docker info +docker version + +set IMAGE_NAME=%1 +echo Running in container %IMAGE_NAME% +sc query com.docker.service + +cd .. + +REM Force reinstallation of build tools +del .buildtools 2>NUL +echo Building docker image... +docker build --rm -t %IMAGE_NAME% docker/%IMAGE_NAME% + +echo Starting build... +docker run -it -v %CD%:/build %IMAGE_NAME% "/build/tools/build.sh" clean + +popd +exit + +:help +cd .. +echo. +echo Usage: build-docker.cmd [container_name] +echo. +echo Supported containers: +dir /B docker +popd From b810c97d06bf7f3afae5c443f595838edaf6aad3 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 13 Nov 2020 19:18:00 -0800 Subject: [PATCH 07/54] Move bazel-specific build files into bazel-specific directory. Keep third_party/json reserved for CMake submodule build. Remove top-level cmake/TBD as it is not needed and not used. --- cmake/TBD | 0 third_party/{ => bazel}/json/BUILD | 0 third_party/{ => bazel}/json/nlohmann_json.BUILD | 0 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cmake/TBD rename third_party/{ => bazel}/json/BUILD (100%) rename third_party/{ => bazel}/json/nlohmann_json.BUILD (100%) diff --git a/cmake/TBD b/cmake/TBD deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/third_party/json/BUILD b/third_party/bazel/json/BUILD similarity index 100% rename from third_party/json/BUILD rename to third_party/bazel/json/BUILD diff --git a/third_party/json/nlohmann_json.BUILD b/third_party/bazel/json/nlohmann_json.BUILD similarity index 100% rename from third_party/json/nlohmann_json.BUILD rename to third_party/bazel/json/nlohmann_json.BUILD From 5e91eeb15d09819140ca597935be74e592124c4e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 22:00:03 -0800 Subject: [PATCH 08/54] Remove opentelemetry-proto - use submodule instead --- .gitmodules | 7 + third_party/opentelemetry-proto/README | 2 - .../opentelemetry/proto/collector/README.md | 9 - .../metrics/v1/metrics_service.proto | 45 -- .../metrics/v1/metrics_service_http.yaml | 9 - .../collector/trace/v1/trace_service.proto | 48 -- .../trace/v1/trace_service_http.yaml | 9 - .../proto/common/v1/common.proto | 77 ---- .../proto/metrics/v1/metrics.proto | 434 ------------------ .../proto/resource/v1/resource.proto | 34 -- .../opentelemetry/proto/trace/v1/trace.proto | 261 ----------- .../proto/trace/v1/trace_config.proto | 78 ---- 12 files changed, 7 insertions(+), 1006 deletions(-) delete mode 100644 third_party/opentelemetry-proto/README delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/collector/README.md delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service.proto delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service_http.yaml delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service.proto delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/common/v1/common.proto delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/resource/v1/resource.proto delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto delete mode 100644 third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace_config.proto diff --git a/.gitmodules b/.gitmodules index e1d94ec89a..05d4a19900 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,7 @@ [submodule "third_party/prometheus-cpp"] path = third_party/prometheus-cpp url = https://github.com/jupp0r/prometheus-cpp.git + branch = master [submodule "tools/vcpkg"] path = tools/vcpkg @@ -20,3 +21,9 @@ [submodule "third_party/benchmark"] path = third_party/benchmark url = https://github.com/google/benchmark + branch = master + +[submodule "third_party/opentelemetry-proto"] + path = third_party/opentelemetry-proto + url = https://github.com/open-telemetry/opentelemetry-proto + branch = master diff --git a/third_party/opentelemetry-proto/README b/third_party/opentelemetry-proto/README deleted file mode 100644 index e32d7de183..0000000000 --- a/third_party/opentelemetry-proto/README +++ /dev/null @@ -1,2 +0,0 @@ -From: https://github.com/open-telemetry/opentelemetry-proto -Commit: e43e1abc40428a6ee98e3bfd79bec1dfa2ed18cd diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/collector/README.md b/third_party/opentelemetry-proto/opentelemetry/proto/collector/README.md deleted file mode 100644 index 4a73a31ed8..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/collector/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# OpenTelemetry Collector Proto - -This package describes the OpenTelemetry collector protocol. - -## Packages - -1. `common` package contains the common messages shared between different services. -2. `trace` package contains the Trace Service protos. -3. `metrics` package contains the Metrics Service protos. diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service.proto b/third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service.proto deleted file mode 100644 index 5a3cbee4c9..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service.proto +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package opentelemetry.proto.collector.metrics.v1; - -import "opentelemetry/proto/metrics/v1/metrics.proto"; - -option java_multiple_files = true; -option java_package = "io.opentelemetry.proto.collector.metrics.v1"; -option java_outer_classname = "MetricsServiceProto"; -option go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go/collector/metrics/v1"; - -// Service that can be used to push metrics between one Application -// instrumented with OpenTelemetry and a collector, or between a collector and a -// central collector. -service MetricsService { - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - rpc Export(ExportMetricsServiceRequest) returns (ExportMetricsServiceResponse) {} -} - -message ExportMetricsServiceRequest { - // An array of ResourceMetrics. - // For data coming from a single resource this array will typically contain one - // element. Intermediary nodes (such as OpenTelemetry Collector) that receive - // data from multiple origins typically batch the data before forwarding further and - // in that case this array will contain multiple elements. - repeated opentelemetry.proto.metrics.v1.ResourceMetrics resource_metrics = 1; -} - -message ExportMetricsServiceResponse { -} diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service_http.yaml b/third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service_http.yaml deleted file mode 100644 index bc5f9ff241..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service_http.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# This is an API configuration to generate an HTTP/JSON -> gRPC gateway for the -# OpenTelemetry service using github.com/grpc-ecosystem/grpc-gateway. -type: google.api.Service -config_version: 3 -http: - rules: - - selector: opentelemetry.proto.collector.metrics.v1.MetricsService.Export - post: /v1/metrics - body: "*" diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service.proto b/third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service.proto deleted file mode 100644 index 16784c666a..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -// NOTE: This proto is experimental and is subject to change at this point. -// Please do not use it at the moment. - -package opentelemetry.proto.collector.trace.v1; - -import "opentelemetry/proto/trace/v1/trace.proto"; - -option java_multiple_files = true; -option java_package = "io.opentelemetry.proto.collector.trace.v1"; -option java_outer_classname = "TraceServiceProto"; -option go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go/collector/trace/v1"; - -// Service that can be used to push spans between one Application instrumented with -// OpenTelemetry and an collector, or between an collector and a central collector (in this -// case spans are sent/received to/from multiple Applications). -service TraceService { - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - rpc Export(ExportTraceServiceRequest) returns (ExportTraceServiceResponse) {} -} - -message ExportTraceServiceRequest { - // An array of ResourceSpans. - // For data coming from a single resource this array will typically contain one - // element. Intermediary nodes (such as OpenTelemetry Collector) that receive - // data from multiple origins typically batch the data before forwarding further and - // in that case this array will contain multiple elements. - repeated opentelemetry.proto.trace.v1.ResourceSpans resource_spans = 1; -} - -message ExportTraceServiceResponse { -} diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml b/third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml deleted file mode 100644 index 10eae48d51..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service_http.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# This is an API configuration to generate an HTTP/JSON -> gRPC gateway for the -# OpenTelemetry service using github.com/grpc-ecosystem/grpc-gateway. -type: google.api.Service -config_version: 3 -http: - rules: - - selector: opentelemetry.proto.collector.trace.v1.TraceService.Export - post: /v1/trace - body: "*" diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/common/v1/common.proto b/third_party/opentelemetry-proto/opentelemetry/proto/common/v1/common.proto deleted file mode 100644 index dc67e43fb6..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/common/v1/common.proto +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package opentelemetry.proto.common.v1; - -option java_multiple_files = true; -option java_package = "io.opentelemetry.proto.common.v1"; -option java_outer_classname = "CommonProto"; -option go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go/common/v1"; - -// AnyValue is used to represent any type of attribute value. AnyValue may contain a -// primitive value such as a string or integer or it may contain an arbitrary nested -// object containing arrays, key-value lists and primitives. -message AnyValue { - // The value is one of the listed fields. It is valid for all values to be unspecified - // in which case this AnyValue is considered to be "null". - oneof value { - string string_value = 1; - bool bool_value = 2; - int64 int_value = 3; - double double_value = 4; - ArrayValue array_value = 5; - KeyValueList kvlist_value = 6; - } -} - -// ArrayValue is a list of AnyValue messages. We need ArrayValue as a message -// since oneof in AnyValue does not allow repeated fields. -message ArrayValue { - // Array of values. The array may be empty (contain 0 elements). - repeated AnyValue values = 1; -} - -// KeyValueList is a list of KeyValue messages. We need KeyValueList as a message -// since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need -// a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to -// avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches -// are semantically equivalent. -message KeyValueList { - // A collection of key/value pairs of key-value pairs. The list may be empty (may - // contain 0 elements). - repeated KeyValue values = 1; -} - -// KeyValue is a key-value pair that is used to store Span attributes, Link -// attributes, etc. -message KeyValue { - string key = 1; - AnyValue value = 2; -} - -// StringKeyValue is a pair of key/value strings. This is the simpler (and faster) version -// of KeyValue that only supports string values. -message StringKeyValue { - string key = 1; - string value = 2; -} - -// InstrumentationLibrary is a message representing the instrumentation library information -// such as the fully qualified name and version. -message InstrumentationLibrary { - string name = 1; - string version = 2; -} diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto b/third_party/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto deleted file mode 100644 index 1d458824fe..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto +++ /dev/null @@ -1,434 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package opentelemetry.proto.metrics.v1; - -import "opentelemetry/proto/common/v1/common.proto"; -import "opentelemetry/proto/resource/v1/resource.proto"; - -option java_multiple_files = true; -option java_package = "io.opentelemetry.proto.metrics.v1"; -option java_outer_classname = "MetricsProto"; -option go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go/metrics/v1"; - -// A collection of InstrumentationLibraryMetrics from a Resource. -message ResourceMetrics { - // The resource for the metrics in this message. - // If this field is not set then no resource info is known. - opentelemetry.proto.resource.v1.Resource resource = 1; - - // A list of metrics that originate from a resource. - repeated InstrumentationLibraryMetrics instrumentation_library_metrics = 2; -} - -// A collection of Metrics produced by an InstrumentationLibrary. -message InstrumentationLibraryMetrics { - // The instrumentation library information for the metrics in this message. - // If this field is not set then no library info is known. - opentelemetry.proto.common.v1.InstrumentationLibrary instrumentation_library = 1; - - // A list of metrics that originate from an instrumentation library. - repeated Metric metrics = 2; -} - -// Defines a Metric which has one or more timeseries. -// -// The data model and relation between entities is shown in the diagram below. -// -// - Metric is composed of a MetricDescriptor and a list of data points. -// - MetricDescriptor contains a list of label keys (shown horizontally). -// - Data is a list of DataPoints (shown vertically). -// - DataPoint contains a list of label values and a value. -// -// Metric -// +----------+ +------------------------+ -// |descriptor|-------->| MetricDescriptor | -// | | |+-----+-----+ +-----+ | -// | | ||label|label|...|label| | -// | data|--+ ||key1 |key2 | |keyN | | -// +----------+ | |+-----+-----+ +-----+ | -// | +------------------------+ -// | -// | +---------------------------+ -// | |DataPoint 1 | -// v |+------+------+ +------+ | -// +-----+ ||label |label |...|label | | -// | 1 |-->||value1|value2|...|valueN| | -// +-----+ |+------+------+ +------+ | -// | . | |+-----+ | -// | . | ||value| | -// | . | |+-----+ | -// | . | +---------------------------+ -// | . | . -// | . | . -// | . | . -// | . | +---------------------------+ -// | . | |DataPoint M | -// +-----+ |+------+------+ +------+ | -// | M |-->||label |label |...|label | | -// +-----+ ||value1|value2|...|valueN| | -// |+------+------+ +------+ | -// |+-----+ | -// ||value| | -// |+-----+ | -// +---------------------------+ -// -//----------------------------------------------------------------------- -// DataPoint is a value of specific type corresponding to a given moment in -// time. Each DataPoint is timestamped. -// -// DataPoint is strongly typed: each DataPoint type has a specific Protobuf message -// depending on the value type of the metric and thus there are currently 4 DataPoint -// messages, which correspond to the types of metric values. -message Metric { - // metric_descriptor describes the Metric. - MetricDescriptor metric_descriptor = 1; - - // Data is a list of one or more DataPoints for a single metric. Only one of the - // following fields is used for the data, depending on the type of the metric defined - // by MetricDescriptor.type field. - repeated Int64DataPoint int64_data_points = 2; - repeated DoubleDataPoint double_data_points = 3; - repeated HistogramDataPoint histogram_data_points = 4; - repeated SummaryDataPoint summary_data_points = 5; -} - -// Defines a metric type and its schema. -message MetricDescriptor { - // name of the metric, including its DNS name prefix. It must be unique. - string name = 1; - - // description of the metric, which can be used in documentation. - string description = 2; - - // unit in which the metric value is reported. Follows the format - // described by http://unitsofmeasure.org/ucum.html. - string unit = 3; - - // Type is the type of values a metric has. - enum Type { - // INVALID_TYPE is the default Type, it MUST not be used. - INVALID_TYPE = 0; - - // INT64 values are signed 64-bit integers. - // - // A Metric of this Type MUST store its values as Int64DataPoint. - INT64 = 1; - - // MONOTONIC_INT64 values are monotonically increasing signed 64-bit - // integers. - // - // A Metric of this Type MUST store its values as Int64DataPoint. - MONOTONIC_INT64 = 2; - - // DOUBLE values are double-precision floating-point numbers. - // - // A Metric of this Type MUST store its values as DoubleDataPoint. - DOUBLE = 3; - - // MONOTONIC_DOUBLE values are monotonically increasing double-precision - // floating-point numbers. - // - // A Metric of this Type MUST store its values as DoubleDataPoint. - MONOTONIC_DOUBLE = 4; - - // Histogram measurement. - // Corresponding values are stored in HistogramDataPoint. - HISTOGRAM = 5; - - // Summary value. Some frameworks implemented Histograms as a summary of observations - // (usually things like request durations and response sizes). While it - // also provides a total count of observations and a sum of all observed - // values, it calculates configurable percentiles over a sliding time - // window. - // Corresponding values are stored in SummaryDataPoint. - SUMMARY = 6; - } - - // type is the type of values this metric has. - Type type = 4; - - // Temporality is the temporal quality values of a metric have. It - // describes how those values relate to the time interval over which they - // are reported. - enum Temporality { - // INVALID_TEMPORALITY is the default Temporality, it MUST not be - // used. - INVALID_TEMPORALITY = 0; - - // INSTANTANEOUS is a metric whose values are measured at a particular - // instant. The values are not aggregated over any time interval and are - // unique per timestamp. As such, these metrics are not expected to have - // an associated start time. - INSTANTANEOUS = 1; - - // DELTA is a metric whose values are the aggregation of measurements - // made over a time interval. Successive metrics contain aggregation of - // values from continuous and non-overlapping intervals. - // - // The values for a DELTA metric are based only on the time interval - // associated with one measurement cycle. There is no dependency on - // previous measurements like is the case for CUMULATIVE metrics. - // - // For example, consider a system measuring the number of requests that - // it receives and reports the sum of these requests every second as a - // DELTA metric: - // - // 1. The system starts receiving at time=t_0. - // 2. A request is received, the system measures 1 request. - // 3. A request is received, the system measures 1 request. - // 4. A request is received, the system measures 1 request. - // 5. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0 to - // t_0+1 with a value of 3. - // 6. A request is received, the system measures 1 request. - // 7. A request is received, the system measures 1 request. - // 8. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0+1 to - // t_0+2 with a value of 2. - DELTA = 2; - - // CUMULATIVE is a metric whose values are the aggregation of - // successively made measurements from a fixed start time until the last - // reported measurement. This means that current values of a CUMULATIVE - // metric depend on all previous measurements since the start time. - // Because of this, the sender is required to retain this state in some - // form. If this state is lost or invalidated, the CUMULATIVE metric - // values MUST be reset and a new fixed start time following the last - // reported measurement time sent MUST be used. - // - // For example, consider a system measuring the number of requests that - // it receives and reports the sum of these requests every second as a - // CUMULATIVE metric: - // - // 1. The system starts receiving at time=t_0. - // 2. A request is received, the system measures 1 request. - // 3. A request is received, the system measures 1 request. - // 4. A request is received, the system measures 1 request. - // 5. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0 to - // t_0+1 with a value of 3. - // 6. A request is received, the system measures 1 request. - // 7. A request is received, the system measures 1 request. - // 8. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0 to - // t_0+2 with a value of 5. - // 9. The system experiences a fault and loses state. - // 10. The system recovers and resumes receiving at time=t_1. - // 11. A request is received, the system measures 1 request. - // 12. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_1 to - // t_0+1 with a value of 1. - CUMULATIVE = 3; - } - - // temporality is the Temporality of values this metric has. - Temporality temporality = 5; -} - -// Int64DataPoint is a single data point in a timeseries that describes the time-varying -// values of a int64 metric. -message Int64DataPoint { - // The set of labels that uniquely identify this timeseries. - repeated opentelemetry.proto.common.v1.StringKeyValue labels = 1; - - // start_time_unix_nano is the time when the cumulative value was reset to zero. - // This is used for Counter type only. For Gauge the value is not specified and - // defaults to 0. - // - // The cumulative value is over the time interval (start_time_unix_nano, time_unix_nano]. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the timestamp - // may be decided by the backend. - fixed64 start_time_unix_nano = 2; - - // time_unix_nano is the moment when this value was recorded. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - fixed64 time_unix_nano = 3; - - // value itself. - int64 value = 4; -} - -// DoubleDataPoint is a single data point in a timeseries that describes the time-varying -// value of a double metric. -message DoubleDataPoint { - // The set of labels that uniquely identify this timeseries. - repeated opentelemetry.proto.common.v1.StringKeyValue labels = 1; - - // start_time_unix_nano is the time when the cumulative value was reset to zero. - // This is used for Counter type only. For Gauge the value is not specified and - // defaults to 0. - // - // The cumulative value is over the time interval (start_time_unix_nano, time_unix_nano]. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the timestamp - // may be decided by the backend. - fixed64 start_time_unix_nano = 2; - - // time_unix_nano is the moment when this value was recorded. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - fixed64 time_unix_nano = 3; - - // value itself. - double value = 4; -} - -// HistogramDataPoint is a single data point in a timeseries that describes the time-varying -// values of a Histogram. A Histogram contains summary statistics for a population of values, -// it may optionally contain the distribution of those values across a set of buckets. -message HistogramDataPoint { - // The set of labels that uniquely identify this timeseries. - repeated opentelemetry.proto.common.v1.StringKeyValue labels = 1; - - // start_time_unix_nano is the time when the cumulative value was reset to zero. - // - // The cumulative value is over the time interval (start_time_unix_nano, time_unix_nano]. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the timestamp - // may be decided by the backend. - // Note: this field is always unspecified and ignored if MetricDescriptor.type==GAUGE_HISTOGRAM. - fixed64 start_time_unix_nano = 2; - - // time_unix_nano is the moment when this value was recorded. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - fixed64 time_unix_nano = 3; - - // count is the number of values in the population. Must be non-negative. This value - // must be equal to the sum of the "count" fields in buckets if a histogram is provided. - uint64 count = 4; - - // sum of the values in the population. If count is zero then this field - // must be zero. This value must be equal to the sum of the "sum" fields in buckets if - // a histogram is provided. - double sum = 5; - - // Bucket contains values for a bucket. - message Bucket { - // The number of values in each bucket of the histogram, as described by - // bucket_options. - uint64 count = 1; - - // Exemplars are example points that may be used to annotate aggregated - // Histogram values. They are metadata that gives information about a - // particular value added to a Histogram bucket. - message Exemplar { - // Value of the exemplar point. It determines which bucket the exemplar belongs to. - // If bucket_options define bounds for this bucket then this value must be within - // the defined bounds. - double value = 1; - - // time_unix_nano is the moment when this exemplar was recorded. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - fixed64 time_unix_nano = 2; - - // exemplar_attachments are contextual information about the example value. - // Keys in this list must be unique. - repeated opentelemetry.proto.common.v1.StringKeyValue attachments = 3; - } - - // exemplar is an optional representative value of the bucket. - Exemplar exemplar = 2; - } - - // buckets is an optional field contains the values of histogram for each bucket. - // - // The sum of the values in the buckets "count" field must equal the value in the count field. - // - // The number of elements in buckets array must be by one greater than the - // number of elements in bucket_bounds array. - // - // Note: if HistogramDataPoint.bucket_options defines bucket bounds then this field - // must also be present and number of elements in this field must be equal to the - // number of buckets defined by bucket_options. - repeated Bucket buckets = 6; - - // A histogram may optionally contain the distribution of the values in the population. - // In that case one of the option fields below and "buckets" field both must be defined. - // Otherwise all option fields and "buckets" field must be omitted in which case the - // distribution of values in the histogram is unknown and only the total count and sum are known. - - // explicit_bounds is the only supported bucket option currently. - // TODO: Add more bucket options. - - // explicit_bounds specifies buckets with explicitly defined bounds for values. - // The bucket boundaries are described by "bounds" field. - // - // This defines size(bounds) + 1 (= N) buckets. The boundaries for bucket - // at index i are: - // - // [0, bounds[i]) for i == 0 - // [bounds[i-1], bounds[i]) for 0 < i < N-1 - // [bounds[i], +infinity) for i == N-1 - // The values in bounds array must be strictly increasing and > 0. - // - // Note: only [a, b) intervals are currently supported for each bucket. If we decides - // to also support (a, b] intervals we should add support for these by defining a boolean - // value which decides what type of intervals to use. - repeated double explicit_bounds = 7; -} - -// SummaryDataPoint is a single data point in a timeseries that describes the time-varying -// values of a Summary metric. -message SummaryDataPoint { - // The set of labels that uniquely identify this timeseries. - repeated opentelemetry.proto.common.v1.StringKeyValue labels = 1; - - // start_time_unix_nano is the time when the cumulative value was reset to zero. - // - // The cumulative value is over the time interval (start_time_unix_nano, time_unix_nano]. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the timestamp - // may be decided by the backend. - fixed64 start_time_unix_nano = 2; - - // time_unix_nano is the moment when this value was recorded. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - fixed64 time_unix_nano = 3; - - // The total number of recorded values since start_time. Optional since - // some systems don't expose this. - uint64 count = 4; - - // The total sum of recorded values since start_time. Optional since some - // systems don't expose this. If count is zero then this field must be zero. - double sum = 5; - - // Represents the value at a given percentile of a distribution. - // - // To record Min and Max values following conventions are used: - // - The 100th percentile is equivalent to the maximum value observed. - // - The 0th percentile is equivalent to the minimum value observed. - // - // See the following issue for more context: - // https://github.com/open-telemetry/opentelemetry-proto/issues/125 - message ValueAtPercentile { - // The percentile of a distribution. Must be in the interval - // [0.0, 100.0]. - double percentile = 1; - - // The value at the given percentile of a distribution. - double value = 2; - } - - // A list of values at different percentiles of the distribution calculated - // from the current snapshot. The percentiles must be strictly increasing. - repeated ValueAtPercentile percentile_values = 6; -} diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/resource/v1/resource.proto b/third_party/opentelemetry-proto/opentelemetry/proto/resource/v1/resource.proto deleted file mode 100644 index fa5d97c6f8..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/resource/v1/resource.proto +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package opentelemetry.proto.resource.v1; - -import "opentelemetry/proto/common/v1/common.proto"; - -option java_multiple_files = true; -option java_package = "io.opentelemetry.proto.resource.v1"; -option java_outer_classname = "ResourceProto"; -option go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go/resource/v1"; - -// Resource information. -message Resource { - // Set of labels that describe the resource. - repeated opentelemetry.proto.common.v1.KeyValue attributes = 1; - - // dropped_attributes_count is the number of dropped attributes. If the value is 0, then - // no attributes were dropped. - uint32 dropped_attributes_count = 2; -} diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto b/third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto deleted file mode 100644 index 5a2350fdee..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package opentelemetry.proto.trace.v1; - -import "opentelemetry/proto/common/v1/common.proto"; -import "opentelemetry/proto/resource/v1/resource.proto"; - -option java_multiple_files = true; -option java_package = "io.opentelemetry.proto.trace.v1"; -option java_outer_classname = "TraceProto"; -option go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go/trace/v1"; - -// A collection of InstrumentationLibrarySpans from a Resource. -message ResourceSpans { - // The resource for the spans in this message. - // If this field is not set then no resource info is known. - opentelemetry.proto.resource.v1.Resource resource = 1; - - // A list of InstrumentationLibrarySpans that originate from a resource. - repeated InstrumentationLibrarySpans instrumentation_library_spans = 2; -} - -// A collection of Spans produced by an InstrumentationLibrary. -message InstrumentationLibrarySpans { - // The instrumentation library information for the spans in this message. - // If this field is not set then no library info is known. - opentelemetry.proto.common.v1.InstrumentationLibrary instrumentation_library = 1; - - // A list of Spans that originate from an instrumentation library. - repeated Span spans = 2; -} - -// Span represents a single operation within a trace. Spans can be -// nested to form a trace tree. Spans may also be linked to other spans -// from the same or different trace and form graphs. Often, a trace -// contains a root span that describes the end-to-end latency, and one -// or more subspans for its sub-operations. A trace can also contain -// multiple root spans, or none at all. Spans do not need to be -// contiguous - there may be gaps or overlaps between spans in a trace. -// -// The next available field id is 17. -message Span { - // A unique identifier for a trace. All spans from the same trace share - // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes - // is considered invalid. - // - // This field is semantically required. Receiver should generate new - // random trace_id if empty or invalid trace_id was received. - // - // This field is required. - bytes trace_id = 1; - - // A unique identifier for a span within a trace, assigned when the span - // is created. The ID is an 8-byte array. An ID with all zeroes is considered - // invalid. - // - // This field is semantically required. Receiver should generate new - // random span_id if empty or invalid span_id was received. - // - // This field is required. - bytes span_id = 2; - - // trace_state conveys information about request position in multiple distributed tracing graphs. - // It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header - // See also https://github.com/w3c/distributed-tracing for more details about this field. - string trace_state = 3; - - // The `span_id` of this span's parent span. If this is a root span, then this - // field must be empty. The ID is an 8-byte array. - bytes parent_span_id = 4; - - // A description of the span's operation. - // - // For example, the name can be a qualified method name or a file name - // and a line number where the operation is called. A best practice is to use - // the same display name at the same call point in an application. - // This makes it easier to correlate spans in different traces. - // - // This field is semantically required to be set to non-empty string. - // When null or empty string received - receiver may use string "name" - // as a replacement. There might be smarted algorithms implemented by - // receiver to fix the empty span name. - // - // This field is required. - string name = 5; - - // SpanKind is the type of span. Can be used to specify additional relationships between spans - // in addition to a parent/child relationship. - enum SpanKind { - // Unspecified. Do NOT use as default. - // Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. - SPAN_KIND_UNSPECIFIED = 0; - - // Indicates that the span represents an internal operation within an application, - // as opposed to an operations happening at the boundaries. Default value. - INTERNAL = 1; - - // Indicates that the span covers server-side handling of an RPC or other - // remote network request. - SERVER = 2; - - // Indicates that the span describes a request to some remote service. - CLIENT = 3; - - // Indicates that the span describes a producer sending a message to a broker. - // Unlike CLIENT and SERVER, there is often no direct critical path latency relationship - // between producer and consumer spans. A PRODUCER span ends when the message was accepted - // by the broker while the logical processing of the message might span a much longer time. - PRODUCER = 4; - - // Indicates that the span describes consumer receiving a message from a broker. - // Like the PRODUCER kind, there is often no direct critical path latency relationship - // between producer and consumer spans. - CONSUMER = 5; - } - - // Distinguishes between spans generated in a particular context. For example, - // two spans with the same name may be distinguished using `CLIENT` (caller) - // and `SERVER` (callee) to identify queueing latency associated with the span. - SpanKind kind = 6; - - // start_time_unix_nano is the start time of the span. On the client side, this is the time - // kept by the local machine where the span execution starts. On the server side, this - // is the time when the server's application handler starts running. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - // - // This field is semantically required and it is expected that end_time >= start_time. - fixed64 start_time_unix_nano = 7; - - // end_time_unix_nano is the end time of the span. On the client side, this is the time - // kept by the local machine where the span execution ends. On the server side, this - // is the time when the server application handler stops running. - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - // - // This field is semantically required and it is expected that end_time >= start_time. - fixed64 end_time_unix_nano = 8; - - // attributes is a collection of key/value pairs. The value can be a string, - // an integer, a double or the Boolean values `true` or `false`. Note, global attributes - // like server name can be set using the resource API. Examples of attributes: - // - // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" - // "/http/server_latency": 300 - // "abc.com/myattribute": true - // "abc.com/score": 10.239 - repeated opentelemetry.proto.common.v1.KeyValue attributes = 9; - - // dropped_attributes_count is the number of attributes that were discarded. Attributes - // can be discarded because their keys are too long or because there are too many - // attributes. If this value is 0, then no attributes were dropped. - uint32 dropped_attributes_count = 10; - - // Event is a time-stamped annotation of the span, consisting of user-supplied - // text description and key-value pairs. - message Event { - // time_unix_nano is the time the event occurred. - fixed64 time_unix_nano = 1; - - // name of the event. - // This field is semantically required to be set to non-empty string. - string name = 2; - - // attributes is a collection of attribute key/value pairs on the event. - repeated opentelemetry.proto.common.v1.KeyValue attributes = 3; - - // dropped_attributes_count is the number of dropped attributes. If the value is 0, - // then no attributes were dropped. - uint32 dropped_attributes_count = 4; - } - - // events is a collection of Event items. - repeated Event events = 11; - - // dropped_events_count is the number of dropped events. If the value is 0, then no - // events were dropped. - uint32 dropped_events_count = 12; - - // A pointer from the current span to another span in the same trace or in a - // different trace. For example, this can be used in batching operations, - // where a single batch handler processes multiple requests from different - // traces or when the handler receives a request from a different project. - message Link { - // A unique identifier of a trace that this linked span is part of. The ID is a - // 16-byte array. - bytes trace_id = 1; - - // A unique identifier for the linked span. The ID is an 8-byte array. - bytes span_id = 2; - - // The trace_state associated with the link. - string trace_state = 3; - - // attributes is a collection of attribute key/value pairs on the link. - repeated opentelemetry.proto.common.v1.KeyValue attributes = 4; - - // dropped_attributes_count is the number of dropped attributes. If the value is 0, - // then no attributes were dropped. - uint32 dropped_attributes_count = 5; - } - - // links is a collection of Links, which are references from this span to a span - // in the same or different trace. - repeated Link links = 13; - - // dropped_links_count is the number of dropped links after the maximum size was - // enforced. If this value is 0, then no links were dropped. - uint32 dropped_links_count = 14; - - // An optional final status for this span. Semantically when Status - // wasn't set it is means span ended without errors and assume - // Status.Ok (code = 0). - Status status = 15; -} - -// The Status type defines a logical error model that is suitable for different -// programming environments, including REST APIs and RPC APIs. -message Status { - - // StatusCode mirrors the codes defined at - // https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-tracing.md#statuscanonicalcode - enum StatusCode { - Ok = 0; - Cancelled = 1; - UnknownError = 2; - InvalidArgument = 3; - DeadlineExceeded = 4; - NotFound = 5; - AlreadyExists = 6; - PermissionDenied = 7; - ResourceExhausted = 8; - FailedPrecondition = 9; - Aborted = 10; - OutOfRange = 11; - Unimplemented = 12; - InternalError = 13; - Unavailable = 14; - DataLoss = 15; - Unauthenticated = 16; - }; - - // The status code. This is optional field. It is safe to assume 0 (OK) - // when not set. - StatusCode code = 1; - - // A developer-facing human readable error message. - string message = 2; -} diff --git a/third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace_config.proto b/third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace_config.proto deleted file mode 100644 index 7269da1ee8..0000000000 --- a/third_party/opentelemetry-proto/opentelemetry/proto/trace/v1/trace_config.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package opentelemetry.proto.trace.v1; - -option java_multiple_files = true; -option java_package = "io.opentelemetry.proto.trace.v1"; -option java_outer_classname = "TraceConfigProto"; -option go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go/collector/trace/v1"; - -// Global configuration of the trace service. All fields must be specified, or -// the default (zero) values will be used for each type. -message TraceConfig { - - // The global default sampler used to make decisions on span sampling. - oneof sampler { - ConstantSampler constant_sampler = 1; - - ProbabilitySampler probability_sampler = 2; - - RateLimitingSampler rate_limiting_sampler = 3; - } - - // The global default max number of attributes per span. - int64 max_number_of_attributes = 4; - - // The global default max number of annotation events per span. - int64 max_number_of_timed_events= 5; - - // The global default max number of attributes per timed event. - int64 max_number_of_attributes_per_timed_event = 6; - - // The global default max number of link entries per span. - int64 max_number_of_links = 7; - - // The global default max number of attributes per span. - int64 max_number_of_attributes_per_link = 8; -} - -// Sampler that always makes a constant decision on span sampling. -message ConstantSampler { - // How spans should be sampled: - // - Always off - // - Always on - // - Always follow the parent Span's decision (off if no parent). - enum ConstantDecision { - ALWAYS_OFF = 0; - ALWAYS_ON = 1; - ALWAYS_PARENT = 2; - } - ConstantDecision decision = 1; -} - -// Sampler that tries to uniformly sample traces with a given probability. -// The probability of sampling a trace is equal to that of the specified probability. -message ProbabilitySampler { - // The desired probability of sampling. Must be within [0.0, 1.0]. - double samplingProbability = 1; -} - -// Sampler that tries to sample with a rate per time window. -message RateLimitingSampler { - // Rate per second. - int64 qps = 1; -} From 4efeee739749029337284e28ae3abd9b9e5f7ac4 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:07:42 -0800 Subject: [PATCH 09/54] Modules --- .gitmodules | 3 ++- third_party/prometheus-cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 160000 third_party/prometheus-cpp diff --git a/.gitmodules b/.gitmodules index 05d4a19900..644ae871be 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "third_party/prometheus-cpp"] path = third_party/prometheus-cpp - url = https://github.com/jupp0r/prometheus-cpp.git + url = https://github.com/jupp0r/prometheus-cpp branch = master [submodule "tools/vcpkg"] @@ -27,3 +27,4 @@ path = third_party/opentelemetry-proto url = https://github.com/open-telemetry/opentelemetry-proto branch = master + diff --git a/third_party/prometheus-cpp b/third_party/prometheus-cpp new file mode 160000 index 0000000000..27c3d670c6 --- /dev/null +++ b/third_party/prometheus-cpp @@ -0,0 +1 @@ +Subproject commit 27c3d670c66985c0096d378cdd780088b08bc8f4 From f05e9e9e5abbc1867c59a57f0b49a0deb2f1861c Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:18:15 -0800 Subject: [PATCH 10/54] Move JSON bazel file to /bazel build files directory --- WORKSPACE | 2 +- {third_party/bazel/json => bazel}/nlohmann_json.BUILD | 0 third_party/bazel/json/BUILD | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) rename {third_party/bazel/json => bazel}/nlohmann_json.BUILD (100%) delete mode 100644 third_party/bazel/json/BUILD diff --git a/WORKSPACE b/WORKSPACE index ef2c9611be..de4ec2a48b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -82,7 +82,7 @@ http_archive( http_archive( name = "github_nlohmann_json", - build_file = "//third_party/json:nlohmann_json.BUILD", + build_file = "//bazel:nlohmann_json.BUILD", sha256 = "69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf", urls = [ "https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip", diff --git a/third_party/bazel/json/nlohmann_json.BUILD b/bazel/nlohmann_json.BUILD similarity index 100% rename from third_party/bazel/json/nlohmann_json.BUILD rename to bazel/nlohmann_json.BUILD diff --git a/third_party/bazel/json/BUILD b/third_party/bazel/json/BUILD deleted file mode 100644 index 8ef196cd85..0000000000 --- a/third_party/bazel/json/BUILD +++ /dev/null @@ -1 +0,0 @@ -exports_files(["LICENSE"]) From 64bd7158e7399b02f16835e482e07c2293f1c773 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:19:45 -0800 Subject: [PATCH 11/54] Allow building with Docker --- docker/ubuntu14.04/Dockerfile | 13 ++++++++ docker/ubuntu16.04/Dockerfile | 10 ++++++ docker/ubuntu18.04/Dockerfile | 10 ++++++ docker/ubuntu20.04/Dockerfile | 10 ++++++ tools/build-docker.cmd | 50 +++++++++++++++++++++++------- tools/setup-cmake.sh | 58 +++++++++++++++++++++++++++++++++++ tools/setup-protobuf.sh | 6 ++++ 7 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 tools/setup-cmake.sh create mode 100644 tools/setup-protobuf.sh diff --git a/docker/ubuntu14.04/Dockerfile b/docker/ubuntu14.04/Dockerfile index b2add385c2..b177c34ce2 100644 --- a/docker/ubuntu14.04/Dockerfile +++ b/docker/ubuntu14.04/Dockerfile @@ -8,6 +8,7 @@ RUN apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade RUN apt-get install -qq -y --ignore-missing \ apt-utils \ automake \ + bc \ build-essential \ bzip2 \ cmake \ @@ -25,5 +26,17 @@ RUN apt-get install -qq -y --ignore-missing \ wget \ zlib1g-dev +RUN mkdir -p /usr/local/bin + +## Install cmake since it's an expensive operation and best be done once +COPY ./setup-cmake.sh /usr/local/bin/setup-cmake.sh +RUN chmod +x /usr/local/bin/setup-cmake.sh +RUN /usr/local/bin/setup-cmake.sh + +## Install protobuf3 since Ubuntu 14.04 does not have protobuf3 +COPY ./setup-protobuf.sh /usr/local/bin/setup-protobuf.sh +RUN chmod +x /usr/local/bin/setup-protobuf.sh +RUN /usr/local/bin/setup-protobuf.sh + # ENTRYPOINT bash CMD /bin/bash diff --git a/docker/ubuntu16.04/Dockerfile b/docker/ubuntu16.04/Dockerfile index abe3506fa9..e705618484 100644 --- a/docker/ubuntu16.04/Dockerfile +++ b/docker/ubuntu16.04/Dockerfile @@ -9,6 +9,7 @@ RUN apt-get install -qq -y --ignore-missing \ apt-utils \ automake \ build-essential \ + bc \ bzip2 \ cmake \ curl \ @@ -19,6 +20,9 @@ RUN apt-get install -qq -y --ignore-missing \ libtool-bin \ make \ pkg-config \ + protobuf \ + protobuf-compiler \ + libprotobuf-dev \ python \ sudo \ tar \ @@ -27,5 +31,11 @@ RUN apt-get install -qq -y --ignore-missing \ wget \ zlib1g-dev +## Install cmake since it's an expensive operation and best be done once +RUN mkdir -p /usr/local/bin +COPY ./setup-cmake.sh /usr/local/bin/setup-cmake.sh +RUN chmod +x /usr/local/bin/setup-cmake.sh +RUN /usr/local/bin/setup-cmake.sh + # ENTRYPOINT bash CMD /bin/bash diff --git a/docker/ubuntu18.04/Dockerfile b/docker/ubuntu18.04/Dockerfile index 0b618de972..45f6cbf8e6 100644 --- a/docker/ubuntu18.04/Dockerfile +++ b/docker/ubuntu18.04/Dockerfile @@ -8,6 +8,7 @@ RUN apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade RUN apt-get install -qq -y --ignore-missing \ apt-utils \ automake \ + bc \ build-essential \ bzip2 \ cmake \ @@ -18,6 +19,9 @@ RUN apt-get install -qq -y --ignore-missing \ libtool-bin \ make \ pkg-config \ + protobuf \ + protobuf-compiler \ + libprotobuf-dev \ python \ sudo \ tar \ @@ -26,5 +30,11 @@ RUN apt-get install -qq -y --ignore-missing \ wget \ zlib1g-dev +## Install cmake since it's an expensive operation and best be done once +RUN mkdir -p /usr/local/bin +COPY ./setup-cmake.sh /usr/local/bin/setup-cmake.sh +RUN chmod +x /usr/local/bin/setup-cmake.sh +RUN /usr/local/bin/setup-cmake.sh + # ENTRYPOINT bash CMD /bin/bash diff --git a/docker/ubuntu20.04/Dockerfile b/docker/ubuntu20.04/Dockerfile index 5f0f40a2a7..74dab23a66 100644 --- a/docker/ubuntu20.04/Dockerfile +++ b/docker/ubuntu20.04/Dockerfile @@ -8,6 +8,7 @@ RUN apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade RUN apt-get install -qq -y --ignore-missing \ apt-utils \ automake \ + bc \ build-essential \ bzip2 \ cmake \ @@ -18,6 +19,9 @@ RUN apt-get install -qq -y --ignore-missing \ libtool-bin \ make \ pkg-config \ + protobuf \ + protobuf-compiler \ + libprotobuf-dev \ python \ sudo \ tar \ @@ -26,5 +30,11 @@ RUN apt-get install -qq -y --ignore-missing \ wget \ zlib1g-dev +## Install cmake since it's an expensive operation and best be done once +RUN mkdir -p /usr/local/bin +COPY ./setup-cmake.sh /usr/local/bin/setup-cmake.sh +RUN chmod +x /usr/local/bin/setup-cmake.sh +RUN /usr/local/bin/setup-cmake.sh + # ENTRYPOINT bash CMD /bin/bash diff --git a/tools/build-docker.cmd b/tools/build-docker.cmd index 39c4e49d56..eebdcf98c7 100644 --- a/tools/build-docker.cmd +++ b/tools/build-docker.cmd @@ -1,12 +1,35 @@ @echo off pushd %~dp0 +REM Default arguments +set A1="/build/tools/build.sh" +set A2=clean if "%~1"=="" goto help +REM Image name is always the first argument +set IMAGE_NAME=%1 + +REM Process other optional arguments +shift +if NOT "%1"=="" ( + set A1=%1 + set A2=%2 + set A3=%3 + set A4=%4 + set A5=%5 + set A6=%6 + set A7=%7 + set A8=%8 + set A9=%9 + set A10=%10 +) + WHERE choco >NUL 2>NUL -IF %ERRORLEVEL% NEQ 0 call tools\setup-choco.cmd +if %ERRORLEVEL% NEQ 0 ( + echo This script requires Chocolatey to install Docker: https://chocolatey.org/ +) WHERE docker >NUL 2>NUL -IF "%ERRORLEVEL%"=="0" goto docker_ok +if "%ERRORLEVEL%"=="0" goto docker_ok choco install -y docker-desktop choco install -y docker-cli :docker_ok @@ -14,19 +37,19 @@ choco install -y docker-cli docker info docker version -set IMAGE_NAME=%1 echo Running in container %IMAGE_NAME% sc query com.docker.service -cd .. - REM Force reinstallation of build tools -del .buildtools 2>NUL -echo Building docker image... -docker build --rm -t %IMAGE_NAME% docker/%IMAGE_NAME% +del ..\.buildtools 2>NUL +echo Building docker image in %CD%... +copy /Y setup-cmake.sh ..\docker\%IMAGE_NAME%\ +copy /Y setup-protobuf.sh ..\docker\%IMAGE_NAME%\ +docker build --rm -t %IMAGE_NAME% ../docker/%IMAGE_NAME% +cd .. echo Starting build... -docker run -it -v %CD%:/build %IMAGE_NAME% "/build/tools/build.sh" clean +docker run -it -v %CD%:/build %IMAGE_NAME% %A1% %A2% popd exit @@ -34,8 +57,13 @@ exit :help cd .. echo. -echo Usage: build-docker.cmd [container_name] +echo Usage: build-docker.cmd [image_name] [arguments...] +echo. +echo Default command: +echo. +echo docker run -it -v $WORKSPACE_ROOT:/build IMAGE_NAME %A1% %A2% echo. -echo Supported containers: +echo Supported images: +echo ================= dir /B docker popd diff --git a/tools/setup-cmake.sh b/tools/setup-cmake.sh new file mode 100644 index 0000000000..522b44bc65 --- /dev/null +++ b/tools/setup-cmake.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# This script installs latest CMake on Linux machine +# +export PATH=/usr/local/bin:$PATH +# Min required CMake version +export CMAKE_MIN_VERSION=${1:-3.1.0} +# Target version to install if min required is not found +export CMAKE_VERSION=${2:-3.18.4} + +UPGRADE_NEEDED=no + +function splitVersion { + pattern='([^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]' + v1=$(cut -d '.' -f 1 <<< $ver ) + v2=$(cut -d '.' -f 2 <<< $ver ) + v3=$(cut -d '.' -f 3 <<< $ver ) +} + +function checkVersion { + # Current CMake version + currVer=`cmake --version | grep version | cut -d' ' -f 3` + ver=$currVer splitVersion + cv1=$v1 + cv2=$v2 + cv3=$v3 + cv=`echo "65536*$v1+256*$v2+$v3" | bc` + + # New CMake version + ver=$CMAKE_MIN_VERSION splitVersion + nv=`echo "65536*$v1+256*$v2+$v3" | bc` + if [ "$cv" -ge "$nv" ]; then + echo "CMake is already installed: $currVer" + else + UPGRADE_NEEDED=yes + fi +} + +checkVersion + +if [[ "$UPGRADE_NEEDED" == "no" ]]; then + echo "Skipping CMake installation" + exit 0 +fi + +# Download cmake to /tmp +pushd /tmp +if [[ ! -f "/tmp/cmake.tar.gz" ]]; then + wget -O /tmp/cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz + tar -zxvf /tmp/cmake.tar.gz +fi +# Bootstrap CMake +cd cmake-${CMAKE_VERSION} +./bootstrap --prefix=/usr/local +# Build CMake without CMake and without Ninja (slow) +make +make install +popd diff --git a/tools/setup-protobuf.sh b/tools/setup-protobuf.sh new file mode 100644 index 0000000000..f6f0fb4535 --- /dev/null +++ b/tools/setup-protobuf.sh @@ -0,0 +1,6 @@ +#!/bin/bash +pushd /tmp +curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip +unzip -o protoc-3.14.0-linux-x86_64.zip -d /usr/local/ +update-alternatives --install /usr/bin/protoc protoc /usr/local/bin/protoc 1 --force +popd From 0113aed83dcd5432a79be05e6a5e787aa76ae8c4 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:20:33 -0800 Subject: [PATCH 12/54] Clean-up Unix build tools --- tools/build-benchmark.sh | 26 ++++ tools/build-gtest.sh | 47 ++++--- tools/build-vcpkg.sh | 23 ++++ tools/build.sh | 233 +++++++++++++++++++++++++--------- tools/setup-buildtools-mac.sh | 1 - tools/setup-buildtools.sh | 26 ++-- 6 files changed, 257 insertions(+), 99 deletions(-) create mode 100644 tools/build-benchmark.sh create mode 100644 tools/build-vcpkg.sh diff --git a/tools/build-benchmark.sh b/tools/build-benchmark.sh new file mode 100644 index 0000000000..58d92dc860 --- /dev/null +++ b/tools/build-benchmark.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +pushd $WORKSPACE_ROOT + +BUILD_ROOT=${BUILD_ROOT:-/tmp/build} +[[ ! -d "${BUILD_ROOT}" ]] && mkdir -p "${BUILD_ROOT}" || echo "Output directory already exists: BUILD_ROOT=${BUILD_ROOT}" + +BENCHMARK_BUILD_ROOT=${BUILD_ROOT}/benchmark +[[ ! -d "${BENCHMARK_BUILD_ROOT}" ]] && mkdir -p "${BENCHMARK_BUILD_ROOT}" || echo "Output directory already exists: BENCHMARK_BUILD_ROOT=${BENCHMARK_BUILD_ROOT}" + +# Build Google Benchmark with given Google Test +export BENCHMARK_SRC_PATH=${WORKSPACE_ROOT}/third_party/benchmark +if [ ! -d "${BENCHMARK_SRC_PATH}" ]; then + echo "Google Benchmark not found!" + exit 1 +fi + +pushd ${BENCHMARK_BUILD_ROOT} +cmake $BENCHMARK_SRC_PATH -DBENCHMARK_ENABLE_TESTING=OFF -DCMAKE_INSTALL_PREFIX=$BUILD_ROOT +make install +popd + +popd diff --git a/tools/build-gtest.sh b/tools/build-gtest.sh index d2573b885a..e7e786ac48 100755 --- a/tools/build-gtest.sh +++ b/tools/build-gtest.sh @@ -1,28 +1,37 @@ #!/usr/bin/env bash -if [ "$1" == "ios" ]; then - IOS_BUILD="YES" - # Skip building tests on iOS as there is no way to run them - BUILD_TESTS="OFF" -else - IOS_BUILD="NO" - BUILD_TESTS="ON" + +# Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +pushd $WORKSPACE_ROOT + +BUILD_ROOT=${BUILD_ROOT:-/tmp/build} +[[ ! -d "${BUILD_ROOT}" ]] && mkdir -p "${BUILD_ROOT}" || echo "Output directory already exists: BUILD_ROOT=${BUILD_ROOT}" + +GTEST_BUILD_ROOT=${BUILD_ROOT}/gtest +[[ ! -d "${GTEST_BUILD_ROOT}" ]] && mkdir -p "${GTEST_BUILD_ROOT}" || echo "Output directory already exists: GTEST_BUILD_ROOT=${GTEST_BUILD_ROOT}" + +# Path to Google Test source. Prefer Google Test from submodule if available: +export GTEST_SRC_PATH=${WORKSPACE_ROOT}/third_party/googletest +if [ ! -d "${GTEST_SRC_PATH}" ]; then + # If not available, then use Google Test that is installed by OS package: + export GTEST_SRC_PATH=/usr/src/gtest + if [ ! -d "${GTEST_SRC_PATH}" ]; then + echo "GTest not found!" + exit 1 + fi + echo Building GTest from source: ${GTEST_SRC_PATH} ... fi -pushd `dirname $0`/.. -cd third_party/googletest -set -evx -env | sort -rm -rf build -mkdir -p build || true -cd build +pushd $GTEST_BUILD_ROOT cmake -Dgtest_build_samples=OFF \ -Dgmock_build_samples=OFF \ -Dgtest_build_tests=OFF \ -Dgmock_build_tests=OFF \ - -DCMAKE_CXX_FLAGS="-fPIC $CXX_FLAGS" \ - -DBUILD_IOS=$IOS_BUILD \ - -DCMAKE_CXX_STANDARD=17 \ - .. -make + -DCMAKE_CXX_FLAGS="-fPIC $CXX_FLAGS -Wno-return-type" \ + -DCMAKE_INSTALL_PREFIX=$BUILD_ROOT \ + "${GTEST_SRC_PATH}" make install popd + +popd diff --git a/tools/build-vcpkg.sh b/tools/build-vcpkg.sh new file mode 100644 index 0000000000..eec27c8d4f --- /dev/null +++ b/tools/build-vcpkg.sh @@ -0,0 +1,23 @@ +#!/bin/bash +export PATH=/usr/local/bin:$PATH +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. + +export VCPKG_ROOT=$WORKSPACE_ROOT/tools/vcpkg +export PATH=$VCPKG_ROOT:$PATH + +if [[ ! -f $DIR/vcpkg/vcpkg ]] ; then + pushd $DIR/vcpkg + ./bootstrap-vcpkg.sh + popd +fi + +vcpkg install gtest +vcpkg install benchmark +vcpkg install ms-gsl +vcpkg install nlohmann-json +vcpkg install abseil + +cd $WORKSPACE_ROOT +export USE_VCPKG=1 +./tools/build.sh ${1:-nostd} ${2:--DCMAKE_TOOLCHAIN_FILE=$WORKSPACE_ROOT/tools/vcpkg/scripts/buildsystems/vcpkg.cmake} diff --git a/tools/build.sh b/tools/build.sh index 3a25c5bc3f..0a4ca6c7eb 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -1,74 +1,183 @@ #!/bin/bash - export PATH=/usr/local/bin:$PATH -DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -WORKSPACE_ROOT=$DIR/.. -cd $WORKSPACE_ROOT -echo "Current directory is `pwd`" +## +## Install all build tools and dependencies on Mac +## +function install_mac_tools { + if [ ! -f $BUILDTOOLS_FILE ] ; then + $WORKSPACE_ROOT/tools/setup-buildtools-mac.sh + echo > $BUILDTOOLS_FILE + else + echo "Build tools already installed. Skipping build tools installation." + fi +} -export NOROOT=$NOROOT +## +## Install all build tools and dependencies on Linux +## +function install_linux_tools { + if [ ! -f $BUILDTOOLS_FILE ] ; then + sudo $WORKSPACE_ROOT/tools/setup-buildtools.sh + echo > $BUILDTOOLS_FILE + else + echo "Build tools already installed. Skipping build tools installation." + fi +} -if [ "$1" == "clean" ]; then - rm -f CMakeCache.txt *.cmake - rm -rf out - rm -rf .buildtools -# make clean -fi - -if [ "$1" == "noroot" ] || [ "$2" == "noroot" ]; then -export NOROOT=true -fi - -if [ "$1" == "release" ] || [ "$2" == "release" ]; then -BUILD_TYPE="release" -else -BUILD_TYPE="debug" -fi - -# Set target MacOS minver -export MACOSX_DEPLOYMENT_TARGET=10.10 - -# Install build tools -FILE=.buildtools -OS_NAME=`uname -a` -if [ ! -f $FILE ]; then -case "$OS_NAME" in - *Darwin*) tools/setup-buildtools-mac.sh ;; - *Linux*) [[ -z "$NOROOT" ]] && sudo tools/setup-buildtools.sh || echo "No root: skipping build tools installation." ;; - *) echo "WARNING: unsupported OS $OS_NAME , skipping build tools installation.." -esac -# Assume that the build tools have been successfully installed -echo > $FILE -fi - -# TODO: fix compiler-version reporting -if [ -f /usr/bin/gcc ]; then -echo "gcc version: `gcc --version`" -COMPILER_NAME=gcc-`gcc -dumpversion` -fi - -if [ -f /usr/bin/clang ]; then -echo "clang version: `clang --version`" -COMPILER_NAME=clang-`clang -dumpversion` -fi - -# TODO: build and install Google Test from source if necessary - -function build_configuration { - BUILD_CONFIG=$1 - BUILD_OPTIONS=$2 +## +## Build dependencies +## +function build_dependencies { + # Build Google Benchmark + $WORKSPACE_ROOT/tools/build-benchmark.sh + # Build Google Test + $WORKSPACE_ROOT/tools/build-gtest.sh +} +## +## Build specific configuration for a given platform +## +function build { echo "Build configuration: $BUILD_CONFIG" cd $WORKSPACE_ROOT - OUTDIR=out/$COMPILER_NAME/$BUILD_CONFIG - mkdir -p $OUTDIR - pushd $OUTDIR - cmake $BUILD_OPTIONS $WORKSPACE_ROOT - make + + export BUILD_ROOT=`pwd`/out/$PLATFORM_NAME/$BUILD_CONFIG + mkdir -p $BUILD_ROOT + + if [ -z ${USE_VCPKG} ] ; then + # TODO: consider that dependencies may also be coming from OS or brew + build_dependencies + else + echo VCPKG_ROOT=${VCPKG_ROOT} + # Prefer ninja from VCPKG if available + NINJA=$WORKSPACE_ROOT/`find tools/vcpkg -name ninja -print -quit` + if [ -z ${NINJA} ] ; then + NINJA=`which ninja` + fi + fi + + # Build OpenTelemetry SDK + pushd $BUILD_ROOT + if [ -z ${NINJA} ] ; then + cmake $BUILD_OPTIONS $WORKSPACE_ROOT + make + else + cmake -G "Ninja" $BUILD_OPTIONS $WORKSPACE_ROOT + echo Building with NINJA=$NINJA + $NINJA + fi popd } -# Example -build_configuration nostd '-DWITH_MY_OPTION:BOOL=OFF' +function runtests { + pushd $BUILD_ROOT + ctest + popd +} + +## +## Clean +## +function clean { + rm -f CMakeCache.txt *.cmake + rm -rf out + rm -rf .buildtools +# make clean +} + +## +## Detect compiler +## +function detect_compiler { + if [ -z "${CC}" ] ; then + # Compiler autodetection + if [ -z "${APPLE}" ] ; then + # Prefer gcc for non-Apple + if [ -f /usr/bin/gcc ] ; then + echo "gcc version: `gcc --version`" + PLATFORM_NAME=`gcc -dumpmachine`-gcc-`gcc -dumpversion` + fi + else + # Prefer clang on Appple platforms + if [ -f /usr/bin/clang ] ; then + echo "clang version: `clang --version`" + PLATFORM_NAME=`clang -dumpmachine`-clang-`clang -dumpversion` + fi + fi + else + # Use compiler specified by ${CC} environment variable + IFS=- read $PLATFORM_NAME $COMPILER_VERSION <<< "${CC}" + echo "CC version: `${CC} --version`" + PLATFORM_NAME=$PLATFORM_NAME-`${CC} -dumpversion` + fi + + if [ -z "${PLATFORM_NAME}" ] ; then + # Default configuration name for unknown compiler + # could be overridden by setting env var explicitly + PLATFORM_NAME=unknown-0 + fi +} + +## +## Detect Host OS, install tools and detect compiler +## +function install_tools { + + # Marker file to signal that the tools have been already installed (save build time for incremental builds) + BUILDTOOLS_FILE=`pwd`/.buildtools + + # Host OS detection + OS_NAME=`uname -a` + case "$OS_NAME" in + *Darwin*) + export APPLE=1 + # Set target MacOS minver + export MACOSX_DEPLOYMENT_TARGET=10.10 + install_mac_tools ;; + + *Linux*) + export LINUX=1 + [[ -z "$NOROOT" ]] && install_linux_tools || echo "No root. Skipping build tools installation." ;; + + *) + echo "WARNING: unsupported OS $OS_NAME. Skipping build tools installation." ;; + esac + + detect_compiler +} + +## +## Parse arguments +## +function parse_args { + # Build debug build by default + if [ "$1" == "release" ] ; then + BUILD_TYPE="release" + else + BUILD_TYPE="debug" + fi +} + +################################################################################################################ + +## Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +cd $WORKSPACE_ROOT +echo "Current directory is `pwd`" + +# Parse command line arguments +parse_args + +# Install the necessary build tools if needed +[[ -z "$NOROOT" ]] && install_tools || echo "No root: skipping build tools installation." + +# Build given configuration. Default configuration is ABI-stable 'nostd::' classes. +# Please refer to CMakeLists.txt for the list of supported build configurations. +BUILD_CONFIG=${1-nostd} +shift +BUILD_OPTIONS="$@" +build +runtests diff --git a/tools/setup-buildtools-mac.sh b/tools/setup-buildtools-mac.sh index cf3090237e..dab077976c 100755 --- a/tools/setup-buildtools-mac.sh +++ b/tools/setup-buildtools-mac.sh @@ -31,4 +31,3 @@ brew install google-benchmark brew tap nlohmann/json brew install nlohmann-json brew install abseil -./tools/build-gtest.sh diff --git a/tools/setup-buildtools.sh b/tools/setup-buildtools.sh index a5fe2c5f0c..30e10fb5a5 100755 --- a/tools/setup-buildtools.sh +++ b/tools/setup-buildtools.sh @@ -1,6 +1,9 @@ -#!/bin/sh +#!/bin/bash -if [ -f /bin/yum ]; then +# Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + +if [ -f /bin/yum ] ; then # Prefer yum over apt-get yum -y install automake yum -y install autoconf @@ -22,23 +25,12 @@ yum -y install devtoolset-7-valgrind yum-config-manager --enable rhel-server-rhscl-7-rpms - -if [ `cmake --version | grep 3` == "" ]; then -yum -y remove cmake -wget https://cmake.org/files/v3.6/cmake-3.6.2.tar.gz -tar -zxvf cmake-3.6.2.tar.gz -cd cmake-3.6.2 -./bootstrap --prefix=/usr/local -make -make install -cd .. -fi - else # Use apt-get export DEBIAN_FRONTEND=noninteractive apt-get update -y apt-get install -qq automake +apt-get install -qq bc apt-get install -qq libtool-bin apt-get install -qq cmake apt-get install -qq curl @@ -52,13 +44,13 @@ apt-get install -qq libsqlite3-dev #apt install libsqlite3-dev apt-get install -qq wget apt-get install -qq clang-format -apt-get install -qq gtest apt-get install -qq libgtest-dev apt-get install -qq libbenchmark-dev apt-get install -qq nlohmann-json-dev fi +# Build and install latest CMake +$DIR/setup-cmake.sh + ## Change owner from root to current dir owner chown -R `stat . -c %u:%g` * - -./tools/build-gtest.sh From 71136a58b44bbdcb828e7160f4e1acdb7a25848a Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:20:56 -0800 Subject: [PATCH 13/54] Add Windows build tools --- CMakeSettings.json | 51 ++++++++++++++++++++++++++++++++++++++ tools/build-vs2015.cmd | 9 +++++-- tools/build-vs2017.cmd | 7 +++++- tools/build-vs2019.cmd | 10 ++++++++ tools/build.cmd | 20 +++++++++------ tools/setup-buildtools.cmd | 35 +++++++++++++++----------- 6 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 CMakeSettings.json diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 0000000000..4b2923f3ca --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,51 @@ +{ + "configurations": [ + { + "name": "nostd-x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [ + { + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" + } + ] + }, + { + "name": "nostd-x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "cmakeToolchain": "", + "variables": [ + { + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" + } + ] + } + ] +} \ No newline at end of file diff --git a/tools/build-vs2015.cmd b/tools/build-vs2015.cmd index a80ca66409..30bb41c3c9 100644 --- a/tools/build-vs2015.cmd +++ b/tools/build-vs2015.cmd @@ -1,6 +1,11 @@ +REM Build with Visual Studio 2015 set "VS_TOOLS_VERSION=vs2015" -REM Ref. https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2014%202015.html -set "CMAKE_GEN=Visual Studio 14 2015 Win64" +set ARCH=Win64 +if NOT "%1"=="" ( + set ARCH=%1 +) +set "CMAKE_GEN=Visual Studio 14 2015 %ARCH%" cd %~dp0 call setup-buildtools.cmd +REM TODO: currently we cannot build without Abseil variant for Visual Studio 2015 call build.cmd -DWITH_ABSEIL:BOOL=ON diff --git a/tools/build-vs2017.cmd b/tools/build-vs2017.cmd index be4322892c..de84593123 100644 --- a/tools/build-vs2017.cmd +++ b/tools/build-vs2017.cmd @@ -1,5 +1,10 @@ +REM Build with Visual Studio 2017 set "VS_TOOLS_VERSION=vs2017" -set "CMAKE_GEN=Visual Studio 15 2017 Win64" +set ARCH=Win64 +if NOT "%1"=="" ( + set ARCH=%1 +) +set "CMAKE_GEN=Visual Studio 15 2017 %ARCH%" cd %~dp0 call setup-buildtools.cmd call build.cmd diff --git a/tools/build-vs2019.cmd b/tools/build-vs2019.cmd index 554c291a31..b4a39938a3 100644 --- a/tools/build-vs2019.cmd +++ b/tools/build-vs2019.cmd @@ -1,4 +1,14 @@ +REM Build with Visual Studio 2017 set "VS_TOOLS_VERSION=vs2019" +set ARCH=Win64 +if NOT "%1"=="" ( + set ARCH=%1 +) +if "%ARCH%"=="Win64" ( + REM Parameter needed for CMake Visual Studio 2019 generator + set CMAKE_ARCH=x64 +) + set "CMAKE_GEN=Visual Studio 16 2019" cd %~dp0 call setup-buildtools.cmd diff --git a/tools/build.cmd b/tools/build.cmd index e49bc14289..55cc8d6c8f 100644 --- a/tools/build.cmd +++ b/tools/build.cmd @@ -21,6 +21,10 @@ setlocal enableextensions setlocal enabledelayedexpansion set "ROOT=%~dp0\.." +if ("%CMAKE_ARCH%"=="") ( + set CMAKE_ARCH=x64 +) + REM Use preinstalled vcpkg if installed or use our local if "%VCPKG_INSTALLATION_ROOT%" neq "" ( set "VCPKG_CMAKE=%VCPKG_INSTALLATION_ROOT%\scripts\buildsystems\vcpkg.cmake" @@ -33,7 +37,6 @@ REM Setup compiler environment REM ******************************************************************** call "%~dp0\vcvars.cmd" - REM ******************************************************************** REM Use cmake REM ******************************************************************** @@ -47,10 +50,10 @@ set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\nostd" call :build_config REM ******************************************************************** -REM Build with STL implementation - only for vs2017+ +REM Build with STL implementation only for vs2017+ REM ******************************************************************** if "%VS_TOOLS_VERSION%" neq "vs2015" ( - set CONFIG=-DWITH_STL:BOOL=ON + set CONFIG=-DWITH_STL:BOOL=ON %* set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\stl" call :build_config ) @@ -66,9 +69,12 @@ REM ******************************************************************** REM TODO: consider rmdir for clean builds if not exist "%OUTDIR%" mkdir "%OUTDIR%" cd "%OUTDIR%" -REM Optional platform specification parameter below: -Ax64 -cmake %ROOT% -G "%CMAKE_GEN%" -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +if ("%VS_TOOLS_VERSION%"=="vs2019") ( + REM Only latest vs2019 generator supports and requires -A parameter + cmake %ROOT% -G "%CMAKE_GEN%" -A %CMAKE_ARCH% -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +) else ( + cmake %ROOT% -G "%CMAKE_GEN%" -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +) set "SOLUTION=%OUTDIR%\opentelemetry-cpp.sln" -REM TODO: allow building [Release|Debug]x[Win32|x64|ARM|ARM64] -msbuild "%SOLUTION%" /p:Configuration=Release /p:Platform=x64 /p:VcpkgEnabled=true +msbuild "%SOLUTION%" /p:Configuration=Release /p:VcpkgEnabled=true exit /b 0 diff --git a/tools/setup-buildtools.cmd b/tools/setup-buildtools.cmd index 830c650c07..25232422dd 100644 --- a/tools/setup-buildtools.cmd +++ b/tools/setup-buildtools.cmd @@ -1,12 +1,22 @@ @echo off -set "PATH=%PATH%;%~dp0;%~dp0\vcpkg" +set "PATH=C:\Program Files\CMake\bin;%~dp0;%~dp0\vcpkg;%PATH%" pushd %~dp0 -REM Fail if chocolatey is not installed -where /Q choco -if ERRORLEVEL 1 ( - echo This script requires chocolatey. Installation instructions: https://chocolatey.org/docs/installation - exit -1 +net session >nul 2>&1 +if %errorLevel% == 0 ( + echo Running with Administrative privilege... + REM Fail if chocolatey is not installed + where /Q choco + if ERRORLEVEL 1 ( + echo This script requires chocolatey. Installation instructions: https://chocolatey.org/docs/installation + exit -1 + ) + REM Install tools needed for building, but only if not installed yet + where /Q vswhere || choco install -y vswhere + where /Q cmake || choco install -y cmake + where /Q git || choco install -y git +) else ( + echo Running without Administrative privilege... ) REM Print current Visual Studio installations detected @@ -16,13 +26,6 @@ if ERRORLEVEL 0 ( vswhere -property installationPath ) -REM Install tools needed for building stuff -choco install -y cmake -choco install -y svn -choco install -y git -choco install -y llvm -choco install -y zip - REM Try to autodetect Visual Studio call "%~dp0\vcvars.cmd" if "%TOOLS_VS_NOTFOUND%" == "1" ( @@ -37,14 +40,16 @@ if ERRORLEVEL 1 ( pushd .\vcpkg call bootstrap-vcpkg.bat popd +) else ( + echo Using existing vcpkg installation... ) -REM Install it +REM Install dependencies vcpkg install gtest:x64-windows vcpkg install --head --overlay-ports=%~dp0\ports benchmark:x64-windows vcpkg install ms-gsl:x64-windows vcpkg install nlohmann-json:x64-windows vcpkg install abseil:x64-windows -vcpkg integrate install +vcpkg install protobuf:x64-windows popd exit /b 0 From 54cc0dde0090867d93b0097f97f3cbf5ea33fadc Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:21:46 -0800 Subject: [PATCH 14/54] Fix dependency issue for build on Windows with OTLP exporter enabled --- .../Protobuf.cmake => cmake/opentelemetry-proto.cmake | 2 +- exporters/otlp/CMakeLists.txt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) rename third_party/opentelemetry-proto/Protobuf.cmake => cmake/opentelemetry-proto.cmake (95%) diff --git a/third_party/opentelemetry-proto/Protobuf.cmake b/cmake/opentelemetry-proto.cmake similarity index 95% rename from third_party/opentelemetry-proto/Protobuf.cmake rename to cmake/opentelemetry-proto.cmake index 50a174f1fc..7f0ba90763 100644 --- a/third_party/opentelemetry-proto/Protobuf.cmake +++ b/cmake/opentelemetry-proto.cmake @@ -37,7 +37,7 @@ add_custom_command( ${TRACE_PROTO} ) -include_directories(SYSTEM "${CMAKE_BINARY_DIR}/generated/third_party/opentelemetry-proto") +include_directories("${GENERATED_PROTOBUF_PATH}") add_library(opentelemetry_proto OBJECT ${COMMON_PB_CPP_FILE} diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 27ee7de956..eebd9829ec 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -1,8 +1,7 @@ include_directories(include) add_library(opentelemetry_exporter_otprotocol src/recordable.cc) -target_link_libraries(opentelemetry_exporter_otprotocol - $) +target_link_libraries(opentelemetry_exporter_otprotocol opentelemetry_proto) if(BUILD_TESTING) add_executable(recordable_test test/recordable_test.cc) From 6a22842a105c72e878a2e869cbdfa89457edd28f Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:22:32 -0800 Subject: [PATCH 15/54] Update benchmark to latest --- third_party/benchmark | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/benchmark b/third_party/benchmark index dce3322a54..348aa2c964 160000 --- a/third_party/benchmark +++ b/third_party/benchmark @@ -1 +1 @@ -Subproject commit dce3322a549650d18f50b5f1428a5942327ab6a5 +Subproject commit 348aa2c964494b5947c0e7f96b82c1fe844d684f From 6b1144333c8bce4d8805187b20fdf132a4f9a797 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:23:16 -0800 Subject: [PATCH 16/54] Ignore scripts copied into docker build from /tools --- docker/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 docker/.gitignore diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 0000000000..21c4e486a8 --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1 @@ +**/setup-*.sh From b72ddd97fc3dca009ed204b35976d562058004e7 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:41:44 -0800 Subject: [PATCH 17/54] Rework CMakeLists.txt to: - use vcpkg for Protobuf and GTest on Windows, assuming it gets built with the matching compiler by vcpkg. - build with prebuilt Protobuf compiler and build GTest/Benchmark from source on POSIX with the matching compiler. --- CMakeLists.txt | 62 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e19e75d0f..53fa0ab08a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,20 +15,20 @@ option(WITH_OTLP "Whether to include the OpenTelemetry Protocol in the SDK" OFF) option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK" OFF) -option(WITH_TESTS "Whether to enable tests" ON) +option(BUILD_TESTING "Whether to enable tests" ON) option(WITH_EXAMPLES "Whether to build examples" ON) set(WITH_PROTOBUF OFF) -if(WITH_OTLP) - set(WITH_PROTOBUF ON) -endif() - -if(WITH_TESTS) - include(CTest) -endif() find_package(Threads) +function(install_windows_deps) + # Bootstrap vcpkg from CMake and auto-install deps in case if we are missing deps on Windows + message("Installing build tools and dependencies...") + execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-buildtools.cmd) + set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake) +endfunction() + if(MSVC) # Options for Visual C++ compiler: /Zc:__cplusplus - report an updated value # for recent C++ language standards. Without this option MSVC returns the @@ -36,23 +36,59 @@ if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus") endif() +if(WITH_OTLP) + set(WITH_PROTOBUF ON) +endif() + if(WITH_PROTOBUF) set(protobuf_MODULE_COMPATIBLE ON) - find_package(Protobuf CONFIG NAMES protobuf) - # Older versions of protobuf don't use cmake config files. + find_package(Protobuf REQUIRED) if(NOT protobuf_FOUND) + if(WIN32) + install_windows_deps() + endif() find_package(Protobuf REQUIRED) + if(WIN32) + # Always use x64 protoc.exe + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + set(Protobuf_PROTOC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/packages/protobuf_x64-windows/tools/protobuf/protoc.exe) + endif() + endif() + # Latest Protobuf uses mixed case instead of uppercase + set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE}) endif() + message("PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}") endif() if(WITH_OTLP) - include(third_party/opentelemetry-proto/Protobuf.cmake) + include(cmake/opentelemetry-proto.cmake) endif() +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") + if(BUILD_TESTING) - find_package(GTest REQUIRED) - find_package(benchmark REQUIRED) + include(CTest) + if(EXISTS ${CMAKE_BINARY_DIR}/lib/libgtest.a) + # Prefer GTest from build tree. GTest is not always working with CMAKE_PREFIX_PATH + set(GTEST_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include) + set(GTEST_BOTH_LIBRARIES ${CMAKE_BINARY_DIR}/lib/libgtest.a ${CMAKE_BINARY_DIR}/lib/libgtest_main.a ${CMAKE_BINARY_DIR}/lib/libgmock.a) + elseif(WIN32) + # Make sure we are always bootsrapped with vcpkg on Windows + find_package(GTest) + if(NOT GTEST_FOUND) + install_windows_deps() + find_package(GTest REQUIRED) + endif() + else() + # Prefer GTest installed by OS distro, brew or vcpkg package manager + find_package(GTest REQUIRED) + endif() include_directories(SYSTEM ${GTEST_INCLUDE_DIRS}) + message("GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}") + message("GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}") + enable_testing() + # Benchmark respects the CMAKE_PREFIX_PATH + find_package(benchmark CONFIG REQUIRED) endif() include_directories(api/include) From c4d5675205e7259bef83b1408c151c7cd1cdd859 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:42:16 -0800 Subject: [PATCH 18/54] Clean-up Dockerfile for Ubuntu 16/18/20 to make sure we do not unnecessarily install protobuf --- docker/ubuntu16.04/Dockerfile | 3 --- docker/ubuntu18.04/Dockerfile | 1 - docker/ubuntu20.04/Dockerfile | 1 - 3 files changed, 5 deletions(-) diff --git a/docker/ubuntu16.04/Dockerfile b/docker/ubuntu16.04/Dockerfile index e705618484..5fbbcc9755 100644 --- a/docker/ubuntu16.04/Dockerfile +++ b/docker/ubuntu16.04/Dockerfile @@ -20,9 +20,6 @@ RUN apt-get install -qq -y --ignore-missing \ libtool-bin \ make \ pkg-config \ - protobuf \ - protobuf-compiler \ - libprotobuf-dev \ python \ sudo \ tar \ diff --git a/docker/ubuntu18.04/Dockerfile b/docker/ubuntu18.04/Dockerfile index 45f6cbf8e6..fd7829298f 100644 --- a/docker/ubuntu18.04/Dockerfile +++ b/docker/ubuntu18.04/Dockerfile @@ -19,7 +19,6 @@ RUN apt-get install -qq -y --ignore-missing \ libtool-bin \ make \ pkg-config \ - protobuf \ protobuf-compiler \ libprotobuf-dev \ python \ diff --git a/docker/ubuntu20.04/Dockerfile b/docker/ubuntu20.04/Dockerfile index 74dab23a66..a440715e3e 100644 --- a/docker/ubuntu20.04/Dockerfile +++ b/docker/ubuntu20.04/Dockerfile @@ -19,7 +19,6 @@ RUN apt-get install -qq -y --ignore-missing \ libtool-bin \ make \ pkg-config \ - protobuf \ protobuf-compiler \ libprotobuf-dev \ python \ From 68a446144048500c6afe155588a7a489c1154b31 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:45:06 -0800 Subject: [PATCH 19/54] Clean modules --- .gitmodules | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index 644ae871be..2a3c7068cf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,8 +23,4 @@ url = https://github.com/google/benchmark branch = master -[submodule "third_party/opentelemetry-proto"] - path = third_party/opentelemetry-proto - url = https://github.com/open-telemetry/opentelemetry-proto - branch = master From de67ca5e28177b63ec0d32bfa99ea6e2e72ba3a2 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:47:20 -0800 Subject: [PATCH 20/54] Add submodule for opentelemetry-proto --- .gitmodules | 5 ++++- third_party/opentelemetry-proto | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 160000 third_party/opentelemetry-proto diff --git a/.gitmodules b/.gitmodules index 2a3c7068cf..e84b068aa3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,4 +23,7 @@ url = https://github.com/google/benchmark branch = master - +[submodule "third_party/opentelemetry-proto"] + path = third_party/opentelemetry-proto + url = https://github.com/open-telemetry/opentelemetry-proto + branch = master diff --git a/third_party/opentelemetry-proto b/third_party/opentelemetry-proto new file mode 160000 index 0000000000..f11e0538fd --- /dev/null +++ b/third_party/opentelemetry-proto @@ -0,0 +1 @@ +Subproject commit f11e0538fd7dc30127ca6bfb2062e5d9f782b77b From 66489b990a266a6c24bdbdefb962ae05cdc13bdd Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Sun, 15 Nov 2020 23:50:53 -0800 Subject: [PATCH 21/54] Fix permissions and attributes --- .gitattributes | 7 ++++--- tools/build-benchmark.sh | 0 tools/build-vcpkg.sh | 0 tools/setup-cmake.sh | 0 tools/setup-protobuf.sh | 0 5 files changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 tools/build-benchmark.sh mode change 100644 => 100755 tools/build-vcpkg.sh mode change 100644 => 100755 tools/setup-cmake.sh mode change 100644 => 100755 tools/setup-protobuf.sh diff --git a/.gitattributes b/.gitattributes index c1c540735f..ca13be9c45 100644 --- a/.gitattributes +++ b/.gitattributes @@ -37,6 +37,7 @@ LICENSE* text *.pdf binary *.rtf binary -## Self-reference =) -.gitignore text -.gitattributes text +## git files +.gitignore text eol=lf +.gitattributes text eol=lf +.gitattributes text eol=lf diff --git a/tools/build-benchmark.sh b/tools/build-benchmark.sh old mode 100644 new mode 100755 diff --git a/tools/build-vcpkg.sh b/tools/build-vcpkg.sh old mode 100644 new mode 100755 diff --git a/tools/setup-cmake.sh b/tools/setup-cmake.sh old mode 100644 new mode 100755 diff --git a/tools/setup-protobuf.sh b/tools/setup-protobuf.sh old mode 100644 new mode 100755 From c19519d3b865ecb70833e6dd2193d0988c1e0d1c Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 02:05:17 -0800 Subject: [PATCH 22/54] Initial implementation of VCPKG support --- docs/building-with-vcpkg.md | 84 +++++++++++++++++++ tools/build-vcpkg.sh | 3 +- tools/build.sh | 10 ++- tools/install.sh | 13 +++ tools/ports/opentelemetry/CONTROL | 10 +++ tools/ports/opentelemetry/TODO.md | 7 ++ tools/ports/opentelemetry/get_repo_name.sh | 6 ++ tools/ports/opentelemetry/portfile.cmake | 76 +++++++++++++++++ .../opentelemetry/response_file_linux.txt | 9 ++ .../ports/opentelemetry/response_file_mac.txt | 9 ++ 10 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 docs/building-with-vcpkg.md create mode 100644 tools/install.sh create mode 100644 tools/ports/opentelemetry/CONTROL create mode 100644 tools/ports/opentelemetry/TODO.md create mode 100644 tools/ports/opentelemetry/get_repo_name.sh create mode 100644 tools/ports/opentelemetry/portfile.cmake create mode 100644 tools/ports/opentelemetry/response_file_linux.txt create mode 100644 tools/ports/opentelemetry/response_file_mac.txt diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md new file mode 100644 index 0000000000..3b42691965 --- /dev/null +++ b/docs/building-with-vcpkg.md @@ -0,0 +1,84 @@ +# Building OpenTelemetry C++ SDK with vcpkg + +vcpkg is a Microsoft cross-platform open source C++ package manager. Onboarding instructions for Windows, Linux and Mac OS X [available here](https://docs.microsoft.com/en-us/cpp/build/vcpkg). This document assumes that the customer build system is already configured to use vcpkg. OpenTelemetry C++ SDK maintainers provide a build recipe, `opentelemetry` port or CONTROL file for vcpkg. Mainline vcpkg repo is refreshed to point to latest stable open source release of OpenTelemetry C++ SDK. + +## Installing opentelemetry package + +The following command can be used to install the public open source release: + +```console +vcpkg install opentelemetry +``` + +That's it! The package should be compiled for the current OS. + +See instructions below to build the SDK with additional Microsoft-proprietary modules. + +## Testing custom dev OpenTelemetry build on Windows + +`cmd.exe` command line prompt commands: + +```console +git clone --recurse-submodules https://github.com/open-telemetry/opentelemetry-cpp +cd opentelemetry-cpp +vcpkg install --head --overlay-ports=%CD%\tools\ports opentelemetry +``` + +## Testing custom dev OpenTelemetry build on POSIX (Linux and Mac) + +Shell commands: + +```console +git clone --recurse-submodules https://github.com/open-telemetry/opentelemetry-cpp +cd opentelemetry-cpp +vcpkg install --head --overlay-ports=`pwd`/tools/ports opentelemetry +``` + +## Using response files to specify dependencies + +vcpkg allows to consolidate parameters passed to vcpkg in a response file. All 3rd party dependencies needed for OpenTelemetry SDK can be described and installed via response file. + +Example for Mac: + +```console +vcpkg install @tools/ports/opentelemetry/response_file_mac.txt +``` + +Example for Linux: + +```console +vcpkg install @tools/ports/opentelemetry/response_file_linux.txt +``` + +vcpkg build log files are created in `${VCPKG_INSTALL_DIR}/buildtrees/opentelemetry/build-[err|out].log` . Review the logs in case if you encounter package installation failures. + +## Using triplets + +In order to enable custom build flags - vcpkg triplets and custom environment variables may be used. Please see [triplets instruction here](https://vcpkg.readthedocs.io/en/latest/users/triplets/). Response file for a custom build, e.g. `response_file_linux_PRODUCTNAME.txt` may specify a custom triplet. For example, custom triplet controls if the library is built as static or dynamic. Default triplets may also be overridden with [custom triplets](https://vcpkg.readthedocs.io/en/latest/examples/overlay-triplets-linux-dynamic/#overlay-triplets-example). Custom triplets specific to various products must be maintained by product teams. Product teams may optionally decide to integrate their triplets in the mainline OpenTelemetry C++ SDK repo as-needed. + +## Using Feature Packages + +To install opentelemetry built with standard library API surface classes: + +```console +vcpkg install opentelemetry[stdlib] +``` + +To install opentelemetry built with Abseil API surface classes: + +```console +vcpkg install opentelemetry[abseil] +``` + +## Build with vcpkg dependencies + +`CMakeLists.txt` in top-level directory lists the following package dependencies: + +- `Protobuf` - required for OTLP exporter. Not required otherwise. +- `GTest` - required when building with tests enabled. +- `Benchmark` - required when building with tests enabled. +- `ms-gsl` - required for `gsl::span` when building with Standard Library with C++14 or C++17 compiler. +- `nlohmann-json` - required when building with zPages module. +- `prometheus-cpp` - required for Prometheus exporter. + +It is possible to adjust the build system to use either vcpkg-installed dependencies or OS-provided dependencies, e.g. `brew` or `deb` packages. diff --git a/tools/build-vcpkg.sh b/tools/build-vcpkg.sh index eec27c8d4f..f7fb829ce2 100755 --- a/tools/build-vcpkg.sh +++ b/tools/build-vcpkg.sh @@ -17,7 +17,8 @@ vcpkg install benchmark vcpkg install ms-gsl vcpkg install nlohmann-json vcpkg install abseil +vcpkg install protobuf cd $WORKSPACE_ROOT export USE_VCPKG=1 -./tools/build.sh ${1:-nostd} ${2:--DCMAKE_TOOLCHAIN_FILE=$WORKSPACE_ROOT/tools/vcpkg/scripts/buildsystems/vcpkg.cmake} +./tools/build.sh ${1-nostd} ${2--DCMAKE_TOOLCHAIN_FILE=$WORKSPACE_ROOT/tools/vcpkg/scripts/buildsystems/vcpkg.cmake} diff --git a/tools/build.sh b/tools/build.sh index 0a4ca6c7eb..adce46b53c 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -41,9 +41,13 @@ function build_dependencies { function build { echo "Build configuration: $BUILD_CONFIG" cd $WORKSPACE_ROOT - - export BUILD_ROOT=`pwd`/out/$PLATFORM_NAME/$BUILD_CONFIG + + BUILD_ROOT=`pwd`/out/$PLATFORM_NAME/$BUILD_CONFIG mkdir -p $BUILD_ROOT + if [ ! -w $BUILD_ROOT ] ; then + echo "Unable to create output directory: $BUILD_ROOT" + exit 1 + fi if [ -z ${USE_VCPKG} ] ; then # TODO: consider that dependencies may also be coming from OS or brew @@ -51,7 +55,7 @@ function build { else echo VCPKG_ROOT=${VCPKG_ROOT} # Prefer ninja from VCPKG if available - NINJA=$WORKSPACE_ROOT/`find tools/vcpkg -name ninja -print -quit` + NINJA=$WORKSPACE_ROOT/`find tools/vcpkg -name ninja -type f -print -quit` if [ -z ${NINJA} ] ; then NINJA=`which ninja` fi diff --git a/tools/install.sh b/tools/install.sh new file mode 100644 index 0000000000..b034750b74 --- /dev/null +++ b/tools/install.sh @@ -0,0 +1,13 @@ +#!/bin/bash +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +pushd $WORKSPACE_ROOT +OPENTELEMETRY_INSTALL_DIR=${1-/usr/local} +echo "Install SDK to $OPENTELEMETRY_INSTALL_DIR" +mkdir -p $OPENTELEMETRY_INSTALL_DIR/lib +# TODO: install libraries? +cp -R api/include $OPENTELEMETRY_INSTALL_DIR +cp -R sdk/include/opentelemetry/sdk $OPENTELEMETRY_INSTALL_DIR/include/opentelemetry +mkdir -p $OPENTELEMETRY_INSTALL_DIR/lib +echo dummy > $OPENTELEMETRY_INSTALL_DIR/lib/libopentelemetry.stub +popd diff --git a/tools/ports/opentelemetry/CONTROL b/tools/ports/opentelemetry/CONTROL new file mode 100644 index 0000000000..d766249fb9 --- /dev/null +++ b/tools/ports/opentelemetry/CONTROL @@ -0,0 +1,10 @@ +Source: opentelemetry +Version: 0.0.1 +Homepage: https://github.com/open-telemetry/opentelemetry-cpp +Description: OpenTelemetry C++ SDK + +Feature: stdlib +Description: Build OpenTelemetry with Standard Library classes + +Feature: abseil +Description: Build OpenTelemetry with Abseil classes diff --git a/tools/ports/opentelemetry/TODO.md b/tools/ports/opentelemetry/TODO.md new file mode 100644 index 0000000000..9dbb7f7e93 --- /dev/null +++ b/tools/ports/opentelemetry/TODO.md @@ -0,0 +1,7 @@ +# TODO + +- Consider adding the following line to portfile.cmake + +``` +Build-Depends: curl[ssl], nlohmann-json +``` diff --git a/tools/ports/opentelemetry/get_repo_name.sh b/tools/ports/opentelemetry/get_repo_name.sh new file mode 100644 index 0000000000..e98b382baa --- /dev/null +++ b/tools/ports/opentelemetry/get_repo_name.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +pushd $DIR/../../ > /dev/null +basename -s .git `git config --get remote.origin.url` +popd > /dev/null diff --git a/tools/ports/opentelemetry/portfile.cmake b/tools/ports/opentelemetry/portfile.cmake new file mode 100644 index 0000000000..7c10e1a48f --- /dev/null +++ b/tools/ports/opentelemetry/portfile.cmake @@ -0,0 +1,76 @@ +include(vcpkg_common_functions) + +message("CURRENT_PACKAGES_DIR = ${CURRENT_PACKAGES_DIR}") + +message("CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}") +message("CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}") +message("CMAKE_CURRENT_LIST_DIR = ${CMAKE_CURRENT_LIST_DIR}") + +message("VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}") +message("VCPKG_CMAKE_SYSTEM_NAME = ${VCPKG_CMAKE_SYSTEM_NAME}") +message("VCPKG_LIBRARY_LINKAGE = ${VCPKG_LIBRARY_LINKAGE}") + +vcpkg_check_features( + OUT_FEATURE_OPTIONS FEATURE_OPTIONS + stdlib WITH_STDLIB + abseil WITH_ABSEIL +) + +# TODO: if building dynamic, use portable ABI. if building static, use STDLIB +string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" BUILD_SHARED) +string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" BUILD_STATIC) + +if (NOT DEFINED WIN32) + execute_process(COMMAND "${CMAKE_CURRENT_LIST_DIR}/get_repo_name.sh" OUTPUT_VARIABLE REPO_NAME ERROR_QUIET) + message("REPO_NAME=${REPO_NAME}") +endif() + +if (DEFINED REPO_NAME) + # Use local snapshot since we already cloned the code + get_filename_component(SOURCE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + message("Using local source snapshot from ${SOURCE_PATH}") +else() + # Fetch from GitHub master + message("Fetching source code from GitHub...") + vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO open-telemetry/opentelemetry-cpp + HEAD_REF master + ) +endif() + +# TODO: it will be slightly cleaner to perform pure CMake or Ninja build, by describing all possible variable options +# as separate triplets. Since we have a fairly non-trivial build logic in build.sh script - we use it as-is for now. +# build.sh itself should check if we are building under vcpkg and avoid installing deps that are coming from vcpkg. +if (UNIX) + set(ENV{USE_VCPKG} 1) + set(ENV{NOROOT} 1) + + # Custom options could be passed to COMMAND, e.g. + # vcpkg_execute_build_process( + # COMMAND ${SOURCE_PATH}/tools/build.sh nostd-vcpkg -DBUILD_TESTING=OFF + # ... + # + vcpkg_execute_build_process( + COMMAND ${SOURCE_PATH}/tools/build.sh nostd-vcpkg ${FEATURE_OPTIONS} + WORKING_DIRECTORY ${SOURCE_PATH}/ + LOGNAME build + ) + + vcpkg_execute_build_process( + COMMAND ${SOURCE_PATH}/tools/install.sh ${CURRENT_PACKAGES_DIR} + WORKING_DIRECTORY ${SOURCE_PATH}/ + LOGNAME install + ) + +else() + # TODO: verify Windows build + vcpkg_execute_build_process( + COMMAND ${SOURCE_PATH}/tools/build.cmd + WORKING_DIRECTORY ${SOURCE_PATH}/ + LOGNAME build + # TODO: add Windows headers installation step + ) +endif() + +file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright) diff --git a/tools/ports/opentelemetry/response_file_linux.txt b/tools/ports/opentelemetry/response_file_linux.txt new file mode 100644 index 0000000000..528b04a268 --- /dev/null +++ b/tools/ports/opentelemetry/response_file_linux.txt @@ -0,0 +1,9 @@ +--head +--overlay-ports=tools/ports +gtest +benchmark +ms-gsl +nlohmann-json +abseil +protobuf +opentelemetry diff --git a/tools/ports/opentelemetry/response_file_mac.txt b/tools/ports/opentelemetry/response_file_mac.txt new file mode 100644 index 0000000000..528b04a268 --- /dev/null +++ b/tools/ports/opentelemetry/response_file_mac.txt @@ -0,0 +1,9 @@ +--head +--overlay-ports=tools/ports +gtest +benchmark +ms-gsl +nlohmann-json +abseil +protobuf +opentelemetry From b782d8d3c46b8764aa4b145fa9aa5ec99d481de3 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 02:37:06 -0800 Subject: [PATCH 23/54] Apply latest cmake format 0.6.13 - it looks much cleaner --- CMakeLists.txt | 25 ++++++++++++++++------- api/test/context/CMakeLists.txt | 5 ++++- api/test/core/CMakeLists.txt | 6 ++++-- api/test/logs/CMakeLists.txt | 5 ++++- api/test/metrics/CMakeLists.txt | 5 ++++- api/test/nostd/CMakeLists.txt | 5 ++++- api/test/plugin/CMakeLists.txt | 6 ++++-- api/test/trace/CMakeLists.txt | 6 ++++-- api/test/trace/propagation/CMakeLists.txt | 5 ++++- ci/install_format_tools.sh | 2 +- docker/ubuntu16.04/Dockerfile | 2 +- docker/ubuntu18.04/Dockerfile | 2 +- docker/ubuntu20.04/Dockerfile | 2 +- exporters/memory/CMakeLists.txt | 12 +++++++---- exporters/ostream/CMakeLists.txt | 12 +++++++---- exporters/otlp/CMakeLists.txt | 6 ++++-- exporters/prometheus/test/CMakeLists.txt | 6 ++++-- ext/test/zpages/CMakeLists.txt | 5 ++++- sdk/test/common/CMakeLists.txt | 5 ++++- sdk/test/metrics/CMakeLists.txt | 5 ++++- sdk/test/trace/CMakeLists.txt | 5 ++++- 21 files changed, 94 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53fa0ab08a..db28dfa487 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,10 +23,13 @@ set(WITH_PROTOBUF OFF) find_package(Threads) function(install_windows_deps) - # Bootstrap vcpkg from CMake and auto-install deps in case if we are missing deps on Windows + # Bootstrap vcpkg from CMake and auto-install deps in case if we are missing + # deps on Windows message("Installing build tools and dependencies...") - execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-buildtools.cmd) - set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake) + execute_process( + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-buildtools.cmd) + set(CMAKE_TOOLCHAIN_FILE + ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake) endfunction() if(MSVC) @@ -51,7 +54,9 @@ if(WITH_PROTOBUF) if(WIN32) # Always use x64 protoc.exe if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - set(Protobuf_PROTOC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/packages/protobuf_x64-windows/tools/protobuf/protoc.exe) + set(Protobuf_PROTOC_EXECUTABLE + ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/packages/protobuf_x64-windows/tools/protobuf/protoc.exe + ) endif() endif() # Latest Protobuf uses mixed case instead of uppercase @@ -69,9 +74,15 @@ list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") if(BUILD_TESTING) include(CTest) if(EXISTS ${CMAKE_BINARY_DIR}/lib/libgtest.a) - # Prefer GTest from build tree. GTest is not always working with CMAKE_PREFIX_PATH - set(GTEST_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include) - set(GTEST_BOTH_LIBRARIES ${CMAKE_BINARY_DIR}/lib/libgtest.a ${CMAKE_BINARY_DIR}/lib/libgtest_main.a ${CMAKE_BINARY_DIR}/lib/libgmock.a) + # Prefer GTest from build tree. GTest is not always working with + # CMAKE_PREFIX_PATH + set(GTEST_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include) + set(GTEST_BOTH_LIBRARIES + ${CMAKE_BINARY_DIR}/lib/libgtest.a + ${CMAKE_BINARY_DIR}/lib/libgtest_main.a + ${CMAKE_BINARY_DIR}/lib/libgmock.a) elseif(WIN32) # Make sure we are always bootsrapped with vcpkg on Windows find_package(GTest) diff --git a/api/test/context/CMakeLists.txt b/api/test/context/CMakeLists.txt index 2edbbc6a86..ea5198fd90 100644 --- a/api/test/context/CMakeLists.txt +++ b/api/test/context/CMakeLists.txt @@ -4,5 +4,8 @@ foreach(testname context_test runtime_context_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX context. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX context. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/core/CMakeLists.txt b/api/test/core/CMakeLists.txt index 633759a9d5..7fead491e5 100644 --- a/api/test/core/CMakeLists.txt +++ b/api/test/core/CMakeLists.txt @@ -3,5 +3,7 @@ include(GoogleTest) add_executable(timestamp_test timestamp_test.cc) target_link_libraries(timestamp_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) -gtest_add_tests(TARGET timestamp_test TEST_PREFIX trace. TEST_LIST - timestamp_test) +gtest_add_tests( + TARGET timestamp_test + TEST_PREFIX trace. + TEST_LIST timestamp_test) diff --git a/api/test/logs/CMakeLists.txt b/api/test/logs/CMakeLists.txt index 737edb893c..9b1b3b0e7d 100644 --- a/api/test/logs/CMakeLists.txt +++ b/api/test/logs/CMakeLists.txt @@ -2,5 +2,8 @@ foreach(testname logger_provider_test logger_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX logs. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX logs. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/metrics/CMakeLists.txt b/api/test/metrics/CMakeLists.txt index c9d2083d5a..9d70c376ef 100644 --- a/api/test/metrics/CMakeLists.txt +++ b/api/test/metrics/CMakeLists.txt @@ -2,5 +2,8 @@ foreach(testname noop_instrument_test meter_provider_test noop_metrics_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index fdbf8e7b07..1fb120736e 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -5,5 +5,8 @@ foreach(testname function_ref_test string_view_test unique_ptr_test add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX nostd. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX nostd. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/plugin/CMakeLists.txt b/api/test/plugin/CMakeLists.txt index d17c300794..6bdcbf9c32 100644 --- a/api/test/plugin/CMakeLists.txt +++ b/api/test/plugin/CMakeLists.txt @@ -4,5 +4,7 @@ add_executable(dynamic_load_test dynamic_load_test.cc) target_link_libraries(dynamic_load_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) target_link_libraries(dynamic_load_test ${CMAKE_DL_LIBS}) -gtest_add_tests(TARGET dynamic_load_test TEST_PREFIX plugin. TEST_LIST - dynamic_load_test) +gtest_add_tests( + TARGET dynamic_load_test + TEST_PREFIX plugin. + TEST_LIST dynamic_load_test) diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index 3d3dc88891..0faac5cfb4 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -12,8 +12,10 @@ foreach( add_executable(api_${testname} "${testname}.cc") target_link_libraries(api_${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET api_${testname} TEST_PREFIX trace. TEST_LIST - api_${testname}) + gtest_add_tests( + TARGET api_${testname} + TEST_PREFIX trace. + TEST_LIST api_${testname}) endforeach() add_executable(span_id_benchmark span_id_benchmark.cc) diff --git a/api/test/trace/propagation/CMakeLists.txt b/api/test/trace/propagation/CMakeLists.txt index f2a9815426..ff707348bd 100644 --- a/api/test/trace/propagation/CMakeLists.txt +++ b/api/test/trace/propagation/CMakeLists.txt @@ -2,5 +2,8 @@ foreach(testname http_text_format_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() diff --git a/ci/install_format_tools.sh b/ci/install_format_tools.sh index c589250168..f65c8ff7a2 100755 --- a/ci/install_format_tools.sh +++ b/ci/install_format_tools.sh @@ -3,6 +3,6 @@ set -e apt install -y clang-format-8 python3-pip git curl -pip3 install cmake_format==0.6.5 +pip3 install cmake_format==0.6.13 curl -L -o /usr/local/bin/buildifier https://github.com/bazelbuild/buildtools/releases/download/2.2.1/buildifier chmod +x /usr/local/bin/buildifier diff --git a/docker/ubuntu16.04/Dockerfile b/docker/ubuntu16.04/Dockerfile index 5fbbcc9755..b5e340e395 100644 --- a/docker/ubuntu16.04/Dockerfile +++ b/docker/ubuntu16.04/Dockerfile @@ -32,7 +32,7 @@ RUN apt-get install -qq -y --ignore-missing \ RUN mkdir -p /usr/local/bin COPY ./setup-cmake.sh /usr/local/bin/setup-cmake.sh RUN chmod +x /usr/local/bin/setup-cmake.sh -RUN /usr/local/bin/setup-cmake.sh +RUN /usr/local/bin/setup-cmake.sh # ENTRYPOINT bash CMD /bin/bash diff --git a/docker/ubuntu18.04/Dockerfile b/docker/ubuntu18.04/Dockerfile index fd7829298f..90cacebbe8 100644 --- a/docker/ubuntu18.04/Dockerfile +++ b/docker/ubuntu18.04/Dockerfile @@ -33,7 +33,7 @@ RUN apt-get install -qq -y --ignore-missing \ RUN mkdir -p /usr/local/bin COPY ./setup-cmake.sh /usr/local/bin/setup-cmake.sh RUN chmod +x /usr/local/bin/setup-cmake.sh -RUN /usr/local/bin/setup-cmake.sh +RUN /usr/local/bin/setup-cmake.sh # ENTRYPOINT bash CMD /bin/bash diff --git a/docker/ubuntu20.04/Dockerfile b/docker/ubuntu20.04/Dockerfile index a440715e3e..5d321c1ff1 100644 --- a/docker/ubuntu20.04/Dockerfile +++ b/docker/ubuntu20.04/Dockerfile @@ -33,7 +33,7 @@ RUN apt-get install -qq -y --ignore-missing \ RUN mkdir -p /usr/local/bin COPY ./setup-cmake.sh /usr/local/bin/setup-cmake.sh RUN chmod +x /usr/local/bin/setup-cmake.sh -RUN /usr/local/bin/setup-cmake.sh +RUN /usr/local/bin/setup-cmake.sh # ENTRYPOINT bash CMD /bin/bash diff --git a/exporters/memory/CMakeLists.txt b/exporters/memory/CMakeLists.txt index aa8d334bd0..2739596fd5 100644 --- a/exporters/memory/CMakeLists.txt +++ b/exporters/memory/CMakeLists.txt @@ -17,8 +17,12 @@ if(BUILD_TESTING) in_memory_span_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_in_memory) - gtest_add_tests(TARGET in_memory_span_data_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_data_test) - gtest_add_tests(TARGET in_memory_span_exporter_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_exporter_test) + gtest_add_tests( + TARGET in_memory_span_data_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_data_test) + gtest_add_tests( + TARGET in_memory_span_exporter_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_exporter_test) endif() diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index 4818dfd5e2..b6faccf513 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -15,8 +15,12 @@ if(BUILD_TESTING) ostream_metrics_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_ostream_metrics) - gtest_add_tests(TARGET ostream_metrics_test TEST_PREFIX exporter. TEST_LIST - ostream_metrics_test) - gtest_add_tests(TARGET ostream_span_test TEST_PREFIX exporter. TEST_LIST - ostream_span_test) + gtest_add_tests( + TARGET ostream_metrics_test + TEST_PREFIX exporter. + TEST_LIST ostream_metrics_test) + gtest_add_tests( + TARGET ostream_span_test + TEST_PREFIX exporter. + TEST_LIST ostream_span_test) endif() # BUILD_TESTING diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index eebd9829ec..ccf22aa5e6 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -8,6 +8,8 @@ if(BUILD_TESTING) target_link_libraries( recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_otprotocol protobuf::libprotobuf) - gtest_add_tests(TARGET recordable_test TEST_PREFIX exporter. TEST_LIST - recordable_test) + gtest_add_tests( + TARGET recordable_test + TEST_PREFIX exporter. + TEST_LIST recordable_test) endif() # BUILD_TESTING diff --git a/exporters/prometheus/test/CMakeLists.txt b/exporters/prometheus/test/CMakeLists.txt index c57f900347..4168c6d3e4 100644 --- a/exporters/prometheus/test/CMakeLists.txt +++ b/exporters/prometheus/test/CMakeLists.txt @@ -3,6 +3,8 @@ foreach(testname prometheus_collector_test prometheus_exporter_utils_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} prometheus_exporter prometheus-cpp::pull) - gtest_add_tests(TARGET ${testname} TEST_PREFIX exporter. TEST_LIST - ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX exporter. + TEST_LIST ${testname}) endforeach() diff --git a/ext/test/zpages/CMakeLists.txt b/ext/test/zpages/CMakeLists.txt index 34c3637316..c7d0d837c8 100644 --- a/ext/test/zpages/CMakeLists.txt +++ b/ext/test/zpages/CMakeLists.txt @@ -4,5 +4,8 @@ foreach(testname tracez_processor_test tracez_data_aggregator_test target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_zpages) - gtest_add_tests(TARGET ${testname} TEST_PREFIX ext. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX ext. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/common/CMakeLists.txt b/sdk/test/common/CMakeLists.txt index 7a181c90c4..5c6ffe868c 100644 --- a/sdk/test/common/CMakeLists.txt +++ b/sdk/test/common/CMakeLists.txt @@ -5,7 +5,10 @@ foreach(testname target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common opentelemetry_trace) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() add_executable(random_fork_test random_fork_test.cc) diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index e518dbdd1e..a33ccbf64b 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -13,5 +13,8 @@ foreach( add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) - gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/trace/CMakeLists.txt b/sdk/test/trace/CMakeLists.txt index 79599495b6..747ec96f31 100644 --- a/sdk/test/trace/CMakeLists.txt +++ b/sdk/test/trace/CMakeLists.txt @@ -14,7 +14,10 @@ foreach( target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common opentelemetry_trace opentelemetry_exporter_in_memory) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() add_executable(sampler_benchmark sampler_benchmark.cc) From d171ad51d113b87f67026f2c372ba1001ad7f98e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 03:11:43 -0800 Subject: [PATCH 24/54] Add submodules to .bazelignore --- .bazelignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .bazelignore diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 0000000000..56306fc4b9 --- /dev/null +++ b/.bazelignore @@ -0,0 +1,3 @@ +third_party +tools +out From 377640ab8110f49239509dd0f4a8a73c643c2ef8 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 03:43:34 -0800 Subject: [PATCH 25/54] Try bazel clean builds to remove stale cache entries --- ci/do_ci.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 41aaa6b54f..bb13a7b0d7 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -112,33 +112,40 @@ EOF examples/plugin/load/load_plugin_example ${PLUGIN_DIR}/libexample_plugin.so /dev/null exit 0 elif [[ "$1" == "bazel.test" ]]; then + bazel clean --expunge bazel build $BAZEL_OPTIONS //... bazel test $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "bazel.legacy.test" ]]; then # we uses C++ future and async() function to test the Prometheus Exporter functionality, # that make this test always fail. ignore Prometheus exporter here. + bazel clean --expunge bazel build $BAZEL_OPTIONS -- //... -//exporters/otlp/... -//exporters/prometheus/... bazel test $BAZEL_TEST_OPTIONS -- //... -//exporters/otlp/... -//exporters/prometheus/... exit 0 elif [[ "$1" == "bazel.noexcept" ]]; then # there are some exceptions and error handling code from the Prometheus Client # that make this test always fail. ignore Prometheus exporter in the noexcept here. + bazel clean --expunge bazel build --copt=-fno-exceptions $BAZEL_OPTIONS -- //... -//exporters/prometheus/... bazel test --copt=-fno-exceptions $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... exit 0 elif [[ "$1" == "bazel.asan" ]]; then + bazel clean --expunge bazel test --config=asan $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "bazel.tsan" ]]; then + bazel clean --expunge bazel test --config=tsan $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "bazel.valgrind" ]]; then + bazel clean --expunge bazel build $BAZEL_OPTIONS //... bazel test --run_under="/usr/bin/valgrind --leak-check=full --error-exitcode=1 --suppressions=\"${SRC_DIR}/ci/valgrind-suppressions\"" $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "benchmark" ]]; then [ -z "${BENCHMARK_DIR}" ] && export BENCHMARK_DIR=$HOME/benchmark + bazel clean --expunge bazel build $BAZEL_OPTIONS -c opt -- \ $(bazel query 'attr("tags", "benchmark_result", ...)') echo "" From 03ff3c7844d5cac77e26b638cd7cc6ade9ce161d Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 18:29:01 -0800 Subject: [PATCH 26/54] Trying to fix the Bazel build failure by recursively cloning with submodules --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++++++++++ ci/do_ci.sh | 7 ------- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb2bb26841..1cb79c1806 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -26,6 +28,8 @@ jobs: runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_ci_environment.sh @@ -44,6 +48,8 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_ci_environment.sh @@ -56,6 +62,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -68,6 +76,8 @@ jobs: runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_ci_environment.sh @@ -83,6 +93,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -96,6 +108,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -109,6 +123,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -122,6 +138,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -135,6 +153,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -148,6 +168,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -168,6 +190,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: sudo ./ci/install_format_tools.sh - name: run tests @@ -178,6 +202,8 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: run tests run: ./ci/do_ci.sh bazel.test @@ -186,6 +212,8 @@ jobs: runs-on: windows-2019 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | ./ci/setup_windows_cmake.ps1 @@ -201,6 +229,8 @@ jobs: runs-on: windows-2019 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: ./ci/install_windows_bazelisk.ps1 - name: run tests @@ -211,6 +241,8 @@ jobs: runs-on: windows-2019 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | ./ci/setup_windows_cmake.ps1 @@ -223,6 +255,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -239,6 +273,8 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: install docfx run: choco install docfx -y - name: run ./ci/docfx.cmd diff --git a/ci/do_ci.sh b/ci/do_ci.sh index bb13a7b0d7..41aaa6b54f 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -112,40 +112,33 @@ EOF examples/plugin/load/load_plugin_example ${PLUGIN_DIR}/libexample_plugin.so /dev/null exit 0 elif [[ "$1" == "bazel.test" ]]; then - bazel clean --expunge bazel build $BAZEL_OPTIONS //... bazel test $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "bazel.legacy.test" ]]; then # we uses C++ future and async() function to test the Prometheus Exporter functionality, # that make this test always fail. ignore Prometheus exporter here. - bazel clean --expunge bazel build $BAZEL_OPTIONS -- //... -//exporters/otlp/... -//exporters/prometheus/... bazel test $BAZEL_TEST_OPTIONS -- //... -//exporters/otlp/... -//exporters/prometheus/... exit 0 elif [[ "$1" == "bazel.noexcept" ]]; then # there are some exceptions and error handling code from the Prometheus Client # that make this test always fail. ignore Prometheus exporter in the noexcept here. - bazel clean --expunge bazel build --copt=-fno-exceptions $BAZEL_OPTIONS -- //... -//exporters/prometheus/... bazel test --copt=-fno-exceptions $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... exit 0 elif [[ "$1" == "bazel.asan" ]]; then - bazel clean --expunge bazel test --config=asan $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "bazel.tsan" ]]; then - bazel clean --expunge bazel test --config=tsan $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "bazel.valgrind" ]]; then - bazel clean --expunge bazel build $BAZEL_OPTIONS //... bazel test --run_under="/usr/bin/valgrind --leak-check=full --error-exitcode=1 --suppressions=\"${SRC_DIR}/ci/valgrind-suppressions\"" $BAZEL_TEST_OPTIONS //... exit 0 elif [[ "$1" == "benchmark" ]]; then [ -z "${BENCHMARK_DIR}" ] && export BENCHMARK_DIR=$HOME/benchmark - bazel clean --expunge bazel build $BAZEL_OPTIONS -c opt -- \ $(bazel query 'attr("tags", "benchmark_result", ...)') echo "" From 220db8c1ede98cd43037ad239c2ec707feb9df38 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 18:35:06 -0800 Subject: [PATCH 27/54] Don't clone submodules for DocFX and code format runs --- .github/workflows/ci.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cb79c1806..bced659610 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,8 +190,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - with: - submodules: 'true' - name: setup run: sudo ./ci/install_format_tools.sh - name: run tests @@ -273,8 +271,6 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 - with: - submodules: 'true' - name: install docfx run: choco install docfx -y - name: run ./ci/docfx.cmd From 72f1c11d896ec2ab522b7802070cadb42342de98 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 20:46:42 -0800 Subject: [PATCH 28/54] No need to clone it anymore: it's now there in the build tree as submodule --- ci/do_ci.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 41aaa6b54f..8b0a7a397d 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -56,12 +56,7 @@ elif [[ "$1" == "cmake.exporter.prometheus.test" ]]; then # apt-get install sudo # apt-get install zlib1g-dev # apt-get -y install libcurl4-openssl-dev - cd third_party - git clone https://github.com/jupp0r/prometheus-cpp - cd prometheus-cpp - git checkout v0.9.0 - git submodule init - git submodule update + cd third_party/prometheus-cpp mkdir _build && cd _build cmake .. -DBUILD_SHARED_LIBS=ON make -j 4 From 9c2c6070a8eb8f8379ee059afa48ca1c9b8303c6 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 20:47:34 -0800 Subject: [PATCH 29/54] Submit submodule updated to latest version v0.10.0 --- third_party/prometheus-cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/prometheus-cpp b/third_party/prometheus-cpp index 27c3d670c6..62897f9e79 160000 --- a/third_party/prometheus-cpp +++ b/third_party/prometheus-cpp @@ -1 +1 @@ -Subproject commit 27c3d670c66985c0096d378cdd780088b08bc8f4 +Subproject commit 62897f9e794e9f16471e8a53f367268109e7fa6e From 177a3cf55888d69570512c69cac95ecde21ee2e0 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 20:59:34 -0800 Subject: [PATCH 30/54] Fix formatting issue after rebase --- sdk/test/logs/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/test/logs/CMakeLists.txt b/sdk/test/logs/CMakeLists.txt index 87f7ae9a96..c1342a16b9 100644 --- a/sdk/test/logs/CMakeLists.txt +++ b/sdk/test/logs/CMakeLists.txt @@ -2,5 +2,8 @@ foreach(testname logger_provider_sdk_test logger_sdk_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_logs) - gtest_add_tests(TARGET ${testname} TEST_PREFIX logs. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX logs. + TEST_LIST ${testname}) endforeach() From 53a94f83f7dd9105965ddcb18192c918817b9d16 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 21:09:29 -0800 Subject: [PATCH 31/54] nit: formatting --- .gitmodules | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index e84b068aa3..3a93fdf0e0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "third_party/prometheus-cpp"] path = third_party/prometheus-cpp url = https://github.com/jupp0r/prometheus-cpp - branch = master + branch = master [submodule "tools/vcpkg"] path = tools/vcpkg @@ -16,14 +16,14 @@ [submodule "third_party/googletest"] path = third_party/googletest url = https://github.com/google/googletest - branch = master + branch = master [submodule "third_party/benchmark"] path = third_party/benchmark url = https://github.com/google/benchmark - branch = master + branch = master [submodule "third_party/opentelemetry-proto"] path = third_party/opentelemetry-proto url = https://github.com/open-telemetry/opentelemetry-proto - branch = master + branch = master From 6ccac730178fd8fb318208a4ffc1bd4bb7653a0f Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 21:10:04 -0800 Subject: [PATCH 32/54] Previous prometheus-cpp had a bug, update to latest --- third_party/prometheus-cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/prometheus-cpp b/third_party/prometheus-cpp index 62897f9e79..27c3d670c6 160000 --- a/third_party/prometheus-cpp +++ b/third_party/prometheus-cpp @@ -1 +1 @@ -Subproject commit 62897f9e794e9f16471e8a53f367268109e7fa6e +Subproject commit 27c3d670c66985c0096d378cdd780088b08bc8f4 From 7a8f2ebb6fee976d1fea31820d05569531049b0d Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 21:38:07 -0800 Subject: [PATCH 33/54] Trying to fix a quirk with prometheus exporter build (shot in the dark coz my local build is fine... sigh) --- ci/do_ci.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 8b0a7a397d..4aafbbb489 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -57,8 +57,10 @@ elif [[ "$1" == "cmake.exporter.prometheus.test" ]]; then # apt-get install zlib1g-dev # apt-get -y install libcurl4-openssl-dev cd third_party/prometheus-cpp + git submodule update --recursive + [[ -d _build ]] && rm -rf ./_build mkdir _build && cd _build - cmake .. -DBUILD_SHARED_LIBS=ON + cmake .. -DBUILD_SHARED_LIBS=ON -DUSE_THIRDPARTY_LIBRARIES=ON make -j 4 sudo make install From 16cbf59b4e0cf25f3a9e2afb8a607d562114f2cb Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 16 Nov 2020 21:56:44 -0800 Subject: [PATCH 34/54] Recursively init just this module instead of full set from the top --- ci/do_ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 4aafbbb489..48b797704f 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -57,7 +57,7 @@ elif [[ "$1" == "cmake.exporter.prometheus.test" ]]; then # apt-get install zlib1g-dev # apt-get -y install libcurl4-openssl-dev cd third_party/prometheus-cpp - git submodule update --recursive + git submodule update --recursive --init [[ -d _build ]] && rm -rf ./_build mkdir _build && cd _build cmake .. -DBUILD_SHARED_LIBS=ON -DUSE_THIRDPARTY_LIBRARIES=ON From 6e92bef13cbe5052a81c6eb90c3a69b8e5a84719 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 16:38:25 -0800 Subject: [PATCH 35/54] Allow OTLP to process const char * strings --- exporters/otlp/src/recordable.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index a48f6a95f8..f15a521463 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -6,7 +6,7 @@ namespace exporter namespace otlp { -const int kAttributeValueSize = 14; +const int kAttributeValueSize = 15; void Recordable::SetIds(trace::TraceId trace_id, trace::SpanId span_id, @@ -59,6 +59,10 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, attribute->mutable_value()->set_string_value(nostd::get(value).data(), nostd::get(value).size()); } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_string_value(nostd::get(value)); + } else if (nostd::holds_alternative>(value)) { for (const auto &val : nostd::get>(value)) From e1757eafac37a3b8d2b06626299acec7ab8e7b07 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 16:38:45 -0800 Subject: [PATCH 36/54] Add missing headers --- api/include/opentelemetry/logs/log_record.h | 1 + api/include/opentelemetry/logs/logger.h | 1 + 2 files changed, 2 insertions(+) diff --git a/api/include/opentelemetry/logs/log_record.h b/api/include/opentelemetry/logs/log_record.h index c663c1c9c7..684583bf4a 100644 --- a/api/include/opentelemetry/logs/log_record.h +++ b/api/include/opentelemetry/logs/log_record.h @@ -22,6 +22,7 @@ #include "opentelemetry/core/timestamp.h" #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" #include "opentelemetry/trace/span_id.h" #include "opentelemetry/trace/trace_flags.h" #include "opentelemetry/trace/trace_id.h" diff --git a/api/include/opentelemetry/logs/logger.h b/api/include/opentelemetry/logs/logger.h index 5f22066460..0040d4f32b 100644 --- a/api/include/opentelemetry/logs/logger.h +++ b/api/include/opentelemetry/logs/logger.h @@ -25,6 +25,7 @@ #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/span.h" #include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE From 15ce22ff66b0092776b7e510dc527085420329fb Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 16:39:17 -0800 Subject: [PATCH 37/54] Use #ifdef instead of #if for unsupported feature that may be needed for non-OTLP exporter --- api/include/opentelemetry/common/attribute_value.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/include/opentelemetry/common/attribute_value.h b/api/include/opentelemetry/common/attribute_value.h index 3df800e187..2d9eb9761d 100644 --- a/api/include/opentelemetry/common/attribute_value.h +++ b/api/include/opentelemetry/common/attribute_value.h @@ -42,8 +42,8 @@ enum AttributeType TYPE_DOUBLE, TYPE_STRING, TYPE_CSTRING, -#if HAVE_SPAN_BYTE - TYPE_SPAN_BYTE, +#ifdef HAVE_SPAN_BYTE + TYPE_SPAN_BYTE, // TODO: not part of OT spec yet #endif TYPE_SPAN_BOOL, TYPE_SPAN_INT, From 5f369d3f8d24b8214a311d0776c5525fe8ad040e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 17:45:45 -0800 Subject: [PATCH 38/54] Partial merge of tools --- .bazelignore | 3 + .gitattributes | 7 +- .github/workflows/ci.yml | 78 ++---- CMakeLists.txt | 73 +++++- WORKSPACE | 2 +- .../common/key_value_iterable_view.h | 1 + api/test/logs/CMakeLists.txt | 5 +- ci/do_ci.sh | 11 +- ci/install_format_tools.sh | 2 +- exporters/memory/CMakeLists.txt | 12 +- exporters/otlp/CMakeLists.txt | 9 +- exporters/prometheus/test/CMakeLists.txt | 6 +- ext/test/zpages/CMakeLists.txt | 5 +- sdk/src/trace/tracer_provider.cc | 6 +- sdk/test/logs/CMakeLists.txt | 5 +- tools/WORKSPACE | 4 + tools/build-all.sh | 6 - tools/build-benchmark.sh | 26 ++ tools/build-docker.cmd | 69 +++++ tools/build-gtest.sh | 47 ++-- tools/build-vcpkg.sh | 24 ++ tools/build-vs2015.cmd | 9 +- tools/build-vs2017.cmd | 7 +- tools/build-vs2019.cmd | 10 + tools/build.cmd | 20 +- tools/build.sh | 242 +++++++++++++----- tools/install.sh | 13 + tools/setup-buildtools-mac.sh | 2 +- tools/setup-buildtools.cmd | 35 +-- tools/setup-buildtools.sh | 26 +- tools/setup-cmake.sh | 58 +++++ tools/setup-ninja.sh | 3 + tools/setup-protobuf.sh | 6 + 33 files changed, 599 insertions(+), 233 deletions(-) create mode 100644 .bazelignore create mode 100644 tools/WORKSPACE delete mode 100755 tools/build-all.sh create mode 100644 tools/build-benchmark.sh create mode 100644 tools/build-docker.cmd create mode 100644 tools/build-vcpkg.sh create mode 100644 tools/install.sh create mode 100644 tools/setup-cmake.sh create mode 100644 tools/setup-ninja.sh create mode 100644 tools/setup-protobuf.sh diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 0000000000..cb65fb06de --- /dev/null +++ b/.bazelignore @@ -0,0 +1,3 @@ +third_party +tools +out diff --git a/.gitattributes b/.gitattributes index c1c540735f..ca13be9c45 100644 --- a/.gitattributes +++ b/.gitattributes @@ -37,6 +37,7 @@ LICENSE* text *.pdf binary *.rtf binary -## Self-reference =) -.gitignore text -.gitattributes text +## git files +.gitignore text eol=lf +.gitattributes text eol=lf +.gitattributes text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f8cd06a70..d4774fa84d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,66 +57,6 @@ jobs: - name: run tests run: ./ci/do_ci.sh cmake.c++20.test - cmake_posix: - name: Build on ${{ matrix.os }} ${{ matrix.config }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - config: [release] - os: [ubuntu-18.04, ubuntu-20.04, macos-latest] - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: build - run: tools/build.sh ${{ matrix.config }} - - # TODO #1: add vs2015 - # TODO #2: consolidate cmake_[vs2015|vs2017|vs2019] into one matrix build - cmake_windows_vs2017: - name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - arch: [x64] - config: [release] - os: [windows-2016] - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: Setup build tools - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\setup-buildtools.cmd - - name: Build - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\build-vs2017.cmd ${{ matrix.config }} - - cmake_windows_vs2019: - name: Build on Windows ${{ matrix.arch }}-${{ matrix.config }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - arch: [x64] - config: [release] - os: [windows-2019] - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: Setup build tools - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\setup-buildtools.cmd - - name: Build - run: | - cd "$Env:GITHUB_WORKSPACE" - .\tools\build-vs2017.cmd ${{ matrix.config }} - plugin_test: name: Plugin -> CMake runs-on: ubuntu-latest @@ -136,6 +76,8 @@ jobs: runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_ci_environment.sh @@ -151,6 +93,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -164,6 +108,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -177,6 +123,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -190,6 +138,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -203,6 +153,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -216,6 +168,8 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: run tests run: ./ci/do_ci.sh bazel.test @@ -273,6 +227,8 @@ jobs: runs-on: windows-2019 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: ./ci/install_windows_bazelisk.ps1 - name: run tests @@ -297,6 +253,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: setup run: | sudo ./ci/setup_cmake.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dd0de71a9..30ec2c2f8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,20 +60,23 @@ option(WITH_OTLP "Whether to include the OpenTelemetry Protocol in the SDK" OFF) option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK" OFF) -option(WITH_TESTS "Whether to enable tests" ON) +option(BUILD_TESTING "Whether to enable tests" ON) option(WITH_EXAMPLES "Whether to build examples" ON) set(WITH_PROTOBUF OFF) -if(WITH_OTLP) - set(WITH_PROTOBUF ON) -endif() - -if(WITH_TESTS) - include(CTest) -endif() find_package(Threads) +function(install_windows_deps) + # Bootstrap vcpkg from CMake and auto-install deps in case if we are missing + # deps on Windows + message("Installing build tools and dependencies...") + execute_process( + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-buildtools.cmd) + set(CMAKE_TOOLCHAIN_FILE + ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake) +endfunction() + if(MSVC) # Options for Visual C++ compiler: /Zc:__cplusplus - report an updated value # for recent C++ language standards. Without this option MSVC returns the @@ -81,23 +84,67 @@ if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus") endif() +if(WITH_OTLP) + set(WITH_PROTOBUF ON) +endif() + if(WITH_PROTOBUF) set(protobuf_MODULE_COMPATIBLE ON) - find_package(Protobuf CONFIG NAMES protobuf) - # Older versions of protobuf don't use cmake config files. + find_package(Protobuf REQUIRED) if(NOT protobuf_FOUND) + if(WIN32) + install_windows_deps() + endif() find_package(Protobuf REQUIRED) + if(WIN32) + # Always use x64 protoc.exe + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + set(Protobuf_PROTOC_EXECUTABLE + ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/packages/protobuf_x64-windows/tools/protobuf/protoc.exe + ) + endif() + endif() + # Latest Protobuf uses mixed case instead of uppercase + set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE}) endif() + message("PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}") endif() if(WITH_OTLP) - include(third_party/opentelemetry-proto/Protobuf.cmake) + include(cmake/opentelemetry-proto.cmake) endif() +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") + if(BUILD_TESTING) - find_package(GTest REQUIRED) - find_package(benchmark REQUIRED) + include(CTest) + if(EXISTS ${CMAKE_BINARY_DIR}/lib/libgtest.a) + # Prefer GTest from build tree. GTest is not always working with + # CMAKE_PREFIX_PATH + set(GTEST_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include) + set(GTEST_BOTH_LIBRARIES + ${CMAKE_BINARY_DIR}/lib/libgtest.a + ${CMAKE_BINARY_DIR}/lib/libgtest_main.a + ${CMAKE_BINARY_DIR}/lib/libgmock.a) + elseif(WIN32) + # Make sure we are always bootsrapped with vcpkg on Windows + find_package(GTest) + if(NOT GTEST_FOUND) + install_windows_deps() + find_package(GTest REQUIRED) + endif() + else() + # Prefer GTest installed by OS distro, brew or vcpkg package manager + find_package(GTest REQUIRED) + endif() include_directories(SYSTEM ${GTEST_INCLUDE_DIRS}) + message("GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}") + message("GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}") + enable_testing() + # Benchmark respects the CMAKE_PREFIX_PATH + find_package(benchmark CONFIG REQUIRED) endif() include_directories(api/include) diff --git a/WORKSPACE b/WORKSPACE index ef2c9611be..de4ec2a48b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -82,7 +82,7 @@ http_archive( http_archive( name = "github_nlohmann_json", - build_file = "//third_party/json:nlohmann_json.BUILD", + build_file = "//bazel:nlohmann_json.BUILD", sha256 = "69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf", urls = [ "https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip", diff --git a/api/include/opentelemetry/common/key_value_iterable_view.h b/api/include/opentelemetry/common/key_value_iterable_view.h index 6aa300d933..a9b61cd87b 100644 --- a/api/include/opentelemetry/common/key_value_iterable_view.h +++ b/api/include/opentelemetry/common/key_value_iterable_view.h @@ -33,6 +33,7 @@ struct is_key_value_iterable template class KeyValueIterableView final : public KeyValueIterable { + static_assert(detail::is_key_value_iterable::value, "Must be a key-value iterable"); public: explicit KeyValueIterableView(const T &container) noexcept : container_{&container} {} diff --git a/api/test/logs/CMakeLists.txt b/api/test/logs/CMakeLists.txt index 737edb893c..9b1b3b0e7d 100644 --- a/api/test/logs/CMakeLists.txt +++ b/api/test/logs/CMakeLists.txt @@ -2,5 +2,8 @@ foreach(testname logger_provider_test logger_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX logs. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX logs. + TEST_LIST ${testname}) endforeach() diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 41aaa6b54f..48b797704f 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -56,14 +56,11 @@ elif [[ "$1" == "cmake.exporter.prometheus.test" ]]; then # apt-get install sudo # apt-get install zlib1g-dev # apt-get -y install libcurl4-openssl-dev - cd third_party - git clone https://github.com/jupp0r/prometheus-cpp - cd prometheus-cpp - git checkout v0.9.0 - git submodule init - git submodule update + cd third_party/prometheus-cpp + git submodule update --recursive --init + [[ -d _build ]] && rm -rf ./_build mkdir _build && cd _build - cmake .. -DBUILD_SHARED_LIBS=ON + cmake .. -DBUILD_SHARED_LIBS=ON -DUSE_THIRDPARTY_LIBRARIES=ON make -j 4 sudo make install diff --git a/ci/install_format_tools.sh b/ci/install_format_tools.sh index c589250168..f65c8ff7a2 100755 --- a/ci/install_format_tools.sh +++ b/ci/install_format_tools.sh @@ -3,6 +3,6 @@ set -e apt install -y clang-format-8 python3-pip git curl -pip3 install cmake_format==0.6.5 +pip3 install cmake_format==0.6.13 curl -L -o /usr/local/bin/buildifier https://github.com/bazelbuild/buildtools/releases/download/2.2.1/buildifier chmod +x /usr/local/bin/buildifier diff --git a/exporters/memory/CMakeLists.txt b/exporters/memory/CMakeLists.txt index aa8d334bd0..2739596fd5 100644 --- a/exporters/memory/CMakeLists.txt +++ b/exporters/memory/CMakeLists.txt @@ -17,8 +17,12 @@ if(BUILD_TESTING) in_memory_span_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_in_memory) - gtest_add_tests(TARGET in_memory_span_data_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_data_test) - gtest_add_tests(TARGET in_memory_span_exporter_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_exporter_test) + gtest_add_tests( + TARGET in_memory_span_data_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_data_test) + gtest_add_tests( + TARGET in_memory_span_exporter_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_exporter_test) endif() diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 27ee7de956..ccf22aa5e6 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -1,14 +1,15 @@ include_directories(include) add_library(opentelemetry_exporter_otprotocol src/recordable.cc) -target_link_libraries(opentelemetry_exporter_otprotocol - $) +target_link_libraries(opentelemetry_exporter_otprotocol opentelemetry_proto) if(BUILD_TESTING) add_executable(recordable_test test/recordable_test.cc) target_link_libraries( recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_otprotocol protobuf::libprotobuf) - gtest_add_tests(TARGET recordable_test TEST_PREFIX exporter. TEST_LIST - recordable_test) + gtest_add_tests( + TARGET recordable_test + TEST_PREFIX exporter. + TEST_LIST recordable_test) endif() # BUILD_TESTING diff --git a/exporters/prometheus/test/CMakeLists.txt b/exporters/prometheus/test/CMakeLists.txt index c57f900347..4168c6d3e4 100644 --- a/exporters/prometheus/test/CMakeLists.txt +++ b/exporters/prometheus/test/CMakeLists.txt @@ -3,6 +3,8 @@ foreach(testname prometheus_collector_test prometheus_exporter_utils_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} prometheus_exporter prometheus-cpp::pull) - gtest_add_tests(TARGET ${testname} TEST_PREFIX exporter. TEST_LIST - ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX exporter. + TEST_LIST ${testname}) endforeach() diff --git a/ext/test/zpages/CMakeLists.txt b/ext/test/zpages/CMakeLists.txt index 34c3637316..c7d0d837c8 100644 --- a/ext/test/zpages/CMakeLists.txt +++ b/ext/test/zpages/CMakeLists.txt @@ -4,5 +4,8 @@ foreach(testname tracez_processor_test tracez_data_aggregator_test target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_zpages) - gtest_add_tests(TARGET ${testname} TEST_PREFIX ext. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX ext. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index e2dd5f69e0..af929ee1eb 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -14,8 +14,12 @@ opentelemetry::nostd::shared_ptr TracerProvider::G nostd::string_view library_name, nostd::string_view library_version) noexcept { - // TODO: do we have to transform this at all, if we can keep it nostd::shared_ptr at source? +#if 0 + // TODO: do we have to cast/transform this or can we keep as nostd::shared_ptr<...> ? + return opentelemetry::nostd::shared_ptr(tracer_); +#endif return tracer_; +#endif } void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept diff --git a/sdk/test/logs/CMakeLists.txt b/sdk/test/logs/CMakeLists.txt index 87f7ae9a96..c1342a16b9 100644 --- a/sdk/test/logs/CMakeLists.txt +++ b/sdk/test/logs/CMakeLists.txt @@ -2,5 +2,8 @@ foreach(testname logger_provider_sdk_test logger_sdk_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_logs) - gtest_add_tests(TARGET ${testname} TEST_PREFIX logs. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX logs. + TEST_LIST ${testname}) endforeach() diff --git a/tools/WORKSPACE b/tools/WORKSPACE new file mode 100644 index 0000000000..abebe189fa --- /dev/null +++ b/tools/WORKSPACE @@ -0,0 +1,4 @@ +local_repository( + name = "vcpkg", + path = "./vcpkg", +) diff --git a/tools/build-all.sh b/tools/build-all.sh deleted file mode 100755 index 8ebedd8983..0000000000 --- a/tools/build-all.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -cd .. -mkdir -p out -cd out -cmake .. -make diff --git a/tools/build-benchmark.sh b/tools/build-benchmark.sh new file mode 100644 index 0000000000..58d92dc860 --- /dev/null +++ b/tools/build-benchmark.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +pushd $WORKSPACE_ROOT + +BUILD_ROOT=${BUILD_ROOT:-/tmp/build} +[[ ! -d "${BUILD_ROOT}" ]] && mkdir -p "${BUILD_ROOT}" || echo "Output directory already exists: BUILD_ROOT=${BUILD_ROOT}" + +BENCHMARK_BUILD_ROOT=${BUILD_ROOT}/benchmark +[[ ! -d "${BENCHMARK_BUILD_ROOT}" ]] && mkdir -p "${BENCHMARK_BUILD_ROOT}" || echo "Output directory already exists: BENCHMARK_BUILD_ROOT=${BENCHMARK_BUILD_ROOT}" + +# Build Google Benchmark with given Google Test +export BENCHMARK_SRC_PATH=${WORKSPACE_ROOT}/third_party/benchmark +if [ ! -d "${BENCHMARK_SRC_PATH}" ]; then + echo "Google Benchmark not found!" + exit 1 +fi + +pushd ${BENCHMARK_BUILD_ROOT} +cmake $BENCHMARK_SRC_PATH -DBENCHMARK_ENABLE_TESTING=OFF -DCMAKE_INSTALL_PREFIX=$BUILD_ROOT +make install +popd + +popd diff --git a/tools/build-docker.cmd b/tools/build-docker.cmd new file mode 100644 index 0000000000..eebdcf98c7 --- /dev/null +++ b/tools/build-docker.cmd @@ -0,0 +1,69 @@ +@echo off +pushd %~dp0 +REM Default arguments +set A1="/build/tools/build.sh" +set A2=clean +if "%~1"=="" goto help + +REM Image name is always the first argument +set IMAGE_NAME=%1 + +REM Process other optional arguments +shift +if NOT "%1"=="" ( + set A1=%1 + set A2=%2 + set A3=%3 + set A4=%4 + set A5=%5 + set A6=%6 + set A7=%7 + set A8=%8 + set A9=%9 + set A10=%10 +) + +WHERE choco >NUL 2>NUL +if %ERRORLEVEL% NEQ 0 ( + echo This script requires Chocolatey to install Docker: https://chocolatey.org/ +) + +WHERE docker >NUL 2>NUL +if "%ERRORLEVEL%"=="0" goto docker_ok +choco install -y docker-desktop +choco install -y docker-cli +:docker_ok + +docker info +docker version + +echo Running in container %IMAGE_NAME% +sc query com.docker.service + +REM Force reinstallation of build tools +del ..\.buildtools 2>NUL +echo Building docker image in %CD%... +copy /Y setup-cmake.sh ..\docker\%IMAGE_NAME%\ +copy /Y setup-protobuf.sh ..\docker\%IMAGE_NAME%\ +docker build --rm -t %IMAGE_NAME% ../docker/%IMAGE_NAME% + +cd .. +echo Starting build... +docker run -it -v %CD%:/build %IMAGE_NAME% %A1% %A2% + +popd +exit + +:help +cd .. +echo. +echo Usage: build-docker.cmd [image_name] [arguments...] +echo. +echo Default command: +echo. +echo docker run -it -v $WORKSPACE_ROOT:/build IMAGE_NAME %A1% %A2% +echo. +echo Supported images: +echo ================= +dir /B docker +popd diff --git a/tools/build-gtest.sh b/tools/build-gtest.sh index d2573b885a..e7e786ac48 100755 --- a/tools/build-gtest.sh +++ b/tools/build-gtest.sh @@ -1,28 +1,37 @@ #!/usr/bin/env bash -if [ "$1" == "ios" ]; then - IOS_BUILD="YES" - # Skip building tests on iOS as there is no way to run them - BUILD_TESTS="OFF" -else - IOS_BUILD="NO" - BUILD_TESTS="ON" + +# Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +pushd $WORKSPACE_ROOT + +BUILD_ROOT=${BUILD_ROOT:-/tmp/build} +[[ ! -d "${BUILD_ROOT}" ]] && mkdir -p "${BUILD_ROOT}" || echo "Output directory already exists: BUILD_ROOT=${BUILD_ROOT}" + +GTEST_BUILD_ROOT=${BUILD_ROOT}/gtest +[[ ! -d "${GTEST_BUILD_ROOT}" ]] && mkdir -p "${GTEST_BUILD_ROOT}" || echo "Output directory already exists: GTEST_BUILD_ROOT=${GTEST_BUILD_ROOT}" + +# Path to Google Test source. Prefer Google Test from submodule if available: +export GTEST_SRC_PATH=${WORKSPACE_ROOT}/third_party/googletest +if [ ! -d "${GTEST_SRC_PATH}" ]; then + # If not available, then use Google Test that is installed by OS package: + export GTEST_SRC_PATH=/usr/src/gtest + if [ ! -d "${GTEST_SRC_PATH}" ]; then + echo "GTest not found!" + exit 1 + fi + echo Building GTest from source: ${GTEST_SRC_PATH} ... fi -pushd `dirname $0`/.. -cd third_party/googletest -set -evx -env | sort -rm -rf build -mkdir -p build || true -cd build +pushd $GTEST_BUILD_ROOT cmake -Dgtest_build_samples=OFF \ -Dgmock_build_samples=OFF \ -Dgtest_build_tests=OFF \ -Dgmock_build_tests=OFF \ - -DCMAKE_CXX_FLAGS="-fPIC $CXX_FLAGS" \ - -DBUILD_IOS=$IOS_BUILD \ - -DCMAKE_CXX_STANDARD=17 \ - .. -make + -DCMAKE_CXX_FLAGS="-fPIC $CXX_FLAGS -Wno-return-type" \ + -DCMAKE_INSTALL_PREFIX=$BUILD_ROOT \ + "${GTEST_SRC_PATH}" make install popd + +popd diff --git a/tools/build-vcpkg.sh b/tools/build-vcpkg.sh new file mode 100644 index 0000000000..f7fb829ce2 --- /dev/null +++ b/tools/build-vcpkg.sh @@ -0,0 +1,24 @@ +#!/bin/bash +export PATH=/usr/local/bin:$PATH +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. + +export VCPKG_ROOT=$WORKSPACE_ROOT/tools/vcpkg +export PATH=$VCPKG_ROOT:$PATH + +if [[ ! -f $DIR/vcpkg/vcpkg ]] ; then + pushd $DIR/vcpkg + ./bootstrap-vcpkg.sh + popd +fi + +vcpkg install gtest +vcpkg install benchmark +vcpkg install ms-gsl +vcpkg install nlohmann-json +vcpkg install abseil +vcpkg install protobuf + +cd $WORKSPACE_ROOT +export USE_VCPKG=1 +./tools/build.sh ${1-nostd} ${2--DCMAKE_TOOLCHAIN_FILE=$WORKSPACE_ROOT/tools/vcpkg/scripts/buildsystems/vcpkg.cmake} diff --git a/tools/build-vs2015.cmd b/tools/build-vs2015.cmd index a80ca66409..30bb41c3c9 100644 --- a/tools/build-vs2015.cmd +++ b/tools/build-vs2015.cmd @@ -1,6 +1,11 @@ +REM Build with Visual Studio 2015 set "VS_TOOLS_VERSION=vs2015" -REM Ref. https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2014%202015.html -set "CMAKE_GEN=Visual Studio 14 2015 Win64" +set ARCH=Win64 +if NOT "%1"=="" ( + set ARCH=%1 +) +set "CMAKE_GEN=Visual Studio 14 2015 %ARCH%" cd %~dp0 call setup-buildtools.cmd +REM TODO: currently we cannot build without Abseil variant for Visual Studio 2015 call build.cmd -DWITH_ABSEIL:BOOL=ON diff --git a/tools/build-vs2017.cmd b/tools/build-vs2017.cmd index be4322892c..de84593123 100644 --- a/tools/build-vs2017.cmd +++ b/tools/build-vs2017.cmd @@ -1,5 +1,10 @@ +REM Build with Visual Studio 2017 set "VS_TOOLS_VERSION=vs2017" -set "CMAKE_GEN=Visual Studio 15 2017 Win64" +set ARCH=Win64 +if NOT "%1"=="" ( + set ARCH=%1 +) +set "CMAKE_GEN=Visual Studio 15 2017 %ARCH%" cd %~dp0 call setup-buildtools.cmd call build.cmd diff --git a/tools/build-vs2019.cmd b/tools/build-vs2019.cmd index 554c291a31..b4a39938a3 100644 --- a/tools/build-vs2019.cmd +++ b/tools/build-vs2019.cmd @@ -1,4 +1,14 @@ +REM Build with Visual Studio 2017 set "VS_TOOLS_VERSION=vs2019" +set ARCH=Win64 +if NOT "%1"=="" ( + set ARCH=%1 +) +if "%ARCH%"=="Win64" ( + REM Parameter needed for CMake Visual Studio 2019 generator + set CMAKE_ARCH=x64 +) + set "CMAKE_GEN=Visual Studio 16 2019" cd %~dp0 call setup-buildtools.cmd diff --git a/tools/build.cmd b/tools/build.cmd index e49bc14289..55cc8d6c8f 100644 --- a/tools/build.cmd +++ b/tools/build.cmd @@ -21,6 +21,10 @@ setlocal enableextensions setlocal enabledelayedexpansion set "ROOT=%~dp0\.." +if ("%CMAKE_ARCH%"=="") ( + set CMAKE_ARCH=x64 +) + REM Use preinstalled vcpkg if installed or use our local if "%VCPKG_INSTALLATION_ROOT%" neq "" ( set "VCPKG_CMAKE=%VCPKG_INSTALLATION_ROOT%\scripts\buildsystems\vcpkg.cmake" @@ -33,7 +37,6 @@ REM Setup compiler environment REM ******************************************************************** call "%~dp0\vcvars.cmd" - REM ******************************************************************** REM Use cmake REM ******************************************************************** @@ -47,10 +50,10 @@ set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\nostd" call :build_config REM ******************************************************************** -REM Build with STL implementation - only for vs2017+ +REM Build with STL implementation only for vs2017+ REM ******************************************************************** if "%VS_TOOLS_VERSION%" neq "vs2015" ( - set CONFIG=-DWITH_STL:BOOL=ON + set CONFIG=-DWITH_STL:BOOL=ON %* set "OUTDIR=%ROOT%\out\%VS_TOOLS_VERSION%\stl" call :build_config ) @@ -66,9 +69,12 @@ REM ******************************************************************** REM TODO: consider rmdir for clean builds if not exist "%OUTDIR%" mkdir "%OUTDIR%" cd "%OUTDIR%" -REM Optional platform specification parameter below: -Ax64 -cmake %ROOT% -G "%CMAKE_GEN%" -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +if ("%VS_TOOLS_VERSION%"=="vs2019") ( + REM Only latest vs2019 generator supports and requires -A parameter + cmake %ROOT% -G "%CMAKE_GEN%" -A %CMAKE_ARCH% -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +) else ( + cmake %ROOT% -G "%CMAKE_GEN%" -DCMAKE_TOOLCHAIN_FILE="%VCPKG_CMAKE%" %CONFIG% +) set "SOLUTION=%OUTDIR%\opentelemetry-cpp.sln" -REM TODO: allow building [Release|Debug]x[Win32|x64|ARM|ARM64] -msbuild "%SOLUTION%" /p:Configuration=Release /p:Platform=x64 /p:VcpkgEnabled=true +msbuild "%SOLUTION%" /p:Configuration=Release /p:VcpkgEnabled=true exit /b 0 diff --git a/tools/build.sh b/tools/build.sh index aa9b5c7f7c..adce46b53c 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -1,77 +1,187 @@ #!/bin/bash - export PATH=/usr/local/bin:$PATH -DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -WORKSPACE_ROOT=$DIR/.. -cd $WORKSPACE_ROOT -echo "Current directory is `pwd`" +## +## Install all build tools and dependencies on Mac +## +function install_mac_tools { + if [ ! -f $BUILDTOOLS_FILE ] ; then + $WORKSPACE_ROOT/tools/setup-buildtools-mac.sh + echo > $BUILDTOOLS_FILE + else + echo "Build tools already installed. Skipping build tools installation." + fi +} -export NOROOT=$NOROOT +## +## Install all build tools and dependencies on Linux +## +function install_linux_tools { + if [ ! -f $BUILDTOOLS_FILE ] ; then + sudo $WORKSPACE_ROOT/tools/setup-buildtools.sh + echo > $BUILDTOOLS_FILE + else + echo "Build tools already installed. Skipping build tools installation." + fi +} -if [ "$1" == "clean" ]; then - rm -f CMakeCache.txt *.cmake - rm -rf out - rm -rf .buildtools -# make clean -fi - -if [ "$1" == "noroot" ] || [ "$2" == "noroot" ]; then -export NOROOT=true -fi - -if [ "$1" == "release" ] || [ "$2" == "release" ]; then -BUILD_TYPE="release" -else -BUILD_TYPE="debug" -fi - -# Set target MacOS minver -export MACOSX_DEPLOYMENT_TARGET=10.10 - -# Install build tools -FILE=.buildtools -OS_NAME=`uname -a` -if [ ! -f $FILE ]; then -case "$OS_NAME" in - *Darwin*) tools/setup-buildtools-mac.sh ;; - *Linux*) [[ -z "$NOROOT" ]] && sudo tools/setup-buildtools.sh || echo "No root: skipping build tools installation." ;; - *) echo "WARNING: unsupported OS $OS_NAME , skipping build tools installation.." -esac -# Assume that the build tools have been successfully installed -echo > $FILE -fi - -# TODO: fix compiler-version reporting -if [ -f /usr/bin/gcc ]; then -echo "gcc version: `gcc --version`" -COMPILER_NAME=gcc-`gcc -dumpversion` -fi - -if [ -f /usr/bin/clang ]; then -echo "clang version: `clang --version`" -COMPILER_NAME=clang-`clang -dumpversion` -fi - -# TODO: do we need to build and install Google Test? -# tools/build-gtest.sh - -# -# Do the build for both configurations: WITH_STL=OFF and WITH_STL=ON -# -function build_configuration { - BUILD_CONFIG=$1 - BUILD_OPTIONS=$2 +## +## Build dependencies +## +function build_dependencies { + # Build Google Benchmark + $WORKSPACE_ROOT/tools/build-benchmark.sh + # Build Google Test + $WORKSPACE_ROOT/tools/build-gtest.sh +} +## +## Build specific configuration for a given platform +## +function build { echo "Build configuration: $BUILD_CONFIG" cd $WORKSPACE_ROOT - OUTDIR=out/$COMPILER_NAME/$BUILD_CONFIG - mkdir -p $OUTDIR - pushd $OUTDIR - cmake $BUILD_OPTIONS $WORKSPACE_ROOT - make + + BUILD_ROOT=`pwd`/out/$PLATFORM_NAME/$BUILD_CONFIG + mkdir -p $BUILD_ROOT + if [ ! -w $BUILD_ROOT ] ; then + echo "Unable to create output directory: $BUILD_ROOT" + exit 1 + fi + + if [ -z ${USE_VCPKG} ] ; then + # TODO: consider that dependencies may also be coming from OS or brew + build_dependencies + else + echo VCPKG_ROOT=${VCPKG_ROOT} + # Prefer ninja from VCPKG if available + NINJA=$WORKSPACE_ROOT/`find tools/vcpkg -name ninja -type f -print -quit` + if [ -z ${NINJA} ] ; then + NINJA=`which ninja` + fi + fi + + # Build OpenTelemetry SDK + pushd $BUILD_ROOT + if [ -z ${NINJA} ] ; then + cmake $BUILD_OPTIONS $WORKSPACE_ROOT + make + else + cmake -G "Ninja" $BUILD_OPTIONS $WORKSPACE_ROOT + echo Building with NINJA=$NINJA + $NINJA + fi popd } -build_configuration nostd '-DWITH_STL:BOOL=OFF' -build_configuration stl '-DWITH_STL:BOOL=ON' +function runtests { + pushd $BUILD_ROOT + ctest + popd +} + +## +## Clean +## +function clean { + rm -f CMakeCache.txt *.cmake + rm -rf out + rm -rf .buildtools +# make clean +} + +## +## Detect compiler +## +function detect_compiler { + if [ -z "${CC}" ] ; then + # Compiler autodetection + if [ -z "${APPLE}" ] ; then + # Prefer gcc for non-Apple + if [ -f /usr/bin/gcc ] ; then + echo "gcc version: `gcc --version`" + PLATFORM_NAME=`gcc -dumpmachine`-gcc-`gcc -dumpversion` + fi + else + # Prefer clang on Appple platforms + if [ -f /usr/bin/clang ] ; then + echo "clang version: `clang --version`" + PLATFORM_NAME=`clang -dumpmachine`-clang-`clang -dumpversion` + fi + fi + else + # Use compiler specified by ${CC} environment variable + IFS=- read $PLATFORM_NAME $COMPILER_VERSION <<< "${CC}" + echo "CC version: `${CC} --version`" + PLATFORM_NAME=$PLATFORM_NAME-`${CC} -dumpversion` + fi + + if [ -z "${PLATFORM_NAME}" ] ; then + # Default configuration name for unknown compiler + # could be overridden by setting env var explicitly + PLATFORM_NAME=unknown-0 + fi +} + +## +## Detect Host OS, install tools and detect compiler +## +function install_tools { + + # Marker file to signal that the tools have been already installed (save build time for incremental builds) + BUILDTOOLS_FILE=`pwd`/.buildtools + + # Host OS detection + OS_NAME=`uname -a` + case "$OS_NAME" in + *Darwin*) + export APPLE=1 + # Set target MacOS minver + export MACOSX_DEPLOYMENT_TARGET=10.10 + install_mac_tools ;; + + *Linux*) + export LINUX=1 + [[ -z "$NOROOT" ]] && install_linux_tools || echo "No root. Skipping build tools installation." ;; + + *) + echo "WARNING: unsupported OS $OS_NAME. Skipping build tools installation." ;; + esac + + detect_compiler +} + +## +## Parse arguments +## +function parse_args { + # Build debug build by default + if [ "$1" == "release" ] ; then + BUILD_TYPE="release" + else + BUILD_TYPE="debug" + fi +} + +################################################################################################################ + +## Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +cd $WORKSPACE_ROOT +echo "Current directory is `pwd`" + +# Parse command line arguments +parse_args + +# Install the necessary build tools if needed +[[ -z "$NOROOT" ]] && install_tools || echo "No root: skipping build tools installation." + +# Build given configuration. Default configuration is ABI-stable 'nostd::' classes. +# Please refer to CMakeLists.txt for the list of supported build configurations. +BUILD_CONFIG=${1-nostd} + +shift +BUILD_OPTIONS="$@" +build +runtests diff --git a/tools/install.sh b/tools/install.sh new file mode 100644 index 0000000000..b034750b74 --- /dev/null +++ b/tools/install.sh @@ -0,0 +1,13 @@ +#!/bin/bash +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +WORKSPACE_ROOT=$DIR/.. +pushd $WORKSPACE_ROOT +OPENTELEMETRY_INSTALL_DIR=${1-/usr/local} +echo "Install SDK to $OPENTELEMETRY_INSTALL_DIR" +mkdir -p $OPENTELEMETRY_INSTALL_DIR/lib +# TODO: install libraries? +cp -R api/include $OPENTELEMETRY_INSTALL_DIR +cp -R sdk/include/opentelemetry/sdk $OPENTELEMETRY_INSTALL_DIR/include/opentelemetry +mkdir -p $OPENTELEMETRY_INSTALL_DIR/lib +echo dummy > $OPENTELEMETRY_INSTALL_DIR/lib/libopentelemetry.stub +popd diff --git a/tools/setup-buildtools-mac.sh b/tools/setup-buildtools-mac.sh index ee14680409..dab077976c 100755 --- a/tools/setup-buildtools-mac.sh +++ b/tools/setup-buildtools-mac.sh @@ -30,4 +30,4 @@ brew install clang-format brew install google-benchmark brew tap nlohmann/json brew install nlohmann-json -./tools/build-gtest.sh +brew install abseil diff --git a/tools/setup-buildtools.cmd b/tools/setup-buildtools.cmd index 830c650c07..25232422dd 100644 --- a/tools/setup-buildtools.cmd +++ b/tools/setup-buildtools.cmd @@ -1,12 +1,22 @@ @echo off -set "PATH=%PATH%;%~dp0;%~dp0\vcpkg" +set "PATH=C:\Program Files\CMake\bin;%~dp0;%~dp0\vcpkg;%PATH%" pushd %~dp0 -REM Fail if chocolatey is not installed -where /Q choco -if ERRORLEVEL 1 ( - echo This script requires chocolatey. Installation instructions: https://chocolatey.org/docs/installation - exit -1 +net session >nul 2>&1 +if %errorLevel% == 0 ( + echo Running with Administrative privilege... + REM Fail if chocolatey is not installed + where /Q choco + if ERRORLEVEL 1 ( + echo This script requires chocolatey. Installation instructions: https://chocolatey.org/docs/installation + exit -1 + ) + REM Install tools needed for building, but only if not installed yet + where /Q vswhere || choco install -y vswhere + where /Q cmake || choco install -y cmake + where /Q git || choco install -y git +) else ( + echo Running without Administrative privilege... ) REM Print current Visual Studio installations detected @@ -16,13 +26,6 @@ if ERRORLEVEL 0 ( vswhere -property installationPath ) -REM Install tools needed for building stuff -choco install -y cmake -choco install -y svn -choco install -y git -choco install -y llvm -choco install -y zip - REM Try to autodetect Visual Studio call "%~dp0\vcvars.cmd" if "%TOOLS_VS_NOTFOUND%" == "1" ( @@ -37,14 +40,16 @@ if ERRORLEVEL 1 ( pushd .\vcpkg call bootstrap-vcpkg.bat popd +) else ( + echo Using existing vcpkg installation... ) -REM Install it +REM Install dependencies vcpkg install gtest:x64-windows vcpkg install --head --overlay-ports=%~dp0\ports benchmark:x64-windows vcpkg install ms-gsl:x64-windows vcpkg install nlohmann-json:x64-windows vcpkg install abseil:x64-windows -vcpkg integrate install +vcpkg install protobuf:x64-windows popd exit /b 0 diff --git a/tools/setup-buildtools.sh b/tools/setup-buildtools.sh index a5fe2c5f0c..30e10fb5a5 100755 --- a/tools/setup-buildtools.sh +++ b/tools/setup-buildtools.sh @@ -1,6 +1,9 @@ -#!/bin/sh +#!/bin/bash -if [ -f /bin/yum ]; then +# Switch to workspace root directory first +DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + +if [ -f /bin/yum ] ; then # Prefer yum over apt-get yum -y install automake yum -y install autoconf @@ -22,23 +25,12 @@ yum -y install devtoolset-7-valgrind yum-config-manager --enable rhel-server-rhscl-7-rpms - -if [ `cmake --version | grep 3` == "" ]; then -yum -y remove cmake -wget https://cmake.org/files/v3.6/cmake-3.6.2.tar.gz -tar -zxvf cmake-3.6.2.tar.gz -cd cmake-3.6.2 -./bootstrap --prefix=/usr/local -make -make install -cd .. -fi - else # Use apt-get export DEBIAN_FRONTEND=noninteractive apt-get update -y apt-get install -qq automake +apt-get install -qq bc apt-get install -qq libtool-bin apt-get install -qq cmake apt-get install -qq curl @@ -52,13 +44,13 @@ apt-get install -qq libsqlite3-dev #apt install libsqlite3-dev apt-get install -qq wget apt-get install -qq clang-format -apt-get install -qq gtest apt-get install -qq libgtest-dev apt-get install -qq libbenchmark-dev apt-get install -qq nlohmann-json-dev fi +# Build and install latest CMake +$DIR/setup-cmake.sh + ## Change owner from root to current dir owner chown -R `stat . -c %u:%g` * - -./tools/build-gtest.sh diff --git a/tools/setup-cmake.sh b/tools/setup-cmake.sh new file mode 100644 index 0000000000..522b44bc65 --- /dev/null +++ b/tools/setup-cmake.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# This script installs latest CMake on Linux machine +# +export PATH=/usr/local/bin:$PATH +# Min required CMake version +export CMAKE_MIN_VERSION=${1:-3.1.0} +# Target version to install if min required is not found +export CMAKE_VERSION=${2:-3.18.4} + +UPGRADE_NEEDED=no + +function splitVersion { + pattern='([^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]' + v1=$(cut -d '.' -f 1 <<< $ver ) + v2=$(cut -d '.' -f 2 <<< $ver ) + v3=$(cut -d '.' -f 3 <<< $ver ) +} + +function checkVersion { + # Current CMake version + currVer=`cmake --version | grep version | cut -d' ' -f 3` + ver=$currVer splitVersion + cv1=$v1 + cv2=$v2 + cv3=$v3 + cv=`echo "65536*$v1+256*$v2+$v3" | bc` + + # New CMake version + ver=$CMAKE_MIN_VERSION splitVersion + nv=`echo "65536*$v1+256*$v2+$v3" | bc` + if [ "$cv" -ge "$nv" ]; then + echo "CMake is already installed: $currVer" + else + UPGRADE_NEEDED=yes + fi +} + +checkVersion + +if [[ "$UPGRADE_NEEDED" == "no" ]]; then + echo "Skipping CMake installation" + exit 0 +fi + +# Download cmake to /tmp +pushd /tmp +if [[ ! -f "/tmp/cmake.tar.gz" ]]; then + wget -O /tmp/cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz + tar -zxvf /tmp/cmake.tar.gz +fi +# Bootstrap CMake +cd cmake-${CMAKE_VERSION} +./bootstrap --prefix=/usr/local +# Build CMake without CMake and without Ninja (slow) +make +make install +popd diff --git a/tools/setup-ninja.sh b/tools/setup-ninja.sh new file mode 100644 index 0000000000..c1ed98e496 --- /dev/null +++ b/tools/setup-ninja.sh @@ -0,0 +1,3 @@ +#!/bin/bash +wget -O /tmp/ninja.zip https://github.com/ninja-build/ninja/releases/download/v1.10.1/ninja-linux.zip +sudo unzip /tmp/ninja.zip -d /usr/local/bin/ diff --git a/tools/setup-protobuf.sh b/tools/setup-protobuf.sh new file mode 100644 index 0000000000..f6f0fb4535 --- /dev/null +++ b/tools/setup-protobuf.sh @@ -0,0 +1,6 @@ +#!/bin/bash +pushd /tmp +curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip +unzip -o protoc-3.14.0-linux-x86_64.zip -d /usr/local/ +update-alternatives --install /usr/bin/protoc protoc /usr/local/bin/protoc 1 --force +popd From d289827431d8aef4c73ce662c9e461a8888b4c5b Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 18:09:50 -0800 Subject: [PATCH 39/54] Apply code and CMake formatting rules --- .bazelignore | 6 +++--- CMakeLists.txt | 4 ---- api/test/context/CMakeLists.txt | 6 +++--- api/test/core/CMakeLists.txt | 6 +++--- api/test/metrics/CMakeLists.txt | 6 +++--- api/test/nostd/CMakeLists.txt | 6 +++--- api/test/plugin/CMakeLists.txt | 4 ++-- api/test/trace/CMakeLists.txt | 6 +++--- api/test/trace/propagation/CMakeLists.txt | 6 +++--- examples/batch/CMakeLists.txt | 4 ++-- examples/metrics_simple/CMakeLists.txt | 3 +-- examples/otlp/CMakeLists.txt | 7 +++---- exporters/ostream/CMakeLists.txt | 6 ++---- exporters/otlp/src/recordable.cc | 2 +- sdk/test/common/CMakeLists.txt | 13 ++++++------- sdk/test/metrics/CMakeLists.txt | 6 +++--- sdk/test/trace/CMakeLists.txt | 10 ++++++---- 17 files changed, 47 insertions(+), 54 deletions(-) diff --git a/.bazelignore b/.bazelignore index cb65fb06de..56306fc4b9 100644 --- a/.bazelignore +++ b/.bazelignore @@ -1,3 +1,3 @@ -third_party -tools -out +third_party +tools +out diff --git a/CMakeLists.txt b/CMakeLists.txt index 30ec2c2f8d..0ca3064843 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,6 @@ if(WITH_ABSEIL) endif() if(WITH_STL) - # Require at least C++17. C++20 is needed to avoid gsl::span add_definitions(-DHAVE_CPP_STDLIB -DHAVE_GSL) @@ -51,12 +50,9 @@ if(WITH_STL) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus ${CMAKE_CXX_FLAGS_SPEED}") endif() - endif() -option(WITH_OTPROTOCOL option(WITH_OTLP "Whether to include the OpenTelemetry Protocol in the SDK" OFF) - option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK" OFF) diff --git a/api/test/context/CMakeLists.txt b/api/test/context/CMakeLists.txt index 6e98471cb1..2c9da11191 100644 --- a/api/test/context/CMakeLists.txt +++ b/api/test/context/CMakeLists.txt @@ -2,9 +2,9 @@ include(GoogleTest) foreach(testname context_test runtime_context_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} TEST_PREFIX context. diff --git a/api/test/core/CMakeLists.txt b/api/test/core/CMakeLists.txt index 39182f3347..0d59831bb4 100644 --- a/api/test/core/CMakeLists.txt +++ b/api/test/core/CMakeLists.txt @@ -1,9 +1,9 @@ include(GoogleTest) add_executable(timestamp_test timestamp_test.cc) -target_link_libraries(timestamp_test ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) +target_link_libraries( + timestamp_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET timestamp_test TEST_PREFIX trace. diff --git a/api/test/metrics/CMakeLists.txt b/api/test/metrics/CMakeLists.txt index 23b27bd37b..f20a46c094 100644 --- a/api/test/metrics/CMakeLists.txt +++ b/api/test/metrics/CMakeLists.txt @@ -1,8 +1,8 @@ foreach(testname noop_instrument_test meter_provider_test noop_metrics_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} TEST_PREFIX metrics. diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index 266b550b63..21c2197ced 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -3,9 +3,9 @@ include(GoogleTest) foreach(testname function_ref_test string_view_test unique_ptr_test utility_test span_test shared_ptr_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} TEST_PREFIX nostd. diff --git a/api/test/plugin/CMakeLists.txt b/api/test/plugin/CMakeLists.txt index 2b229a68d2..29a75b6b84 100644 --- a/api/test/plugin/CMakeLists.txt +++ b/api/test/plugin/CMakeLists.txt @@ -1,8 +1,8 @@ include(GoogleTest) add_executable(dynamic_load_test dynamic_load_test.cc) -target_link_libraries(dynamic_load_test ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} +target_link_libraries( + dynamic_load_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) target_link_libraries(dynamic_load_test ${CMAKE_DL_LIBS}) gtest_add_tests( diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index 0a9fff4387..6c69883b2c 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -10,9 +10,9 @@ foreach( noop_test tracer_test) add_executable(api_${testname} "${testname}.cc") - target_link_libraries(api_${testname} ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + target_link_libraries( + api_${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET api_${testname} TEST_PREFIX trace. diff --git a/api/test/trace/propagation/CMakeLists.txt b/api/test/trace/propagation/CMakeLists.txt index 3b00140acb..8f13cd68de 100644 --- a/api/test/trace/propagation/CMakeLists.txt +++ b/api/test/trace/propagation/CMakeLists.txt @@ -1,8 +1,8 @@ foreach(testname http_text_format_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} TEST_PREFIX trace. diff --git a/examples/batch/CMakeLists.txt b/examples/batch/CMakeLists.txt index 6af8806b2d..41654aeb93 100644 --- a/examples/batch/CMakeLists.txt +++ b/examples/batch/CMakeLists.txt @@ -2,6 +2,6 @@ include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include) add_executable(batch_span_processor_example main.cc) -target_link_libraries(batch_span_processor_example ${CMAKE_THREAD_LIBS_INIT} - ${CORE_RUNTIME_LIBS} +target_link_libraries( + batch_span_processor_example ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_span opentelemetry_trace) diff --git a/examples/metrics_simple/CMakeLists.txt b/examples/metrics_simple/CMakeLists.txt index 638119b998..add3a153ce 100644 --- a/examples/metrics_simple/CMakeLists.txt +++ b/examples/metrics_simple/CMakeLists.txt @@ -3,5 +3,4 @@ include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include) add_executable(simple_metrics main.cc) target_link_libraries( simple_metrics ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics - ${CORE_RUNTIME_LIBS} - opentelemetry_exporter_ostream_metrics) + ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_metrics) diff --git a/examples/otlp/CMakeLists.txt b/examples/otlp/CMakeLists.txt index 19351ea298..bd4be33eee 100644 --- a/examples/otlp/CMakeLists.txt +++ b/examples/otlp/CMakeLists.txt @@ -4,10 +4,9 @@ include_directories(${CMAKE_SOURCE_DIR}/exporters/otlp/include) add_library(otlp_foo_library foo_library/foo_library.cc) target_link_libraries(otlp_foo_library ${CMAKE_THREAD_LIBS_INIT} - ${CORE_RUNTIME_LIBS} - opentelemetry_api) + ${CORE_RUNTIME_LIBS} opentelemetry_api) add_executable(example_otlp main.cc) -target_link_libraries( example_otlp ${CMAKE_THREAD_LIBS_INIT} otlp_foo_library - ${CORE_RUNTIME_LIBS} +target_link_libraries( + example_otlp ${CMAKE_THREAD_LIBS_INIT} otlp_foo_library ${CORE_RUNTIME_LIBS} opentelemetry_trace opentelemetry_exporter_otprotocol) diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index 7307ee10d1..c307de7244 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -9,13 +9,11 @@ if(BUILD_TESTING) target_link_libraries( ostream_span_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - ${CORE_RUNTIME_LIBS} - opentelemetry_exporter_ostream_span) + ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_span) target_link_libraries( ostream_metrics_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - ${CORE_RUNTIME_LIBS} - opentelemetry_exporter_ostream_metrics) + ${CORE_RUNTIME_LIBS} opentelemetry_exporter_ostream_metrics) gtest_add_tests( TARGET ostream_metrics_test diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index cd6bf56bd1..6cc0347a89 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -59,7 +59,7 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, attribute->mutable_value()->set_string_value(nostd::get(value).data(), nostd::get(value).size()); } - else if (nostd::holds_alternative(value)) + else if (nostd::holds_alternative(value)) { attribute->mutable_value()->set_string_value(nostd::get(value)); } diff --git a/sdk/test/common/CMakeLists.txt b/sdk/test/common/CMakeLists.txt index e84a4da17f..f1028bf6d8 100644 --- a/sdk/test/common/CMakeLists.txt +++ b/sdk/test/common/CMakeLists.txt @@ -4,8 +4,7 @@ foreach(testname add_executable(${testname} "${testname}.cc") target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - ${CORE_RUNTIME_LIBS} - opentelemetry_common opentelemetry_trace) + ${CORE_RUNTIME_LIBS} opentelemetry_common opentelemetry_trace) gtest_add_tests( TARGET ${testname} TEST_PREFIX trace. @@ -17,11 +16,11 @@ target_link_libraries(random_fork_test opentelemetry_common) add_test(random_fork_test random_fork_test) add_executable(random_benchmark random_benchmark.cc) -target_link_libraries(random_benchmark benchmark::benchmark - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) +target_link_libraries( + random_benchmark benchmark::benchmark ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) add_executable(circular_buffer_benchmark circular_buffer_benchmark.cc) -target_link_libraries(circular_buffer_benchmark benchmark::benchmark - ${CORE_RUNTIME_LIBS} +target_link_libraries( + circular_buffer_benchmark benchmark::benchmark ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index 82edc3038f..dbab882a46 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -11,9 +11,9 @@ foreach( metric_instrument_test controller_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) gtest_add_tests( TARGET ${testname} TEST_PREFIX metrics. diff --git a/sdk/test/trace/CMakeLists.txt b/sdk/test/trace/CMakeLists.txt index 6a233e714a..b68a57f9cc 100644 --- a/sdk/test/trace/CMakeLists.txt +++ b/sdk/test/trace/CMakeLists.txt @@ -14,8 +14,11 @@ foreach( target_link_libraries( ${testname} ${CORE_RUNTIME_LIBS} - ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_common opentelemetry_trace opentelemetry_exporter_in_memory) + ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + opentelemetry_common + opentelemetry_trace + opentelemetry_exporter_in_memory) gtest_add_tests( TARGET ${testname} TEST_PREFIX trace. @@ -25,5 +28,4 @@ endforeach() add_executable(sampler_benchmark sampler_benchmark.cc) target_link_libraries( sampler_benchmark benchmark::benchmark ${CMAKE_THREAD_LIBS_INIT} - ${CORE_RUNTIME_LIBS} - opentelemetry_trace opentelemetry_exporter_in_memory) + ${CORE_RUNTIME_LIBS} opentelemetry_trace opentelemetry_exporter_in_memory) From 6d61cd11e3bba75fe197a229401118bbd925123f Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 18:44:19 -0800 Subject: [PATCH 40/54] Fix couple minor bugs --- api/test/nostd/CMakeLists.txt | 2 +- sdk/src/trace/tracer_provider.cc | 2 +- third_party/opentelemetry-proto | 1 + tools/build.sh | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) create mode 160000 third_party/opentelemetry-proto diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index 21c2197ced..4e8e288817 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -4,7 +4,7 @@ foreach(testname function_ref_test string_view_test unique_ptr_test utility_test span_test shared_ptr_test) add_executable(${testname} "${testname}.cc") target_link_libraries( - ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${testname} ${GTEST_BOTH_LIBRARIES} benchmark::benchmark ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index af929ee1eb..882eda01c8 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -17,7 +17,7 @@ opentelemetry::nostd::shared_ptr TracerProvider::G #if 0 // TODO: do we have to cast/transform this or can we keep as nostd::shared_ptr<...> ? return opentelemetry::nostd::shared_ptr(tracer_); -#endif +#else return tracer_; #endif } diff --git a/third_party/opentelemetry-proto b/third_party/opentelemetry-proto new file mode 160000 index 0000000000..f11e0538fd --- /dev/null +++ b/third_party/opentelemetry-proto @@ -0,0 +1 @@ +Subproject commit f11e0538fd7dc30127ca6bfb2062e5d9f782b77b diff --git a/tools/build.sh b/tools/build.sh index adce46b53c..9ac4730008 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -42,7 +42,7 @@ function build { echo "Build configuration: $BUILD_CONFIG" cd $WORKSPACE_ROOT - BUILD_ROOT=`pwd`/out/$PLATFORM_NAME/$BUILD_CONFIG + export BUILD_ROOT=`pwd`/out/$PLATFORM_NAME/$BUILD_CONFIG mkdir -p $BUILD_ROOT if [ ! -w $BUILD_ROOT ] ; then echo "Unable to create output directory: $BUILD_ROOT" From 636d4dea60561d97b9de78874fcfeec1a2b6d94d Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 18:49:55 -0800 Subject: [PATCH 41/54] Formatting fix --- api/test/nostd/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index 4e8e288817..52d7d29b40 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -4,8 +4,8 @@ foreach(testname function_ref_test string_view_test unique_ptr_test utility_test span_test shared_ptr_test) add_executable(${testname} "${testname}.cc") target_link_libraries( - ${testname} ${GTEST_BOTH_LIBRARIES} benchmark::benchmark ${CORE_RUNTIME_LIBS} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + ${testname} ${GTEST_BOTH_LIBRARIES} benchmark::benchmark + ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} TEST_PREFIX nostd. From be5194887be16c0a15c3722be90f0cd722aa7876 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 19:01:10 -0800 Subject: [PATCH 42/54] Add missing submodule --- third_party/prometheus-cpp | 1 + 1 file changed, 1 insertion(+) create mode 160000 third_party/prometheus-cpp diff --git a/third_party/prometheus-cpp b/third_party/prometheus-cpp new file mode 160000 index 0000000000..27c3d670c6 --- /dev/null +++ b/third_party/prometheus-cpp @@ -0,0 +1 @@ +Subproject commit 27c3d670c66985c0096d378cdd780088b08bc8f4 From bd009a98f83246decf6e069dc5492b419d470289 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 21:00:57 -0800 Subject: [PATCH 43/54] Fix an issue in CI, where gcc-4.8 may try to link to GTest built with gcc-7+ --- ci/do_ci.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 48b797704f..ea01920730 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -33,6 +33,9 @@ elif [[ "$1" == "cmake.c++20.test" ]]; then elif [[ "$1" == "cmake.legacy.test" ]]; then cd "${BUILD_DIR}" rm -rf * + export BUILD_ROOT="${BUILD_DIR}" + ${SRC_DIR}/tools/build-gtest.sh + ${SRC_DIR}/tools/build-benchmark.sh cmake -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_CXX_FLAGS="-Werror" \ -DCMAKE_CXX_STANDARD=11 \ From ea99318db1f54933a7f6a6a595910c8e9474cff6 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 21:01:36 -0800 Subject: [PATCH 44/54] Add different build configurations to Visual Studio 2019 cmake (GUI) build --- CMakeSettings.json | 65 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/CMakeSettings.json b/CMakeSettings.json index 4b2923f3ca..aa695a82d6 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -5,8 +5,8 @@ "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", + "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", @@ -28,8 +28,8 @@ "generator": "Ninja", "configurationType": "RelWithDebInfo", "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", + "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", @@ -46,6 +46,63 @@ "type": "BOOL" } ] + }, + { + "name": "stdlib-x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", + "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [ + { + "name": "WITH_STL", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" + } + ] + }, + { + "name": "stdlib-x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", + "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "cmakeToolchain": "", + "variables": [ + { + "name": "WITH_STL", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" + } + ] } ] } \ No newline at end of file From f86b7f1a8765f174849c84a79070d51c03d8c496 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 22:25:16 -0800 Subject: [PATCH 45/54] Undo the changes that are not relevant to STDLIB --- api/include/opentelemetry/common/attribute_value.h | 7 ++++++- exporters/otlp/src/recordable.cc | 4 +++- sdk/include/opentelemetry/sdk/common/empty_attributes.h | 8 -------- sdk/include/opentelemetry/sdk/trace/attribute_utils.h | 3 +++ sdk/include/opentelemetry/sdk/trace/tracer_provider.h | 5 ----- sdk/src/trace/tracer_provider.cc | 5 ----- 6 files changed, 12 insertions(+), 20 deletions(-) diff --git a/api/include/opentelemetry/common/attribute_value.h b/api/include/opentelemetry/common/attribute_value.h index 2d9eb9761d..6cb399842a 100644 --- a/api/include/opentelemetry/common/attribute_value.h +++ b/api/include/opentelemetry/common/attribute_value.h @@ -18,7 +18,10 @@ using AttributeValue = uint64_t, double, nostd::string_view, +#ifdef HAVE_CSTRING_TYPE + // TODO: add C-string as possible value on API surface const char *, +#endif #ifdef HAVE_SPAN_BYTE // TODO: 8-bit byte arrays / binary blobs are not part of OT spec yet! // Ref: https://github.com/open-telemetry/opentelemetry-specification/issues/780 @@ -41,9 +44,11 @@ enum AttributeType TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, +#ifdef HAVE_CSTRING_TYPE TYPE_CSTRING, +#endif #ifdef HAVE_SPAN_BYTE - TYPE_SPAN_BYTE, // TODO: not part of OT spec yet + TYPE_SPAN_BYTE, #endif TYPE_SPAN_BOOL, TYPE_SPAN_INT, diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index 6cc0347a89..8e43c69c92 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -6,7 +6,7 @@ namespace exporter namespace otlp { -const int kAttributeValueSize = 15; +const int kAttributeValueSize = 14; void Recordable::SetIds(trace::TraceId trace_id, trace::SpanId span_id, @@ -59,10 +59,12 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, attribute->mutable_value()->set_string_value(nostd::get(value).data(), nostd::get(value).size()); } +#ifdef HAVE_CSTRING_TYPE else if (nostd::holds_alternative(value)) { attribute->mutable_value()->set_string_value(nostd::get(value)); } +#endif else if (nostd::holds_alternative>(value)) { for (const auto &val : nostd::get>(value)) diff --git a/sdk/include/opentelemetry/sdk/common/empty_attributes.h b/sdk/include/opentelemetry/sdk/common/empty_attributes.h index 743b85e7c4..d030d2d118 100644 --- a/sdk/include/opentelemetry/sdk/common/empty_attributes.h +++ b/sdk/include/opentelemetry/sdk/common/empty_attributes.h @@ -8,8 +8,6 @@ OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { - -#if 0 /** * Maintain a static empty array of pairs that represents empty (default) attributes. * This helps to avoid constructing a new empty container every time a call is made @@ -25,11 +23,5 @@ static const opentelemetry::common::KeyValueIterableView, #endif diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index abffd0ca47..6581ad46be 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -54,12 +54,7 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider private: opentelemetry::sdk::AtomicSharedPtr processor_; -#if 0 - // TODO: pros and cons of exposing this as `std::shared_ptr` vs keeping `nostd::shared_ptr` ? std::shared_ptr tracer_; -#else - opentelemetry::nostd::shared_ptr tracer_; -#endif const std::shared_ptr sampler_; }; } // namespace trace diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index 882eda01c8..8f05436b4c 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -14,12 +14,7 @@ opentelemetry::nostd::shared_ptr TracerProvider::G nostd::string_view library_name, nostd::string_view library_version) noexcept { -#if 0 - // TODO: do we have to cast/transform this or can we keep as nostd::shared_ptr<...> ? return opentelemetry::nostd::shared_ptr(tracer_); -#else - return tracer_; -#endif } void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept From 2c65732db89192e0c47249d0c761d6f0bfe6824b Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 17 Nov 2020 23:36:41 -0800 Subject: [PATCH 46/54] Adjust script permissions --- tools/build-benchmark.sh | 0 tools/build-vcpkg.sh | 0 tools/install.sh | 0 tools/setup-cmake.sh | 0 tools/setup-ninja.sh | 0 tools/setup-protobuf.sh | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/build-benchmark.sh mode change 100644 => 100755 tools/build-vcpkg.sh mode change 100644 => 100755 tools/install.sh mode change 100644 => 100755 tools/setup-cmake.sh mode change 100644 => 100755 tools/setup-ninja.sh mode change 100644 => 100755 tools/setup-protobuf.sh diff --git a/tools/build-benchmark.sh b/tools/build-benchmark.sh old mode 100644 new mode 100755 diff --git a/tools/build-vcpkg.sh b/tools/build-vcpkg.sh old mode 100644 new mode 100755 diff --git a/tools/install.sh b/tools/install.sh old mode 100644 new mode 100755 diff --git a/tools/setup-cmake.sh b/tools/setup-cmake.sh old mode 100644 new mode 100755 diff --git a/tools/setup-ninja.sh b/tools/setup-ninja.sh old mode 100644 new mode 100755 diff --git a/tools/setup-protobuf.sh b/tools/setup-protobuf.sh old mode 100644 new mode 100755 From 87b248fbf69b2574ac4ca3838daf4a5355d19fbb Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 8 Dec 2020 18:46:31 -0800 Subject: [PATCH 47/54] Resolve merge conflicts --- .github/workflows/ci.yml | 32 +++++++++---------- .gitignore | 3 ++ CMakeSettings.json | 16 +++++----- WORKSPACE | 9 ++++++ .../sdk/trace/simple_processor.h | 4 ++- .../opentelemetry/sdk/trace/tracer_provider.h | 5 +++ sdk/src/trace/batch_span_processor.cc | 8 +++-- sdk/src/trace/tracer_provider.cc | 5 +++ sdk/test/trace/tracer_provider_test.cc | 12 +++++++ tools/download.cmd | 2 +- tools/install-vs-addons.cmd | 8 ++--- tools/setup-buildtools.cmd | 2 +- tools/vcvars.cmd | 2 +- 13 files changed, 73 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02fc206e0a..538fe07f8f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -29,7 +29,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_ci_environment.sh @@ -49,7 +49,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_ci_environment.sh @@ -63,7 +63,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -77,7 +77,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_ci_environment.sh @@ -94,7 +94,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -109,7 +109,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -124,7 +124,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -139,7 +139,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -154,7 +154,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -169,7 +169,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: run tests run: ./ci/do_ci.sh bazel.test @@ -179,7 +179,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh @@ -212,7 +212,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | ./ci/setup_windows_cmake.ps1 @@ -229,7 +229,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: ./ci/install_windows_bazelisk.ps1 - name: run tests @@ -241,7 +241,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | ./ci/setup_windows_cmake.ps1 @@ -255,7 +255,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - submodules: 'true' + submodules: 'recursive' - name: setup run: | sudo ./ci/setup_cmake.sh diff --git a/.gitignore b/.gitignore index 360c37e288..714760e987 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,9 @@ # Bazel files /bazel-* +# Mac +.DS_Store + # Output directories /out /out.* diff --git a/CMakeSettings.json b/CMakeSettings.json index aa695a82d6..e5285d3fad 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -5,8 +5,8 @@ "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", - "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", @@ -28,8 +28,8 @@ "generator": "Ninja", "configurationType": "RelWithDebInfo", "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", - "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", @@ -52,8 +52,8 @@ "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", - "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", @@ -80,8 +80,8 @@ "generator": "Ninja", "configurationType": "RelWithDebInfo", "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\win32-vs2019\\${name}", - "installRoot": "${projectDir}\\out\\win32-vs2019\\${name}\\install", + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", diff --git a/WORKSPACE b/WORKSPACE index de4ec2a48b..00574985d9 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -102,3 +102,12 @@ http_archive( load("@com_github_jupp0r_prometheus_cpp//bazel:repositories.bzl", "prometheus_cpp_repositories") prometheus_cpp_repositories() + +# libcurl - An optional dependency we pull in for tests. +http_archive( + name = "curl", + build_file = "@//bazel:curl.BUILD", + sha256 = "ba98332752257b47b9dea6d8c0ad25ec1745c20424f1dd3ff2c99ab59e97cf91", + strip_prefix = "curl-7.73.0", + urls = ["https://curl.haxx.se/download/curl-7.73.0.tar.gz"], +) diff --git a/sdk/include/opentelemetry/sdk/trace/simple_processor.h b/sdk/include/opentelemetry/sdk/trace/simple_processor.h index e10d8fa515..38b7a1e7f7 100644 --- a/sdk/include/opentelemetry/sdk/trace/simple_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/simple_processor.h @@ -57,12 +57,14 @@ class SimpleSpanProcessor : public SpanProcessor void Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept override { // We only call shutdown ONCE. - if (!shutdown_latch_.test_and_set(std::memory_order_acquire)) + if (exporter_ != nullptr && !shutdown_latch_.test_and_set(std::memory_order_acquire)) { exporter_->Shutdown(timeout); } } + ~SimpleSpanProcessor() { Shutdown(); } + private: std::unique_ptr exporter_; opentelemetry::common::SpinLockMutex lock_; diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index 6581ad46be..2f7e49d454 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -52,6 +52,11 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider */ std::shared_ptr GetSampler() const noexcept; + /** + * Shutdown the span processor associated with this tracer provider. + */ + void Shutdown() noexcept; + private: opentelemetry::sdk::AtomicSharedPtr processor_; std::shared_ptr tracer_; diff --git a/sdk/src/trace/batch_span_processor.cc b/sdk/src/trace/batch_span_processor.cc index 111fbae0d5..cf0a342081 100644 --- a/sdk/src/trace/batch_span_processor.cc +++ b/sdk/src/trace/batch_span_processor.cc @@ -175,12 +175,14 @@ void BatchSpanProcessor::DrainQueue() void BatchSpanProcessor::Shutdown(std::chrono::microseconds timeout) noexcept { - is_shutdown_ = true; + is_shutdown_.store(true); cv_.notify_one(); worker_thread_.join(); - - exporter_->Shutdown(); + if (exporter_ != nullptr) + { + exporter_->Shutdown(); + } } BatchSpanProcessor::~BatchSpanProcessor() diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index 8f05436b4c..157b1b0449 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -34,6 +34,11 @@ std::shared_ptr TracerProvider::GetSampler() const noexcept { return sampler_; } + +void TracerProvider::Shutdown() noexcept +{ + GetProcessor()->Shutdown(); +} } // namespace trace } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/test/trace/tracer_provider_test.cc b/sdk/test/trace/tracer_provider_test.cc index dca3bc3607..dbf7f5a14f 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -59,3 +59,15 @@ TEST(TracerProvider, GetSampler) ASSERT_EQ("AlwaysOffSampler", t3->GetDescription()); } + +TEST(TracerProvider, Shutdown) +{ + std::shared_ptr processor1(new SimpleSpanProcessor(nullptr)); + + TracerProvider tp1(processor1); + + tp1.Shutdown(); + + // Verify Shutdown returns. + ASSERT_TRUE(true); +} diff --git a/tools/download.cmd b/tools/download.cmd index 97f546863b..55820b6815 100644 --- a/tools/download.cmd +++ b/tools/download.cmd @@ -1,3 +1,3 @@ @REM This script allows to download a file to local machine. First argument is URL -set "PATH=C:\Windows;C:\Windows\System32;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\bin" +set "PATH=%SystemRoot%;%SystemRoot%\System32;%SystemRoot%\System32\WindowsPowerShell\v1.0\;%ProgramFiles%\Git\bin" @powershell -File Download.ps1 %1 diff --git a/tools/install-vs-addons.cmd b/tools/install-vs-addons.cmd index e4c866be33..e6cb0b9a65 100644 --- a/tools/install-vs-addons.cmd +++ b/tools/install-vs-addons.cmd @@ -1,4 +1,4 @@ -set "PATH=C:\Windows;C:\Windows\System32;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\bin" +set "PATH=%SystemRoot%;%SystemRoot%\System32;%SystemRoot%\System32\WindowsPowerShell\v1.0\;%ProgramFiles%\Git\bin" cd %~dp0 call powershell -File .\install_llvm-win64.ps1 @@ -8,7 +8,7 @@ call download.cmd https://llvmextensions.gallerycdn.vsassets.io/extensions/llvme REM Install optional components required for ARM build - vs2017-BuildTools IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" ( "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^ - -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" -q ^ + modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" -q ^ --add Microsoft.VisualStudio.Component.VC.ATL ^ --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 @@ -18,7 +18,7 @@ IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" ( REM Install optional components required for ARM build - vs2017-Enterprise IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" ( "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^ - -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" -q ^ + modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" -q ^ --add Microsoft.VisualStudio.Component.VC.ATL ^ --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 @@ -28,7 +28,7 @@ IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" ( REM Install optional components required for ARM build - vs2019-Enterprise IF EXIST %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise ( "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe" ^ - -- modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise" -q ^ + modify --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise" -q ^ --add Microsoft.VisualStudio.Component.VC.ATL ^ --add Microsoft.VisualStudio.Component.VC.ATL.ARM ^ --add Microsoft.VisualStudio.Component.VC.ATL.ARM64 diff --git a/tools/setup-buildtools.cmd b/tools/setup-buildtools.cmd index 25232422dd..96602dd539 100644 --- a/tools/setup-buildtools.cmd +++ b/tools/setup-buildtools.cmd @@ -1,5 +1,5 @@ @echo off -set "PATH=C:\Program Files\CMake\bin;%~dp0;%~dp0\vcpkg;%PATH%" +set "PATH=%ProgramFiles%\CMake\bin;%~dp0;%~dp0\vcpkg;%PATH%" pushd %~dp0 net session >nul 2>&1 diff --git a/tools/vcvars.cmd b/tools/vcvars.cmd index 1b8215fcbb..fe728367a6 100644 --- a/tools/vcvars.cmd +++ b/tools/vcvars.cmd @@ -72,7 +72,7 @@ set TOOLS_VS2015="%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\bin\vcvars if exist %TOOLS_VS2015% ( echo Building with vs2015 BuildTools... call %TOOLS_VS2015% - set "VCPKG_VISUAL_STUDIO_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0" + set "VCPKG_VISUAL_STUDIO_PATH=%ProgramFiles(x86)%\Microsoft Visual Studio 14.0" set VCPKG_PLATFORM_TOOLSET=v140 goto tools_configured ) From ced9ff7e20c218f202fd2a32ad93fa526d8f9ba2 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 8 Dec 2020 19:40:31 -0800 Subject: [PATCH 48/54] Formatting change --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ca3064843..37161fb3d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ if(WITH_STL) endif() option(WITH_OTLP "Whether to include the OpenTelemetry Protocol in the SDK" OFF) + option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK" OFF) From 5e84ccd3885f454e22e5f98585f7b317b6bb0cfa Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 10 Dec 2020 14:20:23 -0800 Subject: [PATCH 49/54] Address code review comments --- docs/building-with-stdlib.md | 188 ++++++++++++++++++++++++++--------- 1 file changed, 139 insertions(+), 49 deletions(-) diff --git a/docs/building-with-stdlib.md b/docs/building-with-stdlib.md index 4031be90d2..67cb0b1f1c 100644 --- a/docs/building-with-stdlib.md +++ b/docs/building-with-stdlib.md @@ -10,23 +10,73 @@ ABI compatibility is required: - OpenTelemetry SDK binary compiled with compiler A + STL B - may not be ABI compatible with the main executable compiled with compiler C + STL D on a same OS. -Thus, this approach works best only for statically lined / header only use. + +In addition to standard library, similar approach can be reused to implement +the API surface classes with [Abseil classes](https://abseil.io/) instead of +`nostd`, in products that prefer Abseil. ## Motivation -In certain scenarios it may be of benefit to compile the OpenTelemetry SDK from -source using standard library container classes (`std::map`, `std::string_view`, -`std::span`, `std::variant`) instead of OpenTelemetry `nostd::` analogs (which -were backported to C++11 and designed as ABI-stable). This PR also can be used -as a foundation for alternate approach - to also allow bindings to [abseil](https://github.com/abseil/abseil-cpp) -classes. That is in environments that would rather prefer `Abseil` classes -over the standard lib or `nostd`. +`nostd` classes in OpenTelemetry API were introduced for the following reasons: +- ABI stability: scenario where different modules are compiled with different +compiler and incompatible standard library. +- backport of C++17 and above features to C++11 compiler. + +The need for custom `nostd` classes is significantly diminished when the SDK is +compiled with C++17 or above compiler. Only `std::span` needs to be backported. + +Subsequently, there is no need for `nostd` classes in environment with C++20 or +above compiler, where all system modules are compiled with the same / compatible +compiler. And where the same standard library implementation is being used. This +is the case when SDK is compiled into product itself, with no runtime loadable +components. + +Compiling OpenTelemetry SDK from source using standard library classes: +`std::map`, `std::string_view`, `std::span`, `std::variant` +instead of `nostd::` yields better performance and debugability at expense +of potentially losing ABI compatibility. However, the standard library built +for Release is guaranteed to be compatible across Visual Studio 2015, 2017 and +2019 compilers on Windows with vc14x runtime. Thus, ABI stability requirement +introduces an additional unnecessary runtime complexity and overhead. + +While we are committed to support `nostd` classes for those environments where +ABI compatibility is a requirement, we would also like to add flexibility to +build system to optimize the SDK for the case where ABI compatibility is NOT +a requirement. + +Implementation of this feature can be subsequently be used as a foundation for +further work - allow bindings to [Abseil](https://github.com/abseil/abseil-cpp) +"backport" implementation of the standard library. + +Implementation is completely opaque from SDK code / SDK developer perspective: +mapping / aliasing from `nostd::` classes back to their `std::` counterparts +is done in a corresponding `opentelemetry/nostd/*.h` header. Users still use +`nostd` classes, but the most optimal implementation is picked up depending on +whether users require ABI stability or not. + +Example environments that contain the full set of standard classes: +- C++17 or above compiler, with Microsoft GSL backport of `gsl::span` +- C++20 compilers: Visual Studio 2019+, latest LLVM clang, latest gcc -The approach is to provide totally opaque (from SDK code / SDK developer -perspective) mapping / aliasing from `nostd::` classes back to their `std::` -counterparts, and that is only done in environments where this is possible. +We continue fully supporting both models (`nostd`, `stdlib`) by running CI for both. -We continue fully supporting both models and run CI for both. +## Implementation + +Allow to alias from `nostd::` to `std::` classes for C++17 and above. + +Consistent handling of `std::variant` across various OS: + +- backport of a few missing variant features, e.g. `std::get` and `std::visit` + for older version of Mac OS X. Patches that enable proper handling of + `std::visit` and `std::variant` irrespective of OS version to resolve + [this quirk](https://stackoverflow.com/questions/52310835/xcode-10-call-to-unavailable-function-stdvisit). + +- ability to borrow implementation of C++20 `gsl::span` from + [Microsoft Guidelines Support Library](https://github.com/microsoft/GSL). + This is necessary for C++17 and above compiler. + +- ability to use Abseil classes for Visual Studio 2015 :`nostd::variant` does + not compile with Visual Studio 2010. Please refer to [this issue](https://github.com/open-telemetry/opentelemetry-cpp/issues/314) ## Pros and Cons @@ -42,12 +92,10 @@ runtime-checks for Debug builds that use Standard containers. ### Minimizing binary size No need to marshal types from standard to `nostd`, then back to standard -library means less code involved and less memcpy. We use Standard classes -used elsewhere in the app. We can subsequently improve the process by avoiding -`KeyValueIterable` transform (and, thus, unnecessary memcpy) when we know -that the incoming types does not need to be 'transferred' across ABI boundary. -This is the case for statically linked executables and when SDK is implemented -as 'header-only' library. +library across ABI boundary - means less code involved and less memcpy. We use +Standard Library classes used elsewhere in the app. We can optimize the +event passing by avoiding `KeyValueIterable` transform (and, thus, unnecessary memcpy) +when we know that the incoming container type matches that one used by SDK. ### Avoiding unnecessary extra memcpy (perf improvements) @@ -55,48 +103,90 @@ No need to transform from 'native' standard library types, e.g. `std::map` via `KeyValueIterable` means we can bypass that transformation process, if and when we know that the ABI compatibility is not a requirement in certain environment. ETA perf improvement is 1.5%-3% better perf since an extra transform, memcpy, -iteration for-each key-value is avoided. +iteration for-each key-value is avoided. Custom OpenTelemetry SDK implementation +may operate on standard container classes rather than doing transform from one +container type to another. ### ABI stability -Obviously this approach does not work in environment where ABI stability +Obviously this approach does not work in Linux environments, where ABI stability guarantee must be provided, e.g. for dynamically loadable OpenTelemetry SDK -module and plugins for products such as NGINX, Envoy, etc. +module and plugins for products such as NGINX, Envoy, etc. Example: a product is +compiled with modern gcc compiler. But OpenTelemetry SDK is compiled with an +older runtime library. In this case the SDK must be compiled with `nostd`. + +Note that for most scenarios with modern Windows compilers, STL library is +ABI-safe across Visual Studio 2015, 2017 and 2019 with vc14x runtime. + +Quote from [official documentation](https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=msvc-160) : + +Visual Studio 2015, 2017, and 2019: the runtime libraries and apps compiled by +any of these versions of the compiler are binary-compatible. It's reflected in +the C++ toolset major number, which is 14 for all three versions. The toolset +version is v140 for Visual Studio 2015, v141 for 2017, and v142 for 2019. +Say you have third-party libraries built by Visual Studio 2015. You can still +use them in an application built by Visual Studio 2017 or 2019. There's no need +to recompile with a matching toolset. The latest version of the Microsoft Visual +C++ Redistributable package (the Redistributable) works for all of them. -## Scope of changes needed to implement the feature +Visual Studio provides 1st class debug experience for the standard library. +## Build and Test considerations ### Separate flavors of SDK build Supported build flavors: -- `nostd` - OpenTelemetry backport of classes for C++11. Not using STD Lib. -- `stl` - Standard Library. Best be compiled with C++20 compaitlbe compiler. - C++17 may be used with additional dependencies, e.g. MS-GSL or Abseil. -- `absl` - TODO: this should allow using Abseil C++ lirary only (no MS-GSL). +- `nostd` - OpenTelemetry backport of classes for C++11. Not using standard lib. +- `stl` - Standard Library. Full native experience with C++20 compiler. + C++17 works but with additional dependencies, e.g. either MS-GSL or Abseil + for `std::span` implementation (`gsl::span` or `absl::Span`). +- `absl` - TODO: this should allow using Abseil C++ library only (no MS-GSL). + +Currently only `nostd` and `stl` configurations are implemented. +`absl` is reserved for future use. + +### Build matrix + +List of compilers that support building with standard library classes: + +Compiler | Language standard | Notes +-------------------|-------------------|------------------- +Visual Studio 2015 | C++14 | can only be built with `nostd` flavor +Visual Studio 2017 | C++17 | requires `gsl::span` for `std::span` implementation +Visual Studio 2019 | C++20 | +Xcode 11.x | C++17 | requires `gsl::span` for `std::span` implementation +Xcode 12.x | C++20 | +gcc-7 | C++17 | requires `gsl::span` for `std::span` implementation +gcc-9+ | C++20 | + +C++20 `std::span` -compatible implementation is needed for C++17 compilers. + +Other modern C++ language features used by OpenTelemetry, e.g. `std::string_view` +and `std::variant` are available in C++17 standard library. Minor customization +needed for Apple LLVM clang in `std::variant` exception handling due to the fact +that the variant exception handler presence depends on what OS version developer +is targeting. This exception on Apple systems is implemented inside the OS system +library. This idiosyncrasy is now handled by OpenTelemetry API in opaque manner: +support `nostd::variant` exception handling even on older Mac OS X and iOS by +providing implementation of it in OpenTelemetry SDK: if exceptions are enabled, +then throw `nostd::bad_variant_access` exception old OS where `std::bad_variant_access` +is unavailable. + +#### Note on `gsl::span` vs `absl::Span` + +It is important to note that, while `absl::Span` is similar in design and +purpose to the `std::span` (and existing `gsl::span` reference implementation), +`absl::Span` is not currently guaranteeing to be a drop-in replacement for any +eventual standard. Instead, `absl::Span` aims to have an interface as similar +as possible to `absl::string_view`, without the string-specific functionality. + +Thus, OpenTelemetry built with standard library prefers `gsl::span` as it is +fully compatible with standard `std::span`. It may become possible to use Abseil +classes should we confirm that its behavior is consistent with `nostd::span` +expectations. ### Test setup -Tests to validate that all OpenTelemetry functionality is working the same +CI allows to validate that all OpenTelemetry functionality is working the same identical way irrespective of what C++ runtime / STL library it is compiled -with. - -### Implementation Details - -Feature allows to alias from `nostd::` to `std::` classes for C++17 and above. - -Consistent handling of `std::variant` across various OS: - -- backport of a few missing variant features, e.g. `std::get` and `std::visit` - for older version of Mac OS X. Patches that enable proper - handling of `std::visit` and `std::variant` irrespective of OS version - to resolve [this quirk](https://stackoverflow.com/questions/52310835/xcode-10-call-to-unavailable-function-stdvisit). - -- ability to optionally borrow implementation of C++20 `gsl::span` from - [Microsoft Guidelines Support Library](https://github.com/microsoft/GSL). - This is not necessary for C++20 and above compilers. - -- ability to use Abseil `absl::variant` for Visual Studio 2015 - -- set of tools to locally build the SDK with both options across various OS - and compilers, including vs2015 (C++11), vs2017 (C++17), vs2019 (C++20), - ubuntu-18.xx (C++17), ubuntu-20.xx/gcc-9 (C++20), Mac OS X (C++17 and above). +with. Additional performance benchmarks were added. From a38993503870a5ba1670a08226e67617af224a2a Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 17 Dec 2020 19:33:52 -0800 Subject: [PATCH 50/54] Fix formatting issue --- examples/otlp/CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/otlp/CMakeLists.txt b/examples/otlp/CMakeLists.txt index f63f22e478..8b77baad38 100644 --- a/examples/otlp/CMakeLists.txt +++ b/examples/otlp/CMakeLists.txt @@ -7,5 +7,11 @@ target_link_libraries(otlp_foo_library ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} opentelemetry_api) add_executable(example_otlp main.cc) -target_link_libraries(example_otlp ${CMAKE_THREAD_LIBS_INIT} otlp_foo_library opentelemetry_trace ${CORE_RUNTIME_LIBS} - opentelemetry_exporter_otprotocol gRPC::grpc++) +target_link_libraries( + example_otlp + ${CMAKE_THREAD_LIBS_INIT} + otlp_foo_library + opentelemetry_trace + ${CORE_RUNTIME_LIBS} + opentelemetry_exporter_otprotocol + gRPC::grpc++) From b8e7cb1672c9e9606e77665ee6642bf93fd51d7e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 21 Dec 2020 12:50:42 -0800 Subject: [PATCH 51/54] Addressing code review comments, moving benchmarks into a separate future PR. --- api/test/nostd/BUILD | 3 - api/test/nostd/CMakeLists.txt | 2 +- api/test/nostd/shared_ptr_test.cc | 19 ----- api/test/nostd/span_test.cc | 58 --------------- api/test/nostd/string_view_test.cc | 111 ----------------------------- docs/building-with-stdlib.md | 15 ++-- 6 files changed, 8 insertions(+), 200 deletions(-) diff --git a/api/test/nostd/BUILD b/api/test/nostd/BUILD index c42d2b9255..35306e6a3c 100644 --- a/api/test/nostd/BUILD +++ b/api/test/nostd/BUILD @@ -16,7 +16,6 @@ cc_test( ], deps = [ "//api", - "@com_github_google_benchmark//:benchmark", "@com_google_googletest//:gtest_main", ], ) @@ -61,7 +60,6 @@ cc_test( ], deps = [ "//api", - "@com_github_google_benchmark//:benchmark", "@com_google_googletest//:gtest_main", ], ) @@ -73,7 +71,6 @@ cc_test( ], deps = [ "//api", - "@com_github_google_benchmark//:benchmark", "@com_google_googletest//:gtest_main", ], ) diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index 52d7d29b40..fdec960d9a 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -4,7 +4,7 @@ foreach(testname function_ref_test string_view_test unique_ptr_test utility_test span_test shared_ptr_test) add_executable(${testname} "${testname}.cc") target_link_libraries( - ${testname} ${GTEST_BOTH_LIBRARIES} benchmark::benchmark + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} diff --git a/api/test/nostd/shared_ptr_test.cc b/api/test/nostd/shared_ptr_test.cc index bda4e983db..f24b8c6946 100644 --- a/api/test/nostd/shared_ptr_test.cc +++ b/api/test/nostd/shared_ptr_test.cc @@ -1,6 +1,5 @@ #include "opentelemetry/nostd/shared_ptr.h" -#include #include #include @@ -185,21 +184,3 @@ TEST(SharedPtrTest, Sort) { SharedPtrTest_Sort(); } - -static void SharedPtrTestSort(benchmark::State &state) -{ - for (auto _ : state) - { - SharedPtrTest_Sort(10000); - } -} -BENCHMARK(SharedPtrTestSort); - -TEST(SharedPtr, PerfTests) -{ - // Run all benchmarks - int argc = 0; - const char *argv[] = {""}; - ::benchmark::Initialize(&argc, (char **)(argv)); - ::benchmark::RunSpecifiedBenchmarks(); -} diff --git a/api/test/nostd/span_test.cc b/api/test/nostd/span_test.cc index 6d484bccad..8bfbf60f29 100644 --- a/api/test/nostd/span_test.cc +++ b/api/test/nostd/span_test.cc @@ -1,6 +1,5 @@ #include "opentelemetry/nostd/span.h" -#include #include #include @@ -187,60 +186,3 @@ TEST(SpanTest, Iteration) EXPECT_EQ(std::distance(s2.begin(), s2.end()), array.size()); EXPECT_TRUE(std::equal(s2.begin(), s2.end(), array.begin())); } - -static void SpanIterator(benchmark::State &state) -{ - constexpr size_t aSize = 100000; - std::array array{}; - for (size_t i = 0; i < aSize; i++) - { - array[i] = i; - } - span s1{array.data(), array.size()}; - for (auto _ : state) - { - size_t i = 0; - for (auto item : s1) - { - EXPECT_EQ(item, i); - i++; - } - } -} -BENCHMARK(SpanIterator); - -static void SpanConstructor(benchmark::State &state) -{ - constexpr size_t aSize = 1000000; - auto *aInt16 = new std::array{}; - auto *aInt32 = new std::array{}; - auto *aInt64 = new std::array{}; - for (size_t i = 0; i < aSize; i++) - { - (*aInt16)[i] = i; - (*aInt32)[i] = i; - (*aInt64)[i] = i; - } - size_t j = aSize; - for (auto _ : state) - { - benchmark::DoNotOptimize([&] { - span s1{aInt16->data(), aInt16->size()}; - span s2{aInt32->data(), aInt32->size()}; - span s3{aInt64->data(), aInt64->size()}; - }); - } - delete aInt16; - delete aInt32; - delete aInt64; -} -BENCHMARK(SpanConstructor); - -TEST(SpanTest, PerfTests) -{ - // Run all benchmarks - int argc = 0; - const char *argv[] = {""}; - ::benchmark::Initialize(&argc, (char **)(argv)); - ::benchmark::RunSpecifiedBenchmarks(); -} diff --git a/api/test/nostd/string_view_test.cc b/api/test/nostd/string_view_test.cc index 01cbd29ce6..3673082cca 100644 --- a/api/test/nostd/string_view_test.cc +++ b/api/test/nostd/string_view_test.cc @@ -2,9 +2,6 @@ #include -#include -#include -#include #include using opentelemetry::nostd::string_view; @@ -105,111 +102,3 @@ TEST(StringViewTest, MapKeyOrdering) i++; } } - -static void StringViewSubStr(benchmark::State &state) -{ - std::string s = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - for (auto _ : state) - { - string_view sv = s; - auto oneSv = sv.substr(0, 5); - auto twoSv = sv.substr(6, 5); - auto threeSv = sv.substr(12, 5); - auto fourSv = sv.substr(18, 11); - auto fiveSv = sv.substr(30, 5); - benchmark::DoNotOptimize(oneSv); - benchmark::DoNotOptimize(twoSv); - benchmark::DoNotOptimize(threeSv); - benchmark::DoNotOptimize(fourSv); - benchmark::DoNotOptimize(fiveSv); - } -} -BENCHMARK(StringViewSubStr); - -static void StringViewMaps(benchmark::State &state) -{ - std::map m; - std::string txt; - size_t i = 0; - for (auto _ : state) - { - i %= 200; // up to 200 key-value pairs in this collection - m[string_view(std::to_string(i))] = string_view(std::to_string(i)); - i += 1; - }; -} -BENCHMARK(StringViewMaps); - -static void StringViewFromCString(benchmark::State &state) -{ - std::string s = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - for (auto _ : state) - { - string_view sv(s.c_str()); - // scan thru string_view - for (const auto &c : sv) - ; - }; -} -BENCHMARK(StringViewFromCString); - -static void StringViewToString(benchmark::State &state) -{ - string_view s = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - std::string txt; - for (auto _ : state) - { - txt = std::string(s.data(), s.length()); - }; -} -BENCHMARK(StringViewToString); - -static void StringViewExplode(benchmark::State &state) -{ - for (auto _ : state) - { - string_view sv = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - std::string s; - for (size_t i = 0; i < 5; i++) - { - s += std::string(sv.data(), sv.length()); - sv = s; - string_view sv2 = s; - if (sv == sv2) - ; // FIXME: Warning C4390 ';' : empty controlled statement found; is this the intent ? - } - }; -} -BENCHMARK(StringViewExplode); - -static void StringViewVector(benchmark::State &state) -{ - std::vector v; - for (auto _ : state) - { - string_view sv = - "Hello OpenTelemetry nostd::string_view implementation! Feel free to evaluate my " - "performance."; - v.push_back(sv); - if (v.size() > 10000) - v.clear(); - } -} -BENCHMARK(StringViewVector); - -TEST(StringView, PerfTests) -{ - // Run all benchmarks - int argc = 0; - const char *argv[] = {""}; - ::benchmark::Initialize(&argc, (char **)(argv)); - ::benchmark::RunSpecifiedBenchmarks(); -} diff --git a/docs/building-with-stdlib.md b/docs/building-with-stdlib.md index 63ae284c0b..ed0911aa1a 100644 --- a/docs/building-with-stdlib.md +++ b/docs/building-with-stdlib.md @@ -5,11 +5,9 @@ process (environment where ABI compat is not a requirement), or for "header-only" implementation of SDK. Proposed approach cannot be employed for shared libs in environments where -ABI compatibility is required: - -- OpenTelemetry SDK binary compiled with compiler A + STL B -- may not be ABI compatible with the main executable compiled with compiler - C + STL D on a same OS. +ABI compatibility is required. OpenTelemetry SDK binary compiled with +`compiler A + STL B` will not be ABI -compatible with the main executable +compiled with `compiler C + STL D`. In addition to standard library, similar approach can be reused to implement the API surface classes with [Abseil classes](https://abseil.io/) instead of @@ -142,8 +140,9 @@ Supported build flavors: for `std::span` implementation (`gsl::span` or `absl::Span`). - `absl` - TODO: this should allow using Abseil C++ library only (no MS-GSL). -Currently only `nostd` and `stdlib` configurations are implemented. -`absl` is reserved for future use. +Currently only `nostd` and `stdlib` configurations are implemented in CMake build. +`absl` is reserved for future use. Build systems other than CMake need to +`#define HAVE_CPP_STDLIB` to enable the Standard Library classes. ### Build matrix @@ -189,4 +188,4 @@ expectations. CI allows to validate that all OpenTelemetry functionality is working the same identical way irrespective of what C++ runtime / STL library it is compiled -with. Additional performance benchmarks were added. +with. From 1f0519793433609f24998999e64cd110cb4a05c9 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 21 Dec 2020 12:52:10 -0800 Subject: [PATCH 52/54] Update submodules to latest stable --- third_party/benchmark | 2 +- third_party/opentelemetry-proto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/benchmark b/third_party/benchmark index dce3322a54..bf585a2789 160000 --- a/third_party/benchmark +++ b/third_party/benchmark @@ -1 +1 @@ -Subproject commit dce3322a549650d18f50b5f1428a5942327ab6a5 +Subproject commit bf585a2789e30585b4e3ce6baf11ef2750b54677 diff --git a/third_party/opentelemetry-proto b/third_party/opentelemetry-proto index 59c488bfb8..286810dc20 160000 --- a/third_party/opentelemetry-proto +++ b/third_party/opentelemetry-proto @@ -1 +1 @@ -Subproject commit 59c488bfb8fb6d0458ad6425758b70259ff4a2bd +Subproject commit 286810dc20d40f6483abf719f2b8de28f543fc78 From 46572b4814b5d456cc77aad7438cccef9e788bb0 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 21 Dec 2020 13:00:48 -0800 Subject: [PATCH 53/54] Fix formatting issue --- api/test/nostd/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index fdec960d9a..21c2197ced 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -4,8 +4,8 @@ foreach(testname function_ref_test string_view_test unique_ptr_test utility_test span_test shared_ptr_test) add_executable(${testname} "${testname}.cc") target_link_libraries( - ${testname} ${GTEST_BOTH_LIBRARIES} - ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests( TARGET ${testname} TEST_PREFIX nostd. From f0b5506e0719f5e4971cc66786a69359df0074c7 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 21 Dec 2020 13:01:13 -0800 Subject: [PATCH 54/54] Ignore Visual Studio temporary files directory --- tools/format.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/format.sh b/tools/format.sh index 2e9ad3fb54..523cceb75d 100755 --- a/tools/format.sh +++ b/tools/format.sh @@ -6,7 +6,7 @@ fi set -e -FIND="find . -name third_party -prune -o -name tools -prune -o -name .git -prune -o -name _deps -prune -o -name .build -prune -o -name out -prune -o" +FIND="find . -name third_party -prune -o -name tools -prune -o -name .git -prune -o -name _deps -prune -o -name .build -prune -o -name out -prune -o -name .vs -prune -o" # GNU syntax. SED=(sed -i)