diff --git a/.github/actions/prepare_vm/action.yaml b/.github/actions/prepare_vm/action.yaml index d95ab630e67..a953ed84387 100644 --- a/.github/actions/prepare_vm/action.yaml +++ b/.github/actions/prepare_vm/action.yaml @@ -67,15 +67,6 @@ runs: cmake --install . --config Release --prefix ~/ydb_deps/grpc cd ../../ - # Install base64 - wget -O base64-0.5.2.tar.gz https://github.com/aklomp/base64/archive/refs/tags/v0.5.2.tar.gz - tar -xvzf base64-0.5.2.tar.gz && cd base64-0.5.2 - mkdir build && cd build - cmake -G Ninja ${ENABLE_CCACHE} -DCMAKE_BUILD_TYPE=Release .. - cmake --build . --config Release - cmake --install . --config Release --prefix ~/ydb_deps/base64 - cd ../../ - # Install brotli wget -O brotli-1.1.0.tar.gz https://github.com/google/brotli/archive/refs/tags/v1.1.0.tar.gz tar -xvzf brotli-1.1.0.tar.gz && cd brotli-1.1.0 @@ -85,17 +76,8 @@ runs: cmake --install . --config Release --prefix ~/ydb_deps/brotli cd ../../ - # Install jwt-cpp - wget -O jwt-cpp-0.7.0.tar.gz https://github.com/Thalhammer/jwt-cpp/archive/refs/tags/v0.7.0.tar.gz - tar -xvzf jwt-cpp-0.7.0.tar.gz && cd jwt-cpp-0.7.0 - mkdir build && cd build - cmake -G Ninja ${ENABLE_CCACHE} -DCMAKE_BUILD_TYPE=Release .. - cmake --build . --config Release - cmake --install . --config Release --prefix ~/ydb_deps/jwt-cpp - cd ../../ - # Clean up ccache -s sudo rm -rf llvm.sh abseil-cpp-20230802.0.tar.gz protobuf-3.21.12.tar.gz grpc-1.54.3.tar.gz \ - base64-0.5.2.tar.gz brotli-1.1.0.tar.gz jwt-cpp-0.7.0.tar.gz abseil-cpp-20230802.0 \ - protobuf-3.21.12 grpc-1.54.3 base64-0.5.2 brotli-1.1.0 jwt-cpp-0.7.0 + brotli-1.1.0.tar.gz abseil-cpp-20230802.0 \ + protobuf-3.21.12 grpc-1.54.3 brotli-1.1.0 diff --git a/.github/workflows/release_publish.yaml b/.github/workflows/release_publish.yaml new file mode 100644 index 00000000000..6ab6dd96c17 --- /dev/null +++ b/.github/workflows/release_publish.yaml @@ -0,0 +1,128 @@ +name: Publish release artifacts + +on: + release: + types: [published] + workflow_dispatch: + inputs: + tag: + description: "Release tag to attach assets to (e.g. v1.2.3)" + required: true + type: string + +concurrency: + group: release-publish-${{ github.event.release.tag_name || inputs.tag }} + cancel-in-progress: false + +permissions: + contents: write + +jobs: + build-and-upload-debs: + name: "Build .deb packages and attach to release (Ubuntu 24.04 / noble)" + runs-on: ubuntu-latest + steps: + - name: Resolve release tag + id: tag + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT" + echo "ref=${{ inputs.tag }}" >> "$GITHUB_OUTPUT" + else + echo "tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT" + echo "ref=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT" + fi + + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + ref: ${{ steps.tag.outputs.ref }} + + - name: Build .deb packages in Ubuntu 24.04 container + shell: bash + run: | + mkdir -p artifacts + docker run --rm --network host \ + -v "$PWD:/source" \ + ubuntu:24.04 \ + bash -c ' + set -e + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install -y \ + build-essential \ + cmake \ + pkg-config \ + git \ + libidn11-dev \ + libssl-dev \ + zlib1g-dev \ + libprotobuf-dev \ + protobuf-compiler \ + libgrpc++-dev \ + protobuf-compiler-grpc \ + libbrotli-dev \ + liblz4-dev \ + libzstd-dev \ + libbz2-dev \ + libxxhash-dev \ + libsnappy-dev \ + libdouble-conversion-dev \ + libgtest-dev \ + libre2-dev \ + libc-ares-dev \ + rapidjson-dev \ + python3 \ + python3-six \ + ragel \ + yasm + + cd /source + cmake -S scripts/googleapis_deb -B build_googleapis_deb -DCMAKE_INSTALL_PREFIX=/usr/share/yandex + cmake --build build_googleapis_deb -j$(nproc) + cmake --build build_googleapis_deb --target package + dpkg -i build_googleapis_deb/*.deb + + ./scripts/generate-debian-directory.sh + cmake -S . -B build-deb \ + -DCMAKE_BUILD_TYPE=Release \ + -DYDB_SDK_INSTALL=ON \ + -DYDB_SDK_EXAMPLES=OFF \ + -DYDB_SDK_TESTS=OFF \ + -DYDB_SDK_ENABLE_OTEL_METRICS=ON \ + -DYDB_SDK_ENABLE_OTEL_TRACE=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DYDB_SDK_USE_SYSTEM_GOOGLEAPIS=ON \ + -DCMAKE_INSTALL_PREFIX=/usr/share/yandex \ + -DCMAKE_PREFIX_PATH="/usr/share/yandex" + cmake --build build-deb --target package -j$(nproc) + + cp build_googleapis_deb/*.deb /source/artifacts/ + cp build-deb/*.deb /source/artifacts/ + ' + + - name: Smoke-test generated .deb packages + shell: bash + run: | + ./scripts/test_deb_packages.sh artifacts + + - name: List built artifacts + shell: bash + run: ls -la artifacts/ + + - name: Upload .deb files to GitHub release + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + gh release upload "${{ steps.tag.outputs.tag }}" artifacts/*.deb --clobber + + - name: Upload .deb files as workflow artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: deb-packages-${{ steps.tag.outputs.tag }} + path: artifacts/*.deb + if-no-files-found: warn + retention-days: 30 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4eb73216f68..f0816775abb 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -177,4 +177,94 @@ jobs: if [ -z "$(ls -A ./_install)" ]; then echo "Error: Installation directory is empty!" exit 1 - fi \ No newline at end of file + fi + + deb-packages: + name: "Test Debian Packages" + concurrency: + group: deb-packages-${{ github.ref }} + cancel-in-progress: true + runs-on: ubuntu-latest + steps: + - name: Checkout PR + uses: actions/checkout@v4 + if: github.event.pull_request.head.sha != '' + with: + submodules: true + ref: ${{ github.event.pull_request.head.sha }} + + - name: Checkout + uses: actions/checkout@v4 + if: github.event.pull_request.head.sha == '' + with: + submodules: true + + - name: Validate dpkg-buildpackage + shell: bash + run: | + ./scripts/test_dpkg_buildpackage.sh + + - name: Build CPack .deb packages + shell: bash + run: | + docker run --rm --network host \ + -v "$PWD:/source" \ + ubuntu:24.04 \ + bash -c ' + set -e + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install -y \ + build-essential \ + cmake \ + pkg-config \ + git \ + libidn11-dev \ + libssl-dev \ + zlib1g-dev \ + libprotobuf-dev \ + protobuf-compiler \ + libgrpc++-dev \ + protobuf-compiler-grpc \ + libbrotli-dev \ + liblz4-dev \ + libzstd-dev \ + libbz2-dev \ + libxxhash-dev \ + libsnappy-dev \ + libdouble-conversion-dev \ + libgtest-dev \ + libre2-dev \ + libc-ares-dev \ + rapidjson-dev \ + python3 \ + python3-six \ + ragel \ + yasm + + cd /source + cmake -S scripts/googleapis_deb -B build_googleapis_deb -DCMAKE_INSTALL_PREFIX=/usr/share/yandex + cmake --build build_googleapis_deb -j$(nproc) + cmake --build build_googleapis_deb --target package + dpkg -i build_googleapis_deb/*.deb + + ./scripts/generate-debian-directory.sh + cmake -S . -B build-deb \ + -DCMAKE_BUILD_TYPE=Release \ + -DYDB_SDK_INSTALL=ON \ + -DYDB_SDK_EXAMPLES=OFF \ + -DYDB_SDK_TESTS=OFF \ + -DYDB_SDK_ENABLE_OTEL_METRICS=ON \ + -DYDB_SDK_ENABLE_OTEL_TRACE=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DYDB_SDK_USE_SYSTEM_GOOGLEAPIS=ON \ + -DCMAKE_INSTALL_PREFIX=/usr/share/yandex \ + -DCMAKE_PREFIX_PATH="/usr/share/yandex" + cmake --build build-deb --target package -j$(nproc) + cp build_googleapis_deb/*.deb build-deb/ + ' + + - name: Smoke-test generated .deb packages + shell: bash + run: | + ./scripts/test_deb_packages.sh build-deb \ No newline at end of file diff --git a/.gitignore b/.gitignore index dbe9ebc55e5..cf184074ffb 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,4 @@ CMakeUserPresets.json # Dev Containers !Dockerfile +debian/ diff --git a/.gitmodules b/.gitmodules index ddeadcf3e65..d5951cffaab 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,12 @@ [submodule "third_party/FastLZ"] path = third_party/FastLZ url = https://github.com/ariya/FastLZ +[submodule "third_party/aklomp-base64"] + path = third_party/aklomp-base64 + url = https://github.com/aklomp/base64.git +[submodule "third_party/jwt-cpp"] + path = third_party/jwt-cpp + url = https://github.com/Thalhammer/jwt-cpp.git +[submodule "third_party/opentelemetry-cpp"] + path = third_party/opentelemetry-cpp + url = https://github.com/open-telemetry/opentelemetry-cpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 6df450c510c..f4177996491 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,12 +73,83 @@ if (YDB_SDK_TESTS) endif() if (YDB_SDK_INSTALL) + function(_ydb_sdk_create_package_library PackageProp TargetName ComponentName) + foreach(Tgt IN LISTS YDB_CPP_${PackageProp}_COMPONENT_TARGETS) + _ydb_sdk_collect_package_target(${PackageProp} ${Tgt}) + endforeach() + + get_property(PackageSources GLOBAL PROPERTY YDB_CPP_${PackageProp}_SOURCES) + if (NOT PackageSources) + return() + endif() + + get_property(PackageInternalDeps GLOBAL PROPERTY YDB_CPP_${PackageProp}_INTERNAL_DEPS) + get_property(PackagePublicDeps GLOBAL PROPERTY YDB_CPP_${PackageProp}_PUBLIC_DEPS) + get_property(PackagePublicOpts GLOBAL PROPERTY YDB_CPP_${PackageProp}_PUBLIC_OPTS) + get_property(PackagePublicDefs GLOBAL PROPERTY YDB_CPP_${PackageProp}_PUBLIC_DEFS) + get_property(PackageIncludeDirs GLOBAL PROPERTY YDB_CPP_${PackageProp}_INCLUDE_DIRS) + + list(REMOVE_DUPLICATES PackageSources) + if (PackageInternalDeps) + list(REMOVE_DUPLICATES PackageInternalDeps) + endif() + if (PackagePublicDeps) + list(REMOVE_DUPLICATES PackagePublicDeps) + list(REMOVE_ITEM PackagePublicDeps ${PackageInternalDeps}) + endif() + if (PackagePublicOpts) + list(REMOVE_DUPLICATES PackagePublicOpts) + endif() + if (PackagePublicDefs) + list(REMOVE_DUPLICATES PackagePublicDefs) + endif() + if (PackageIncludeDirs) + list(REMOVE_DUPLICATES PackageIncludeDirs) + endif() + + foreach(src IN LISTS PackageSources) + if (NOT EXISTS "${src}") + set_source_files_properties("${src}" PROPERTIES GENERATED TRUE) + endif() + endforeach() + + add_library(${TargetName} STATIC ${PackageSources}) + target_include_directories(${TargetName} PUBLIC + $ + $ + $ + $ + $ + ) + target_include_directories(${TargetName} PRIVATE + ${PackageIncludeDirs} + ) + if (TargetName STREQUAL "libydb-cpp") + set_target_properties(${TargetName} PROPERTIES OUTPUT_NAME ydb-cpp) + endif() + target_compile_definitions(${TargetName} PUBLIC YDB_SDK_OSS ${PackagePublicDefs}) + target_link_libraries(${TargetName} PUBLIC ${PackagePublicDeps}) + if (PackageInternalDeps) + add_dependencies(${TargetName} ${PackageInternalDeps}) + endif() + if (PackagePublicOpts) + target_compile_options(${TargetName} PUBLIC ${PackagePublicOpts}) + endif() + _ydb_sdk_install_targets(TARGETS ${TargetName} COMPONENT ${ComponentName}) + endfunction() + + _ydb_sdk_create_package_library(CORE libydb-cpp libydb-cpp) + _ydb_sdk_create_package_library(LIBYDB_CPP_IAM ydb-cpp-iam libydb-cpp-iam) + _ydb_sdk_create_package_library(LIBYDB_CPP_OTEL_METRICS ydb-cpp-otel-metrics libydb-cpp-otel-metrics) + _ydb_sdk_create_package_library(LIBYDB_CPP_OTEL_TRACING ydb-cpp-otel-tracing libydb-cpp-otel-tracing) + _ydb_sdk_install_headers(${CMAKE_INSTALL_INCLUDEDIR}) install(EXPORT ydb-cpp-sdk-targets FILE ydb-cpp-sdk-targets.cmake CONFIGURATIONS RELEASE NAMESPACE YDB-CPP-SDK:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ydb-cpp-sdk/release + COMPONENT libydb-cpp ) configure_package_config_file( ${YDB_SDK_SOURCE_DIR}/cmake/ydb-cpp-sdk-config.cmake.in diff --git a/CMakePresets.json b/CMakePresets.json index d33c11b6811..36cc5b8413d 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -11,7 +11,7 @@ "displayName": "Generic Config", "cacheVariables": { "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", - "CMAKE_PREFIX_PATH": "~/ydb_deps/absl;~/ydb_deps/protobuf;~/ydb_deps/grpc;~/ydb_deps/base64;~/ydb_deps/brotli;~/ydb_deps/jwt-cpp" + "CMAKE_PREFIX_PATH": "~/ydb_deps/absl;~/ydb_deps/protobuf;~/ydb_deps/grpc;~/ydb_deps/brotli" }, "generator": "Ninja", "binaryDir": "${sourceDir}/build" @@ -65,6 +65,22 @@ "inherits": ["release-base", "clang-toolchain"], "displayName": "Default Release Config (Clang)" }, + { + "name": "package-deb-clang", + "inherits": ["release-base", "clang-toolchain"], + "displayName": "Package Config (Clang) for .deb", + "binaryDir": "${sourceDir}/build-deb", + "cacheVariables": { + "YDB_SDK_INSTALL": "ON", + "YDB_SDK_ENABLE_OTEL_METRICS": "ON", + "YDB_SDK_ENABLE_OTEL_TRACE": "ON", + "YDB_SDK_EXAMPLES": "OFF", + "BUILD_SHARED_LIBS": "OFF", + "CMAKE_EXE_LINKER_FLAGS": "", + "CMAKE_SHARED_LINKER_FLAGS": "", + "CMAKE_PREFIX_PATH": "~/ydb_deps/absl;~/ydb_deps/protobuf;~/ydb_deps/grpc;~/ydb_deps/brotli;~/ydb_deps/opentelemetry-cpp-install" + } + }, { "name": "release-gcc", "inherits": ["release-base", "gcc-toolchain"], diff --git a/README.md b/README.md index e53fb359d9c..564c69b1fc8 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,79 @@ cmake --preset $sdk_configure_preset cmake --build --preset $sdk_configure_preset ``` +### Build `.deb` packages + +The SDK can be packaged as Debian development packages with CPack. The packaging build uses static libraries and produces the following packages: + +- `libydb-cpp-dev` — core SDK static library, public headers and CMake package files; +- `libydb-cpp-iam-dev` — IAM credentials plugin; +- `libydb-cpp-otel-metrics-dev` — OpenTelemetry metrics plugin; +- `libydb-cpp-otel-tracing-dev` — OpenTelemetry tracing plugin. + +The Debian packaging flow is intended for Ubuntu 24.04. Install the regular build dependencies first. If OpenTelemetry plugins are enabled, install `opentelemetry-cpp` as a CMake package as well; the default `package-deb-clang` preset expects it in `~/ydb_deps/opentelemetry-cpp-install`. + +To build `.deb` packages directly with CPack: + +```bash +cmake --preset package-deb-clang +cmake --build build-deb --target package -j$(nproc) +``` + +The generated `.deb` files are placed into `build-deb/`. + +To prepare Debian source-package metadata, run: + +```bash +./scripts/generate-debian-directory.sh +``` + +This updates `debian/changelog` from `src/version.h` and the current Git commit. The `debian/` directory contains package metadata and install manifests for `dpkg-buildpackage`/PPA builds. + +To validate a binary Debian package build in an Ubuntu 24.04 Docker container: + +```bash +./scripts/test_dpkg_buildpackage.sh +``` + +To smoke-test generated `.deb` packages with the sample consumer project: + +```bash +./scripts/test_deb_packages.sh build-deb +``` + +### Install from GitHub releases + +Pre-built `.deb` packages for Ubuntu 24.04 (Noble) are attached to each +GitHub release. Download the assets and install them with `dpkg`: + +```bash +# Replace with the desired release tag (e.g. v1.2.3) +TAG= +BASE="https://github.com/ydb-platform/ydb-cpp-sdk/releases/download/${TAG}" + +wget "${BASE}/yandex-googleapis-api-common-protos_1.0.0_amd64.deb" +wget "${BASE}/libydb-cpp-dev_${TAG#v}_amd64.deb" +# Optional plugins: +wget "${BASE}/libydb-cpp-iam-dev_${TAG#v}_amd64.deb" +wget "${BASE}/libydb-cpp-otel-metrics-dev_${TAG#v}_amd64.deb" +wget "${BASE}/libydb-cpp-otel-tracing-dev_${TAG#v}_amd64.deb" + +sudo dpkg -i yandex-googleapis-api-common-protos_*.deb +sudo dpkg -i libydb-cpp-dev_*.deb libydb-cpp-iam-dev_*.deb \ + libydb-cpp-otel-metrics-dev_*.deb libydb-cpp-otel-tracing-dev_*.deb +sudo apt-get install -f # resolve any remaining dependencies +``` + +After installation, use the SDK in your CMake project: + +```cmake +find_package(ydb-cpp-sdk REQUIRED COMPONENTS Driver Table Topic) +target_link_libraries(myapp PRIVATE YDB-CPP-SDK::Driver YDB-CPP-SDK::Table) +``` + +Pass `-DCMAKE_PREFIX_PATH=/usr/share/yandex` since the packages install +under the Yandex prefix. + ### Test Specify a level of parallelism by passing the `-j` option into the command below (e.g. `-j$(nproc)`) diff --git a/cmake/PackSDK.cmake b/cmake/PackSDK.cmake index c500eeebf9e..4d80d4f3918 100644 --- a/cmake/PackSDK.cmake +++ b/cmake/PackSDK.cmake @@ -7,17 +7,36 @@ set(CPACK_PACKAGE_DESCRIPTION with strict consistency and ACID transactions." ) -set(CPACK_PACKAGE_NAME "ydb-cpp-sdk-dev") +set(CPACK_PACKAGE_NAME "ydb-cpp-sdk") set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) set(CPACK_GENERATOR "DEB") set(CPACK_PACKAGE_VERSION "${YDB_SDK_VERSION}") set(CPACK_PACKAGE_HOMEPAGE_URL "https://ydb.tech") set(CPACK_PACKAGE_CONTACT "YDB Team ") # TODO set(CPACK_RESOURCE_FILE_LICENSE "${YDB_SDK_SOURCE_DIR}/LICENSE") -# TODO add more parameters -# TODO specify package dependencies -# set(CPACK_DEBIAN_PACKAGE_DEPENDS "liblz4-dev libdouble-conversion-dev libssl-dev") +set(CPACK_DEB_COMPONENT_INSTALL ON) +set(CPACK_COMPONENTS_ALL libydb-cpp libydb-cpp-iam libydb-cpp-otel-metrics libydb-cpp-otel-tracing) + +set(CPACK_DEBIAN_LIBYDB_CPP_PACKAGE_NAME "libydb-cpp-dev") +set(CPACK_DEBIAN_LIBYDB_CPP_PACKAGE_DEPENDS + "libidn11-dev, libssl-dev, zlib1g-dev, libprotobuf-dev, libgrpc++-dev, libbrotli-dev, liblz4-dev, libzstd-dev, libbz2-dev, libxxhash-dev, libsnappy-dev, libdouble-conversion-dev, libgtest-dev, libre2-dev, libc-ares-dev, rapidjson-dev" +) + +set(CPACK_DEBIAN_LIBYDB_CPP_IAM_PACKAGE_NAME "libydb-cpp-iam-dev") +set(CPACK_DEBIAN_LIBYDB_CPP_IAM_PACKAGE_DEPENDS "libydb-cpp-dev (= ${YDB_SDK_VERSION})") + +set(CPACK_DEBIAN_LIBYDB_CPP_OTEL_METRICS_PACKAGE_NAME "libydb-cpp-otel-metrics-dev") +set(CPACK_DEBIAN_LIBYDB_CPP_OTEL_METRICS_PACKAGE_DEPENDS "libydb-cpp-dev (= ${YDB_SDK_VERSION})") + +set(CPACK_DEBIAN_LIBYDB_CPP_OTEL_TRACING_PACKAGE_NAME "libydb-cpp-otel-tracing-dev") +set(CPACK_DEBIAN_LIBYDB_CPP_OTEL_TRACING_PACKAGE_DEPENDS "libydb-cpp-dev (= ${YDB_SDK_VERSION})") + +foreach(component IN ITEMS libydb-cpp libydb-cpp-iam libydb-cpp-otel-metrics libydb-cpp-otel-tracing) + string(TOUPPER "${component}" component_upper) + string(REPLACE "-" "_" component_var "${component_upper}") + set("CPACK_DEBIAN_${component_upper}_PACKAGE_NAME" "${CPACK_DEBIAN_${component_var}_PACKAGE_NAME}") + set("CPACK_DEBIAN_${component_upper}_PACKAGE_DEPENDS" "${CPACK_DEBIAN_${component_var}_PACKAGE_DEPENDS}") +endforeach() -# TODO use lintian in CI to check deb package include(CPack) diff --git a/cmake/common.cmake b/cmake/common.cmake index bd017425190..fe2d5f30250 100644 --- a/cmake/common.cmake +++ b/cmake/common.cmake @@ -175,9 +175,28 @@ endfunction() function(_ydb_sdk_make_client_component CmpName Tgt) add_library(YDB-CPP-SDK::${CmpName} ALIAS ${Tgt}) - _ydb_sdk_install_targets(TARGETS ${Tgt} ${ARGN}) + if (CmpName STREQUAL "Iam" OR CmpName STREQUAL "IamPrivate") + set(PKG_COMP_NAME "libydb-cpp-iam") + elseif (CmpName STREQUAL "OpenTelemetryMetrics") + set(PKG_COMP_NAME "libydb-cpp-otel-metrics") + elseif (CmpName STREQUAL "OpenTelemetryTrace") + set(PKG_COMP_NAME "libydb-cpp-otel-tracing") + else() + set(PKG_COMP_NAME "libydb-cpp") + endif() + set(YDB-CPP-SDK_AVAILABLE_COMPONENTS ${YDB-CPP-SDK_AVAILABLE_COMPONENTS} ${CmpName} CACHE INTERNAL "") - set(YDB-CPP-SDK_COMPONENT_TARGETS ${YDB-CPP-SDK_COMPONENT_TARGETS} ${Tgt} CACHE INTERNAL "") + + if (PKG_COMP_NAME STREQUAL "libydb-cpp") + set(YDB_CPP_CORE_COMPONENT_TARGETS ${YDB_CPP_CORE_COMPONENT_TARGETS} ${Tgt} ${ARGN} CACHE INTERNAL "") + set(YDB-CPP-SDK_COMPONENT_TARGETS ${YDB-CPP-SDK_COMPONENT_TARGETS} libydb-cpp CACHE INTERNAL "") + else() + string(REPLACE "-" "_" PKG_PROP_NAME "${PKG_COMP_NAME}") + string(TOUPPER "${PKG_PROP_NAME}" PKG_PROP_NAME) + set(YDB_CPP_${PKG_PROP_NAME}_COMPONENT_TARGETS ${YDB_CPP_${PKG_PROP_NAME}_COMPONENT_TARGETS} ${Tgt} ${ARGN} CACHE INTERNAL "") + string(REGEX REPLACE "^lib" "" PKG_TARGET_NAME "${PKG_COMP_NAME}") + set(YDB-CPP-SDK_COMPONENT_TARGETS ${YDB-CPP-SDK_COMPONENT_TARGETS} ${PKG_TARGET_NAME} CACHE INTERNAL "") + endif() endfunction() function(_ydb_sdk_add_library Tgt) @@ -192,6 +211,7 @@ function(_ydb_sdk_add_library Tgt) set(libraryMode "INTERFACE") set(includeMode "INTERFACE") endif() + add_library(${Tgt} ${libraryMode}) target_include_directories(${Tgt} ${includeMode} $ @@ -201,6 +221,156 @@ function(_ydb_sdk_add_library Tgt) target_compile_definitions(${Tgt} ${includeMode} YDB_SDK_OSS ) + +endfunction() + +function(_ydb_sdk_b64_set_codec_file BASE64_SRC_ROOT simd subdir) + set(_var "COMPILE_FLAGS_${simd}") + if (NOT DEFINED ${_var}) + return() + endif() + set(_flags "${${_var}}") + if (_flags STREQUAL " ") + return() + endif() + set(_codec_c "${BASE64_SRC_ROOT}/lib/arch/${subdir}/codec.c") + if (EXISTS "${_codec_c}") + set_source_files_properties("${_codec_c}" PROPERTIES COMPILE_FLAGS "${_flags}") + endif() +endfunction() + +# aklomp/base64 sets per-file COMPILE_FLAGS in its subdirectory; those properties are not +# visible when the same absolute paths are added to package static libs at the top level. +# Re-apply SIMD flags using the same compiler settings as third_party/aklomp-base64. +function(_ydb_sdk_apply_aklomp_base64_simd_file_flags BASE64_SRC_ROOT) + if (NOT IS_DIRECTORY "${BASE64_SRC_ROOT}") + return() + endif() + if (NOT EXISTS "${BASE64_SRC_ROOT}/cmake/Modules/TargetSIMDInstructionSet.cmake") + return() + endif() + include("${BASE64_SRC_ROOT}/cmake/Modules/TargetSIMDInstructionSet.cmake") + define_SIMD_compile_flags() + _ydb_sdk_b64_set_codec_file("${BASE64_SRC_ROOT}" SSSE3 ssse3) + _ydb_sdk_b64_set_codec_file("${BASE64_SRC_ROOT}" SSE41 sse41) + _ydb_sdk_b64_set_codec_file("${BASE64_SRC_ROOT}" SSE42 sse42) + _ydb_sdk_b64_set_codec_file("${BASE64_SRC_ROOT}" AVX avx) + _ydb_sdk_b64_set_codec_file("${BASE64_SRC_ROOT}" AVX2 avx2) + _ydb_sdk_b64_set_codec_file("${BASE64_SRC_ROOT}" AVX512 avx512) +endfunction() + +function(_ydb_sdk_collect_package_target PackageName Tgt) + if (NOT TARGET ${Tgt}) + return() + endif() + + get_target_property(aliased_target ${Tgt} ALIASED_TARGET) + if (aliased_target) + set(Tgt ${aliased_target}) + endif() + + get_target_property(imported_target ${Tgt} IMPORTED) + if (imported_target) + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_PUBLIC_DEPS ${Tgt}) + return() + endif() + + get_property(visited_targets GLOBAL PROPERTY YDB_CPP_${PackageName}_VISITED_TARGETS) + if (Tgt IN_LIST visited_targets) + return() + endif() + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_VISITED_TARGETS ${Tgt}) + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_INTERNAL_DEPS ${Tgt}) + + get_target_property(tgt_type ${Tgt} TYPE) + if (tgt_type STREQUAL "STATIC_LIBRARY" OR tgt_type STREQUAL "OBJECT_LIBRARY") + get_target_property(tgt_srcs ${Tgt} SOURCES) + get_target_property(tgt_source_dir ${Tgt} SOURCE_DIR) + if (tgt_srcs) + set(resolved_srcs "") + foreach(src IN LISTS tgt_srcs) + if (NOT src MATCHES "^\\$<") + if (NOT IS_ABSOLUTE "${src}") + set(src "${tgt_source_dir}/${src}") + endif() + list(APPEND resolved_srcs "${src}") + endif() + endforeach() + if (resolved_srcs) + get_target_property(tgt_compile_defs ${Tgt} COMPILE_DEFINITIONS) + get_target_property(tgt_compile_opts ${Tgt} COMPILE_OPTIONS) + foreach(resolved_src IN LISTS resolved_srcs) + get_source_file_property(_file_simd_flags ${resolved_src} COMPILE_FLAGS) + if (_file_simd_flags STREQUAL "NOTFOUND") + set(_file_simd_flags "") + endif() + get_source_file_property(_file_defs ${resolved_src} COMPILE_DEFINITIONS) + if (_file_defs STREQUAL "NOTFOUND") + set(_file_defs "") + endif() + + if (tgt_compile_defs) + if (_file_defs) + set_source_files_properties(${resolved_src} PROPERTIES + COMPILE_DEFINITIONS "${_file_defs};${tgt_compile_defs}") + else() + set_source_files_properties(${resolved_src} PROPERTIES + COMPILE_DEFINITIONS "${tgt_compile_defs}") + endif() + elseif (_file_defs) + set_source_files_properties(${resolved_src} PROPERTIES + COMPILE_DEFINITIONS "${_file_defs}") + endif() + + if (tgt_compile_opts) + set_source_files_properties(${resolved_src} PROPERTIES COMPILE_OPTIONS "${tgt_compile_opts}") + endif() + + if (_file_simd_flags) + set_source_files_properties(${resolved_src} PROPERTIES COMPILE_FLAGS "${_file_simd_flags}") + endif() + endforeach() + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_SOURCES ${resolved_srcs}) + endif() + endif() + endif() + + foreach(prop IN ITEMS INCLUDE_DIRECTORIES INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(target_include_dirs ${Tgt} ${prop}) + if (target_include_dirs) + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_INCLUDE_DIRS ${target_include_dirs}) + endif() + endforeach() + + foreach(prop IN ITEMS LINK_LIBRARIES INTERFACE_LINK_LIBRARIES) + get_target_property(target_deps ${Tgt} ${prop}) + if (target_deps) + foreach(dep IN LISTS target_deps) + if (dep MATCHES "^\\$<") + continue() + endif() + if (TARGET ${dep}) + _ydb_sdk_collect_package_target(${PackageName} ${dep}) + else() + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_PUBLIC_DEPS ${dep}) + endif() + endforeach() + endif() + endforeach() + + get_target_property(tgt_pub_opts ${Tgt} INTERFACE_COMPILE_OPTIONS) + if (tgt_pub_opts) + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_PUBLIC_OPTS ${tgt_pub_opts}) + endif() + + get_target_property(tgt_pub_defs ${Tgt} INTERFACE_COMPILE_DEFINITIONS) + if (tgt_pub_defs) + set_property(GLOBAL APPEND PROPERTY YDB_CPP_${PackageName}_PUBLIC_DEFS ${tgt_pub_defs}) + endif() +endfunction() + +function(_ydb_sdk_collect_core_target Tgt) + _ydb_sdk_collect_package_target(CORE ${Tgt}) endfunction() function(_ydb_sdk_validate_public_headers) diff --git a/cmake/external_libs.cmake b/cmake/external_libs.cmake index 4560fd662b3..334dc480884 100644 --- a/cmake/external_libs.cmake +++ b/cmake/external_libs.cmake @@ -9,14 +9,117 @@ find_package(ZSTD REQUIRED) find_package(BZip2 REQUIRED) find_package(LZ4 REQUIRED) find_package(Snappy 1.1.8 REQUIRED) -find_package(base64 REQUIRED) +set(_ydb_sdk_vendor_base64 "${YDB_SDK_SOURCE_DIR}/third_party/aklomp-base64") +set(_ydb_sdk_vendor_jwt_cpp "${YDB_SDK_SOURCE_DIR}/third_party/jwt-cpp") + +find_package(base64 QUIET) +if (NOT base64_FOUND) + if (EXISTS "${_ydb_sdk_vendor_base64}/CMakeLists.txt") + set(BASE64_WERROR OFF CACHE BOOL "" FORCE) + set(BASE64_BUILD_CLI OFF CACHE BOOL "" FORCE) + set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME libydb-cpp) + add_subdirectory("${_ydb_sdk_vendor_base64}" "${YDB_SDK_BINARY_DIR}/third_party/aklomp-base64") + _ydb_sdk_apply_aklomp_base64_simd_file_flags("${_ydb_sdk_vendor_base64}") + if (TARGET base64 AND NOT TARGET aklomp::base64) + add_library(aklomp::base64 ALIAS base64) + endif() + elseif (FETCHCONTENT_FULLY_DISCONNECTED) + message(FATAL_ERROR + "base64 is required but was not found (find_package), vendored sources are missing at " + "'${_ydb_sdk_vendor_base64}', and FETCHCONTENT_FULLY_DISCONNECTED=ON prevents FetchContent.") + else() + include(FetchContent) + FetchContent_Declare( + base64 + GIT_REPOSITORY https://github.com/aklomp/base64.git + GIT_TAG v0.5.2 + ) + set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME libydb-cpp) + FetchContent_MakeAvailable(base64) + get_target_property(_ydb_sdk_b64_src_dir base64 SOURCE_DIR) + _ydb_sdk_apply_aklomp_base64_simd_file_flags("${_ydb_sdk_b64_src_dir}") + if (TARGET base64 AND NOT TARGET aklomp::base64) + add_library(aklomp::base64 ALIAS base64) + endif() + endif() +endif() find_package(Brotli 1.1.0 REQUIRED) -find_package(jwt-cpp REQUIRED) +find_package(jwt-cpp QUIET) +if (NOT jwt-cpp_FOUND) + if (EXISTS "${_ydb_sdk_vendor_jwt_cpp}/CMakeLists.txt") + set(JWT_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + set(JWT_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME libydb-cpp) + add_subdirectory("${_ydb_sdk_vendor_jwt_cpp}" "${YDB_SDK_BINARY_DIR}/third_party/jwt-cpp") + elseif (FETCHCONTENT_FULLY_DISCONNECTED) + message(FATAL_ERROR + "jwt-cpp is required but was not found (find_package), vendored sources are missing at " + "'${_ydb_sdk_vendor_jwt_cpp}', and FETCHCONTENT_FULLY_DISCONNECTED=ON prevents FetchContent.") + else() + include(FetchContent) + FetchContent_Declare( + jwt-cpp + GIT_REPOSITORY https://github.com/Thalhammer/jwt-cpp.git + GIT_TAG v0.6.0 + ) + set(JWT_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + set(JWT_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME libydb-cpp) + FetchContent_MakeAvailable(jwt-cpp) + endif() +endif() find_package(double-conversion REQUIRED) # OpenTelemetry +set(_ydb_sdk_vendor_otel "${YDB_SDK_SOURCE_DIR}/third_party/opentelemetry-cpp") + if (YDB_SDK_ENABLE_OTEL_METRICS OR YDB_SDK_ENABLE_OTEL_TRACE) - find_package(opentelemetry-cpp REQUIRED) + find_package(opentelemetry-cpp QUIET) + if (NOT opentelemetry-cpp_FOUND) + set(BUILD_TESTING OFF CACHE BOOL "" FORCE) + set(WITH_OTLP_HTTP OFF CACHE BOOL "" FORCE) + set(WITH_OTLP_GRPC OFF CACHE BOOL "" FORCE) + set(WITH_PROMETHEUS OFF CACHE BOOL "" FORCE) + set(WITH_EXAMPLES OFF CACHE BOOL "" FORCE) + set(OTELCPP_MAINTAINER_MODE OFF CACHE BOOL "" FORCE) + set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "" FORCE) + set(WITH_STL "CXX20" CACHE STRING "" FORCE) + set(OPENTELEMETRY_INSTALL ON CACHE BOOL "" FORCE) + if (EXISTS "${_ydb_sdk_vendor_otel}/CMakeLists.txt") + add_subdirectory("${_ydb_sdk_vendor_otel}" "${YDB_SDK_BINARY_DIR}/third_party/opentelemetry-cpp") + elseif (FETCHCONTENT_FULLY_DISCONNECTED) + message(FATAL_ERROR + "opentelemetry-cpp is required but was not found (find_package), vendored sources are missing at " + "'${_ydb_sdk_vendor_otel}', and FETCHCONTENT_FULLY_DISCONNECTED=ON prevents FetchContent.") + else() + include(FetchContent) + FetchContent_Declare( + opentelemetry-cpp + GIT_REPOSITORY https://github.com/open-telemetry/opentelemetry-cpp.git + GIT_TAG v1.12.0 + ) + FetchContent_MakeAvailable(opentelemetry-cpp) + endif() + # Create namespaced aliases matching the installed opentelemetry-cpp::* targets + if (TARGET opentelemetry_api AND NOT TARGET opentelemetry-cpp::api) + add_library(opentelemetry-cpp::api ALIAS opentelemetry_api) + endif() + if (TARGET opentelemetry_metrics AND NOT TARGET opentelemetry-cpp::metrics) + add_library(opentelemetry-cpp::metrics ALIAS opentelemetry_metrics) + endif() + if (TARGET opentelemetry_trace AND NOT TARGET opentelemetry-cpp::trace) + add_library(opentelemetry-cpp::trace ALIAS opentelemetry_trace) + endif() + if (TARGET opentelemetry_common AND NOT TARGET opentelemetry-cpp::common) + add_library(opentelemetry-cpp::common ALIAS opentelemetry_common) + endif() + if (TARGET opentelemetry_resources AND NOT TARGET opentelemetry-cpp::resources) + add_library(opentelemetry-cpp::resources ALIAS opentelemetry_resources) + endif() + if (TARGET opentelemetry_version AND NOT TARGET opentelemetry-cpp::version) + add_library(opentelemetry-cpp::version ALIAS opentelemetry_version) + endif() + endif() endif() # RapidJSON @@ -31,7 +134,12 @@ if (YDB_SDK_USE_RAPID_JSON) endif() # api-common-protos -if (YDB_SDK_GOOGLE_COMMON_PROTOS_TARGET) +option(YDB_SDK_USE_SYSTEM_GOOGLEAPIS "Use system-provided yandex-googleapis-api-common-protos" OFF) + +if (YDB_SDK_USE_SYSTEM_GOOGLEAPIS) + find_package(yandex-googleapis-api-common-protos REQUIRED) + add_library(api-common-protos ALIAS yandex-googleapis-api-common-protos::api-common-protos) +elseif (YDB_SDK_GOOGLE_COMMON_PROTOS_TARGET) add_library(api-common-protos ALIAS ${YDB_SDK_GOOGLE_COMMON_PROTOS_TARGET}) else() file(MAKE_DIRECTORY ${YDB_SDK_BINARY_DIR}/third_party/api-common-protos) diff --git a/cmake/global_flags.cmake b/cmake/global_flags.cmake index 23837966df6..6cee71ada62 100644 --- a/cmake/global_flags.cmake +++ b/cmake/global_flags.cmake @@ -33,7 +33,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") # See: https://maskray.me/blog/2021-11-07-init-ctors-init-array string(APPEND COMMON_C_CXX_FLAGS " -fuse-init-array") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - string(APPEND COMMON_C_CXX_FLAGS " -fpermissive") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive") endif() endif() diff --git a/cmake/install.cmake b/cmake/install.cmake index 2c1334f01bd..be2742b9e6a 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -2,26 +2,36 @@ function(_ydb_sdk_install_targets) if (NOT YDB_SDK_INSTALL) return() endif() + set(oneValueArgs COMPONENT) set(multiValueArgs TARGETS) cmake_parse_arguments( - ARG "${option}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}" + ARG "${option}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) if (NOT ARG_TARGETS) message(FATAL_ERROR "No TARGETS given for install") return() endif() + if (NOT ARG_COMPONENT) + set(ARG_COMPONENT "libydb-cpp") + endif() foreach (ITEM_TARGET IN LISTS ARG_TARGETS) if(NOT TARGET ${ITEM_TARGET}) message(FATAL_ERROR "${ITEM_TARGET} is not target. You should use only targets") return() endif() endforeach() + if (ARG_COMPONENT STREQUAL "libydb-cpp") + list(FILTER ARG_TARGETS INCLUDE REGEX "^libydb-cpp$") + if (NOT ARG_TARGETS) + return() + endif() + endif() install(TARGETS ${ARG_TARGETS} EXPORT ydb-cpp-sdk-targets CONFIGURATIONS RELEASE - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${ARG_COMPONENT} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${ARG_COMPONENT} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${ARG_COMPONENT} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_INSTALL_INCLUDEDIR}/__ydb_sdk_special_headers @@ -32,10 +42,10 @@ function(_ydb_sdk_directory_install) if (NOT ${YDB_SDK_INSTALL}) return() endif() - set(oneValueArgs DESTINATION PATTERN) + set(oneValueArgs DESTINATION PATTERN COMPONENT EXCLUDE) set(multiValueArgs FILES DIRECTORY) cmake_parse_arguments( - ARG "${option}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}" + ARG "${option}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) if (NOT ARG_DESTINATION) message(FATAL_ERROR "No DESTINATION for install") @@ -46,13 +56,18 @@ function(_ydb_sdk_directory_install) if (ARG_FILES AND ARG_DIRECTORY) message(FATAL_ERROR "FILES and DIRECTORY are mutually exclusive install arguments") endif() + if (NOT ARG_COMPONENT) + set(ARG_COMPONENT "libydb-cpp") + endif() if (ARG_FILES) - install(FILES ${ARG_FILES} DESTINATION ${ARG_DESTINATION}) + install(FILES ${ARG_FILES} DESTINATION ${ARG_DESTINATION} COMPONENT ${ARG_COMPONENT}) else() if (DEFINED ARG_PATTERN) - install(DIRECTORY ${ARG_DIRECTORY} DESTINATION ${ARG_DESTINATION} USE_SOURCE_PERMISSIONS FILES_MATCHING PATTERN ${ARG_PATTERN}) + install(DIRECTORY ${ARG_DIRECTORY} DESTINATION ${ARG_DESTINATION} USE_SOURCE_PERMISSIONS COMPONENT ${ARG_COMPONENT} FILES_MATCHING PATTERN ${ARG_PATTERN}) + elseif (DEFINED ARG_EXCLUDE) + install(DIRECTORY ${ARG_DIRECTORY} DESTINATION ${ARG_DESTINATION} USE_SOURCE_PERMISSIONS COMPONENT ${ARG_COMPONENT} PATTERN ${ARG_EXCLUDE} EXCLUDE) else() - install(DIRECTORY ${ARG_DIRECTORY} DESTINATION ${ARG_DESTINATION} USE_SOURCE_PERMISSIONS) + install(DIRECTORY ${ARG_DIRECTORY} DESTINATION ${ARG_DESTINATION} USE_SOURCE_PERMISSIONS COMPONENT ${ARG_COMPONENT}) endif() endif() endfunction() @@ -61,27 +76,47 @@ function(_ydb_sdk_install_headers ArgIncludeDir) if (NOT ${YDB_SDK_INSTALL}) return() endif() - _ydb_sdk_directory_install(DIRECTORY ${YDB_SDK_SOURCE_DIR}/include/ydb-cpp-sdk - DESTINATION ${ArgIncludeDir} + set(oneValueArgs COMPONENT) + set(multiValueArgs DIRECTORY) + cmake_parse_arguments( + ARG "${option}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - - file(STRINGS ${YDB_SDK_SOURCE_DIR}/cmake/public_headers.txt PublicHeaders) - file(STRINGS ${YDB_SDK_SOURCE_DIR}/cmake/protos_public_headers.txt ProtosPublicHeaders) - if (NOT MSVC) - list(REMOVE_ITEM PublicHeaders library/cpp/deprecated/atomic/atomic_win.h) + if (NOT ARG_COMPONENT) + set(ARG_COMPONENT "libydb-cpp") endif() - foreach(HeaderPath ${PublicHeaders}) - get_filename_component(RelInstallPath ${HeaderPath} DIRECTORY) - _ydb_sdk_directory_install(FILES - ${YDB_SDK_SOURCE_DIR}/${HeaderPath} - DESTINATION ${ArgIncludeDir}/__ydb_sdk_special_headers/${RelInstallPath} + + if (ARG_DIRECTORY) + _ydb_sdk_directory_install(DIRECTORY ${ARG_DIRECTORY} + DESTINATION ${ArgIncludeDir} + COMPONENT ${ARG_COMPONENT} ) - endforeach() - foreach(HeaderPath ${ProtosPublicHeaders}) - get_filename_component(RelInstallPath ${HeaderPath} DIRECTORY) - _ydb_sdk_directory_install(FILES - ${YDB_SDK_BINARY_DIR}/${HeaderPath} - DESTINATION ${ArgIncludeDir}/__ydb_sdk_special_headers/${RelInstallPath} + else() + _ydb_sdk_directory_install(DIRECTORY ${YDB_SDK_SOURCE_DIR}/include/ydb-cpp-sdk + DESTINATION ${ArgIncludeDir} + COMPONENT ${ARG_COMPONENT} + EXCLUDE "open_telemetry" ) - endforeach() + + file(STRINGS ${YDB_SDK_SOURCE_DIR}/cmake/public_headers.txt PublicHeaders) + file(STRINGS ${YDB_SDK_SOURCE_DIR}/cmake/protos_public_headers.txt ProtosPublicHeaders) + if (NOT MSVC) + list(REMOVE_ITEM PublicHeaders library/cpp/deprecated/atomic/atomic_win.h) + endif() + foreach(HeaderPath ${PublicHeaders}) + get_filename_component(RelInstallPath ${HeaderPath} DIRECTORY) + _ydb_sdk_directory_install(FILES + ${YDB_SDK_SOURCE_DIR}/${HeaderPath} + DESTINATION ${ArgIncludeDir}/__ydb_sdk_special_headers/${RelInstallPath} + COMPONENT ${ARG_COMPONENT} + ) + endforeach() + foreach(HeaderPath ${ProtosPublicHeaders}) + get_filename_component(RelInstallPath ${HeaderPath} DIRECTORY) + _ydb_sdk_directory_install(FILES + ${YDB_SDK_BINARY_DIR}/${HeaderPath} + DESTINATION ${ArgIncludeDir}/__ydb_sdk_special_headers/${RelInstallPath} + COMPONENT ${ARG_COMPONENT} + ) + endforeach() + endif() endfunction() diff --git a/cmake/ydb-cpp-sdk-config.cmake.in b/cmake/ydb-cpp-sdk-config.cmake.in index ba1c144f0a1..9ab167f4f53 100644 --- a/cmake/ydb-cpp-sdk-config.cmake.in +++ b/cmake/ydb-cpp-sdk-config.cmake.in @@ -26,6 +26,10 @@ find_package(jwt-cpp REQUIRED) find_package(GTest REQUIRED) find_package(double-conversion REQUIRED) +if (@YDB_SDK_USE_SYSTEM_GOOGLEAPIS@) + find_package(yandex-googleapis-api-common-protos REQUIRED) +endif() + if (@YDB_SDK_USE_RAPID_JSON@) find_package(RapidJSON REQUIRED) @@ -36,6 +40,10 @@ if (@YDB_SDK_USE_RAPID_JSON@) ) endif() +if (@YDB_SDK_ENABLE_OTEL_METRICS@ OR @YDB_SDK_ENABLE_OTEL_TRACE@) + find_package(opentelemetry-cpp REQUIRED) +endif() + include("${CMAKE_CURRENT_LIST_DIR}/release/ydb-cpp-sdk-targets.cmake") function(_find_ydb_sdk_component CompName) diff --git a/library/cpp/logger/CMakeLists.txt b/library/cpp/logger/CMakeLists.txt index 1047043d0fa..bb0d74e702b 100644 --- a/library/cpp/logger/CMakeLists.txt +++ b/library/cpp/logger/CMakeLists.txt @@ -35,6 +35,7 @@ target_link_libraries(logger.global PUBLIC yutil json + logger PRIVATE enum_serialization_runtime ) diff --git a/plugins/metrics/CMakeLists.txt b/plugins/metrics/CMakeLists.txt index 2bcde514095..9b5f5d8505b 100644 --- a/plugins/metrics/CMakeLists.txt +++ b/plugins/metrics/CMakeLists.txt @@ -1,3 +1,3 @@ if (YDB_SDK_ENABLE_OTEL_METRICS) - add_subdirectory(otel EXCLUDE_FROM_ALL) + add_subdirectory(otel) endif() \ No newline at end of file diff --git a/plugins/metrics/otel/CMakeLists.txt b/plugins/metrics/otel/CMakeLists.txt index fe6bcf4ea04..6875ce3a672 100644 --- a/plugins/metrics/otel/CMakeLists.txt +++ b/plugins/metrics/otel/CMakeLists.txt @@ -1,7 +1,7 @@ _ydb_sdk_add_library(open_telemetry_metrics) target_sources(open_telemetry_metrics PRIVATE - src/metrics.cpp + metrics.cpp ) target_include_directories(open_telemetry_metrics PUBLIC $ @@ -15,4 +15,4 @@ target_link_libraries(open_telemetry_metrics PUBLIC ) _ydb_sdk_make_client_component(OpenTelemetryMetrics open_telemetry_metrics) -_ydb_sdk_install_headers(${CMAKE_INSTALL_INCLUDEDIR} DIRECTORY include/) \ No newline at end of file +_ydb_sdk_directory_install(FILES ${YDB_SDK_SOURCE_DIR}/include/ydb-cpp-sdk/open_telemetry/metrics.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ydb-cpp-sdk/open_telemetry COMPONENT libydb-cpp-otel-metrics) \ No newline at end of file diff --git a/plugins/metrics/otel/metrics.cpp b/plugins/metrics/otel/metrics.cpp index 22bfa284107..38705474965 100644 --- a/plugins/metrics/otel/metrics.cpp +++ b/plugins/metrics/otel/metrics.cpp @@ -145,8 +145,9 @@ class TOtelMetricRegistry : public IMetricRegistry { histogramConfig->boundaries_ = buckets; auto view = std::make_unique( + name, std::string{}, - std::string{}, + unit, sdk::metrics::AggregationType::kHistogram, histogramConfig ); diff --git a/plugins/trace/CMakeLists.txt b/plugins/trace/CMakeLists.txt index c1977028a0d..bfa3fe8e27e 100644 --- a/plugins/trace/CMakeLists.txt +++ b/plugins/trace/CMakeLists.txt @@ -1,3 +1,3 @@ if (YDB_SDK_ENABLE_OTEL_TRACE) - add_subdirectory(otel EXCLUDE_FROM_ALL) + add_subdirectory(otel) endif() \ No newline at end of file diff --git a/plugins/trace/otel/CMakeLists.txt b/plugins/trace/otel/CMakeLists.txt index c1cec305ec3..37783bb5cfe 100644 --- a/plugins/trace/otel/CMakeLists.txt +++ b/plugins/trace/otel/CMakeLists.txt @@ -1,6 +1,6 @@ _ydb_sdk_add_library(open_telemetry_trace) target_sources(open_telemetry_trace PRIVATE - src/trace.cpp + trace.cpp ) target_include_directories(open_telemetry_trace PUBLIC $ @@ -13,4 +13,4 @@ target_link_libraries(open_telemetry_trace PUBLIC ) _ydb_sdk_make_client_component(OpenTelemetryTrace open_telemetry_trace) -_ydb_sdk_install_headers(${CMAKE_INSTALL_INCLUDEDIR} DIRECTORY include/) \ No newline at end of file +_ydb_sdk_directory_install(FILES ${YDB_SDK_SOURCE_DIR}/include/ydb-cpp-sdk/open_telemetry/trace.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ydb-cpp-sdk/open_telemetry COMPONENT libydb-cpp-otel-tracing) \ No newline at end of file diff --git a/plugins/trace/otel/trace.cpp b/plugins/trace/otel/trace.cpp index f3095dd14d4..a606b451847 100644 --- a/plugins/trace/otel/trace.cpp +++ b/plugins/trace/otel/trace.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -60,24 +61,24 @@ class TOtelSpan : public ISpan { Span_->End(); } - void SetAttribute(const std::string& key, const std::string& value) override { - Span_->SetAttribute(key, value); + void SetAttribute(std::string_view key, std::string_view value) override { + Span_->SetAttribute(otel_nostd::string_view(key.data(), key.size()), otel_nostd::string_view(value.data(), value.size())); } - void SetAttribute(const std::string& key, int64_t value) override { - Span_->SetAttribute(key, value); + void SetAttribute(std::string_view key, int64_t value) override { + Span_->SetAttribute(otel_nostd::string_view(key.data(), key.size()), value); } - void AddEvent(const std::string& name, const std::map& attributes) override { - if (attributes.empty()) { - Span_->AddEvent(name); + void AddEvent(std::string_view name, TAttributes attributes = {}) override { + if (attributes.size() == 0) { + Span_->AddEvent(otel_nostd::string_view(name.data(), name.size())); } else { std::vector> attrs; attrs.reserve(attributes.size()); for (const auto& [k, v] : attributes) { - attrs.emplace_back(otel_nostd::string_view(k), otel_common::AttributeValue(otel_nostd::string_view(v))); + attrs.emplace_back(otel_nostd::string_view(k.data(), k.size()), otel_common::AttributeValue(otel_nostd::string_view(v.data(), v.size()))); } - Span_->AddEvent(name, attrs); + Span_->AddEvent(otel_nostd::string_view(name.data(), name.size()), otel_common::MakeAttributes(attrs)); } } @@ -85,8 +86,8 @@ class TOtelSpan : public ISpan { return std::make_unique(Span_); } - void SetStatus(ESpanStatus status, const std::string& description) override { - Span_->SetStatus(MapSpanStatus(status), description); + void SetStatus(ESpanStatus status, std::string_view description = {}) override { + Span_->SetStatus(MapSpanStatus(status), otel_nostd::string_view(description.data(), description.size())); } private: @@ -113,6 +114,10 @@ class TOtelTracer : public ITracer { return std::make_shared(Tracer_->StartSpan(name, options)); } + std::string GetCurrentTraceparent() const override { + return ""; // Stub implementation, OpenTelemetry doesn't natively expose this through the Tracer easily + } + private: otel_nostd::shared_ptr Tracer_; }; diff --git a/scripts/generate-debian-directory.sh b/scripts/generate-debian-directory.sh new file mode 100755 index 00000000000..414140e6b4e --- /dev/null +++ b/scripts/generate-debian-directory.sh @@ -0,0 +1,190 @@ +#!/bin/bash +set -e + +SCRIPT_DIR=$(dirname "$(realpath "$0")") +SOURCE_DIR=$(realpath "$SCRIPT_DIR/..") + +# --------------------------------------------------------------------------- +# Parse arguments +# --------------------------------------------------------------------------- +SERIES="noble" +while [[ $# -gt 0 ]]; do + case "$1" in + --series) + SERIES="$2" + shift 2 + ;; + --series=*) + SERIES="${1#*=}" + shift + ;; + *) + echo "Unknown option: $1" >&2 + echo "Usage: $0 [--series ]" >&2 + exit 1 + ;; + esac +done + +cd "$SOURCE_DIR" + +VERSION=$(grep -E 'YDB_SDK_VERSION = "[0-9]+\.[0-9]+\.[0-9]+"' src/version.h | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+)".*/\1/') +if [ -z "$VERSION" ]; then + echo "Error: Could not extract YDB_SDK_VERSION from src/version.h" + exit 1 +fi + +GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + +mkdir -p debian/ + +CHANGELOG_FILE="debian/changelog" + +DEB_VERSION="${VERSION}-1~${SERIES}1" + +cat < "$CHANGELOG_FILE" +ydb-cpp-sdk (${DEB_VERSION}) ${SERIES}; urgency=low + + * Automated package build + * Git commit: ${GIT_COMMIT} + + -- YDB Team $(date -R) +EOF_CHANGELOG + +cat < debian/control +Source: ydb-cpp-sdk +Section: libdevel +Priority: optional +Maintainer: YDB Team +Build-Depends: debhelper-compat (= 13), + cmake, + git, + pkg-config, + python3, + python3-six, + ragel, + yasm, + libidn11-dev, + libssl-dev, + zlib1g-dev, + libprotobuf-dev, + protobuf-compiler, + libgrpc++-dev, + protobuf-compiler-grpc, + libbrotli-dev, + liblz4-dev, + libzstd-dev, + libbz2-dev, + libxxhash-dev, + libsnappy-dev, + libdouble-conversion-dev, + libgtest-dev, + libre2-dev, + libc-ares-dev, + rapidjson-dev, + yandex-googleapis-api-common-protos +Standards-Version: 4.6.2 +Homepage: https://ydb.tech +Rules-Requires-Root: no + +Package: libydb-cpp-dev +Architecture: any +Depends: \${misc:Depends}, + libidn11-dev, + libssl-dev, + zlib1g-dev, + libprotobuf-dev, + libgrpc++-dev, + libbrotli-dev, + liblz4-dev, + libzstd-dev, + libbz2-dev, + libxxhash-dev, + libsnappy-dev, + libdouble-conversion-dev, + libgtest-dev, + libre2-dev, + libc-ares-dev, + rapidjson-dev, + yandex-googleapis-api-common-protos +Description: YDB C++ SDK development files + Static library, public headers and CMake package files for YDB C++ SDK. + +Package: libydb-cpp-iam-dev +Architecture: any +Depends: \${misc:Depends}, libydb-cpp-dev (= \${binary:Version}) +Description: YDB C++ SDK IAM plugin development files + Static library for YDB C++ SDK IAM credentials plugin. + +Package: libydb-cpp-otel-metrics-dev +Architecture: any +Depends: \${misc:Depends}, libydb-cpp-dev (= \${binary:Version}) +Description: YDB C++ SDK OpenTelemetry metrics plugin development files + Static library and headers for YDB C++ SDK OpenTelemetry metrics plugin. + +Package: libydb-cpp-otel-tracing-dev +Architecture: any +Depends: \${misc:Depends}, libydb-cpp-dev (= \${binary:Version}) +Description: YDB C++ SDK OpenTelemetry tracing plugin development files + Static library and headers for YDB C++ SDK OpenTelemetry tracing plugin. +EOF_CONTROL + +cat <<'EOF_RULES' > debian/rules +#!/usr/bin/make -f + +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +%: + dh $@ --buildsystem=cmake + +override_dh_auto_configure: + dh_auto_configure -- \ + -DCMAKE_BUILD_TYPE=Release \ + -DYDB_SDK_INSTALL=ON \ + -DYDB_SDK_EXAMPLES=OFF \ + -DYDB_SDK_TESTS=OFF \ + -DYDB_SDK_ENABLE_OTEL_METRICS=ON \ + -DYDB_SDK_ENABLE_OTEL_TRACE=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DYDB_SDK_USE_SYSTEM_GOOGLEAPIS=ON \ + -DCMAKE_INSTALL_PREFIX=/usr/share/yandex \ + -DCMAKE_PREFIX_PATH="/usr/share/yandex" +EOF_RULES +chmod +x debian/rules + +cat < debian/libydb-cpp-dev.install +debian/tmp/usr/share/yandex/lib/*/libydb-cpp.a usr/share/yandex/lib/ +debian/tmp/usr/share/yandex/include/ydb-cpp-sdk usr/share/yandex/include/ +debian/tmp/usr/share/yandex/include/__ydb_sdk_special_headers usr/share/yandex/include/ +debian/tmp/usr/share/yandex/lib/*/cmake/ydb-cpp-sdk usr/share/yandex/lib/*/cmake/ +debian/tmp/usr/share/yandex/include/libbase64.h usr/share/yandex/include/ +debian/tmp/usr/share/yandex/lib/*/libbase64.a usr/share/yandex/lib/ +debian/tmp/usr/share/yandex/lib/*/cmake/base64 usr/share/yandex/lib/*/cmake/ +debian/tmp/usr/share/yandex/include/picojson usr/share/yandex/include/ +debian/tmp/usr/share/yandex/include/jwt-cpp usr/share/yandex/include/ +debian/tmp/usr/share/yandex/cmake/jwt-cpp* usr/share/yandex/cmake/ +debian/tmp/usr/share/yandex/include/opentelemetry usr/share/yandex/include/ +debian/tmp/usr/share/yandex/lib/*/libopentelemetry_* usr/share/yandex/lib/ +debian/tmp/usr/share/yandex/lib/*/cmake/opentelemetry-cpp usr/share/yandex/lib/*/cmake/ +debian/tmp/usr/share/yandex/lib/*/pkgconfig/opentelemetry_*.pc usr/share/yandex/lib/*/pkgconfig/ +EOF_INSTALL + +cat < debian/libydb-cpp-iam-dev.install +debian/tmp/usr/share/yandex/lib/*/libydb-cpp-iam.a usr/share/yandex/lib/ +EOF_INSTALL + +cat < debian/libydb-cpp-otel-metrics-dev.install +debian/tmp/usr/share/yandex/lib/*/libydb-cpp-otel-metrics.a usr/share/yandex/lib/ +debian/tmp/usr/share/yandex/include/ydb-cpp-sdk/open_telemetry/metrics.h usr/share/yandex/include/ydb-cpp-sdk/open_telemetry/ +EOF_INSTALL + +cat < debian/libydb-cpp-otel-tracing-dev.install +debian/tmp/usr/share/yandex/lib/*/libydb-cpp-otel-tracing.a usr/share/yandex/lib/ +debian/tmp/usr/share/yandex/include/ydb-cpp-sdk/open_telemetry/trace.h usr/share/yandex/include/ydb-cpp-sdk/open_telemetry/ +EOF_INSTALL + + +mkdir -p debian/source +echo "3.0 (quilt)" > debian/source/format + +echo "Generated debian directory for version ${DEB_VERSION} (series: ${SERIES})" diff --git a/scripts/googleapis_deb/CMakeLists.txt b/scripts/googleapis_deb/CMakeLists.txt new file mode 100644 index 00000000000..0d8bc0623ef --- /dev/null +++ b/scripts/googleapis_deb/CMakeLists.txt @@ -0,0 +1,97 @@ +cmake_minimum_required(VERSION 3.10) +project(yandex-googleapis-api-common-protos) + +set(CMAKE_CXX_STANDARD 20) + +find_package(Protobuf REQUIRED) + +set(PROTOS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/api-common-protos") +get_filename_component(PROTOS_DIR "${PROTOS_DIR}" ABSOLUTE) + +if(NOT EXISTS "${PROTOS_DIR}/google") + message(FATAL_ERROR + "api-common-protos sources not found under \"${PROTOS_DIR}/google\". " + "Initialize git submodules / third_party checkout.") +endif() + +file(GLOB_RECURSE PROTO_FILES "${PROTOS_DIR}/google/*.proto") + +# We need to generate the cpp files +set(PROTO_SRCS) +set(PROTO_HDRS) + +foreach(proto_file ${PROTO_FILES}) + file(RELATIVE_PATH rel_path "${PROTOS_DIR}" "${proto_file}") + string(REPLACE ".proto" ".pb.cc" cpp_file "${CMAKE_CURRENT_BINARY_DIR}/${rel_path}") + string(REPLACE ".proto" ".pb.h" h_file "${CMAKE_CURRENT_BINARY_DIR}/${rel_path}") + + get_filename_component(out_dir "${cpp_file}" DIRECTORY) + file(MAKE_DIRECTORY "${out_dir}") + + add_custom_command( + OUTPUT "${cpp_file}" "${h_file}" + COMMAND "${Protobuf_PROTOC_EXECUTABLE}" + ARGS + "--cpp_out=${CMAKE_CURRENT_BINARY_DIR}" + "-I." + "${rel_path}" + WORKING_DIRECTORY "${PROTOS_DIR}" + DEPENDS "${proto_file}" + COMMENT "Running C++ protocol buffer compiler on ${rel_path}" + VERBATIM + ) + + list(APPEND PROTO_SRCS "${cpp_file}") + list(APPEND PROTO_HDRS "${h_file}") +endforeach() + +add_library(api-common-protos STATIC ${PROTO_SRCS} ${PROTO_HDRS}) +add_library(yandex-googleapis-api-common-protos::api-common-protos ALIAS api-common-protos) + +target_include_directories(api-common-protos PUBLIC + $ + $ +) + +target_link_libraries(api-common-protos PUBLIC protobuf::libprotobuf) + +include(GNUInstallDirs) + +install(TARGETS api-common-protos + EXPORT yandex-googleapis-api-common-protos-targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/google" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.pb.h" +) + +install(EXPORT yandex-googleapis-api-common-protos-targets + FILE yandex-googleapis-api-common-protosTargets.cmake + NAMESPACE yandex-googleapis-api-common-protos:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/yandex-googleapis-api-common-protos +) + +include(CMakePackageConfigHelpers) +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/yandex-googleapis-api-common-protosConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/yandex-googleapis-api-common-protosConfig.cmake" + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/yandex-googleapis-api-common-protos +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/yandex-googleapis-api-common-protosConfig.cmake" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/yandex-googleapis-api-common-protos +) + +set(CPACK_PACKAGE_NAME "yandex-googleapis-api-common-protos") +set(CPACK_PACKAGE_VERSION "1.0.0") +set(CPACK_GENERATOR "DEB") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "YDB Team ") +set(CPACK_DEBIAN_PACKAGE_DEPENDS "libprotobuf-dev") +set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/share/yandex") + +include(CPack) diff --git a/scripts/googleapis_deb/yandex-googleapis-api-common-protosConfig.cmake.in b/scripts/googleapis_deb/yandex-googleapis-api-common-protosConfig.cmake.in new file mode 100644 index 00000000000..9437a3ae170 --- /dev/null +++ b/scripts/googleapis_deb/yandex-googleapis-api-common-protosConfig.cmake.in @@ -0,0 +1,6 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(Protobuf) + +include("${CMAKE_CURRENT_LIST_DIR}/yandex-googleapis-api-common-protosTargets.cmake") diff --git a/scripts/test_deb_packages.sh b/scripts/test_deb_packages.sh new file mode 100755 index 00000000000..2f2d198c0f9 --- /dev/null +++ b/scripts/test_deb_packages.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +DEB_DIR=$(realpath "$1") +SCRIPT_DIR=$(dirname "$(realpath "$0")") +TEST_DIR=$(realpath "$SCRIPT_DIR/../tests/deb_package") + +echo "Building test Docker image..." +docker build --network host -t ydb-cpp-sdk-deb-test "$TEST_DIR" + +echo "Running test container..." +docker run --rm --network host \ + -v "$DEB_DIR:/deb_packages:ro" \ + ydb-cpp-sdk-deb-test \ + bash -c "apt-get update && apt-get install -y /deb_packages/*.deb && mkdir build && cd build && cmake .. -DCMAKE_PREFIX_PATH='/usr/share/yandex' && make && ./test_app" + +echo "Test successful!" \ No newline at end of file diff --git a/scripts/test_dpkg_buildpackage.sh b/scripts/test_dpkg_buildpackage.sh new file mode 100755 index 00000000000..bf5e53ab1d7 --- /dev/null +++ b/scripts/test_dpkg_buildpackage.sh @@ -0,0 +1,64 @@ +#!/bin/bash +set -e + +SCRIPT_DIR=$(dirname "$(realpath "$0")") +SOURCE_DIR=$(realpath "$SCRIPT_DIR/..") + +echo "Building test Docker image for dpkg-buildpackage..." + +# We need a Dockerfile that has all the build dependencies for dpkg-buildpackage +DOCKERFILE=$(mktemp) +cat < "$DOCKERFILE" +FROM ubuntu:24.04 +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y \\ + build-essential \\ + cmake \\ + pkg-config \\ + git \\ + libidn11-dev \\ + libssl-dev \\ + zlib1g-dev \\ + libprotobuf-dev \\ + protobuf-compiler \\ + libgrpc++-dev \\ + protobuf-compiler-grpc \\ + libbrotli-dev \\ + liblz4-dev \\ + libzstd-dev \\ + libbz2-dev \\ + libxxhash-dev \\ + libsnappy-dev \\ + libdouble-conversion-dev \\ + libgtest-dev \\ + libre2-dev \\ + libc-ares-dev \\ + rapidjson-dev \\ + debhelper \\ + dpkg-dev \\ + python3 \\ + python3-six \\ + ragel \\ + yasm \\ + && rm -rf /var/lib/apt/lists/* +WORKDIR /source +EOF + +docker build --network host -t ydb-cpp-sdk-dpkg-test -f "$DOCKERFILE" . +rm -f "$DOCKERFILE" + +# Prepare a clean tarball or just copy the directory inside the container +echo "Running dpkg-buildpackage in the container..." +docker run --rm --network host \ + -v "$SOURCE_DIR:/source:ro" \ + ydb-cpp-sdk-dpkg-test \ + bash -c "cp -r /source /tmp/source && cd /tmp/source && \ + rm -rf build_googleapis_deb && \ + cmake -S scripts/googleapis_deb -B build_googleapis_deb -DCMAKE_INSTALL_PREFIX=/usr/share/yandex && \ + cmake --build build_googleapis_deb -j\$(nproc) && \ + cmake --build build_googleapis_deb --target package && \ + dpkg -i build_googleapis_deb/*.deb && \ + ./scripts/generate-debian-directory.sh && \ + dpkg-buildpackage -us -uc -b -d -j\$(nproc)" + +echo "Test successful! dpkg-buildpackage works." \ No newline at end of file diff --git a/tests/deb_package/Dockerfile b/tests/deb_package/Dockerfile new file mode 100644 index 00000000000..c6ed11a77b3 --- /dev/null +++ b/tests/deb_package/Dockerfile @@ -0,0 +1,31 @@ +FROM ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y \ + build-essential \ + cmake \ + pkg-config \ + git \ + libidn11-dev \ + libssl-dev \ + zlib1g-dev \ + libprotobuf-dev \ + protobuf-compiler \ + libgrpc++-dev \ + protobuf-compiler-grpc \ + libbrotli-dev \ + liblz4-dev \ + libzstd-dev \ + libbz2-dev \ + libxxhash-dev \ + libsnappy-dev \ + libdouble-conversion-dev \ + libgtest-dev \ + libre2-dev \ + libc-ares-dev \ + rapidjson-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY test_project /test_project +WORKDIR /test_project \ No newline at end of file diff --git a/tests/deb_package/test_project/CMakeLists.txt b/tests/deb_package/test_project/CMakeLists.txt new file mode 100644 index 00000000000..af4830c4fe0 --- /dev/null +++ b/tests/deb_package/test_project/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.10) +project(test_ydb_cpp_sdk) + +set(CMAKE_CXX_STANDARD 20) + +find_package(ydb-cpp-sdk REQUIRED) + +add_executable(test_app main.cpp) + +target_link_libraries(test_app + PRIVATE + YDB-CPP-SDK::Driver + YDB-CPP-SDK::Iam + YDB-CPP-SDK::OpenTelemetryMetrics + YDB-CPP-SDK::OpenTelemetryTrace +) \ No newline at end of file diff --git a/tests/deb_package/test_project/main.cpp b/tests/deb_package/test_project/main.cpp new file mode 100644 index 00000000000..c4e05b3ca48 --- /dev/null +++ b/tests/deb_package/test_project/main.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +#include + +int main() { + auto config = NYdb::TDriverConfig() + .SetEndpoint("localhost:2136") + .SetDatabase("/local") + .SetCredentialsProviderFactory(NYdb::CreateIamCredentialsProviderFactory({})); + + std::cout << "Successfully instantiated driver configuration with IAM credentials provider." << std::endl; + return 0; +} \ No newline at end of file diff --git a/third_party/aklomp-base64 b/third_party/aklomp-base64 new file mode 160000 index 00000000000..8bdda2d47ca --- /dev/null +++ b/third_party/aklomp-base64 @@ -0,0 +1 @@ +Subproject commit 8bdda2d47caf8b066999c5bd01069e55bcd0d396 diff --git a/third_party/jwt-cpp b/third_party/jwt-cpp new file mode 160000 index 00000000000..4a537e96989 --- /dev/null +++ b/third_party/jwt-cpp @@ -0,0 +1 @@ +Subproject commit 4a537e969891dde542ad8b1a4a214955a83be29f diff --git a/third_party/opentelemetry-cpp b/third_party/opentelemetry-cpp new file mode 160000 index 00000000000..46e20a42aef --- /dev/null +++ b/third_party/opentelemetry-cpp @@ -0,0 +1 @@ +Subproject commit 46e20a42aef521b9cc1b7207310bfefcd490741a