From de8b22b35084af80cdbe07cfe008c0906dca4ddb Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Sat, 18 Apr 2026 00:24:33 +0000 Subject: [PATCH 01/18] feat: add Conan 2 + CMakePresets build system for client repo - conanfile.py: declares C++ deps (rapidjson, gtest, libcurl, grpc, protobuf, re2); injects TRITON_COMMON_SOURCE_DIR and TRITON_SKIP_THIRD_PARTY_FETCH into CMakeToolchain so the build uses the monorepo common/ sibling instead of fetching from GitHub. - cmake/CMakePresets.json: four presets covering cpu/cuda x ubuntu/manylinux for x86_64 and aarch64; all ubuntu presets enable TRITON_ENABLE_JAVA_HTTP. - CMakeLists.txt: Conan mode adds common/, src/c++, src/python, src/java via add_subdirectory; legacy ExternalProject path is unchanged. - src/c++/CMakeLists.txt: Conan mode skips FetchContent; adds GTest::gtest alias for test compatibility. - src/python/CMakeLists.txt: Conan mode skips FetchContent of repo-common; proto-py-library comes from the parent add_subdirectory(common/). - Conan profiles: linux-gcc13-{release,debug}-x86_64 (Ubuntu /usr/bin/gcc-13) and linux-gcc13-release-manylinux-x86_64 (AlmaLinux SCL gcc-toolset-13). - Dockerfile.sdk: multi-stage Conan build producing an image at parity with nvcr.io/nvidia/tritonserver:*-py3-sdk; uses Python 3.12 venv, BuildKit cache mounts, BuildKit secret for Conan token, Java API bindings, QA suites, Model Analyzer, DCGM, entrypoint banner. - Dockerfile.sdk.manylinux: builds a manylinux_2_28_x86_64 Python wheel on quay.io/pypa/manylinux_2_28_x86_64 (AlmaLinux 8) with auditwheel repair. --- CMakeLists.txt | 322 ++++++++++-------- CMakePresets.json | 4 + Dockerfile.sdk | 314 +++++++++++++++++ Dockerfile.sdk.manylinux | 182 ++++++++++ cmake/CMakePresets.json | 105 ++++++ conan/profiles/linux-gcc13-debug-x86_64 | 15 + .../linux-gcc13-release-manylinux-x86_64 | 15 + conan/profiles/linux-gcc13-release-x86_64 | 15 + conanfile.py | 88 +++++ src/c++/CMakeLists.txt | 69 ++-- src/python/CMakeLists.txt | 31 +- 11 files changed, 978 insertions(+), 182 deletions(-) create mode 100644 CMakePresets.json create mode 100644 Dockerfile.sdk create mode 100644 Dockerfile.sdk.manylinux create mode 100644 cmake/CMakePresets.json create mode 100644 conan/profiles/linux-gcc13-debug-x86_64 create mode 100644 conan/profiles/linux-gcc13-release-manylinux-x86_64 create mode 100644 conan/profiles/linux-gcc13-release-x86_64 create mode 100644 conanfile.py diff --git a/CMakeLists.txt b/CMakeLists.txt index c1d09f793..3161aacbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,154 +67,190 @@ endif() # # Dependencies # -include(FetchContent) - -FetchContent_Declare( - repo-third-party - GIT_REPOSITORY ${TRITON_REPO_ORGANIZATION}/third_party.git - GIT_TAG ${TRITON_THIRD_PARTY_REPO_TAG} - GIT_SHALLOW ON -) -set(TRITON_THIRD_PARTY_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/third-party) -FetchContent_MakeAvailable(repo-third-party) - -# Some libs are installed to ${TRITON_THIRD_PARTY_INSTALL_PREFIX}/lib64 instead -# of ${TRITON_THIRD_PARTY_INSTALL_PREFIX}/lib on Centos -set (LIB_DIR "lib") -if(LINUX) - file(STRINGS "/etc/os-release" DISTRO_ID_LIKE REGEX "ID_LIKE") - if(${DISTRO_ID_LIKE} MATCHES "rhel|centos") - set (LIB_DIR "lib64") - endif(${DISTRO_ID_LIKE} MATCHES "rhel|centos") -endif(LINUX) - -# Need to use ExternalProject for our builds so that we can get the -# correct dependencies between our components and the ExternalProject -# dependencies (found in the third_party repo) -include(ExternalProject) - -if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(TRITON_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/cc-clients/install) -else() - set(TRITON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) -endif() -set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "") -if (OPENSSL_ROOT_DIR) - set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}") -endif() +if(TRITON_SKIP_THIRD_PARTY_FETCH) + # Conan mode: all C++ deps come from Conan packages. Build sub-projects + # directly via add_subdirectory so the Conan toolchain is inherited. -set(_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE "") -if (CMAKE_TOOLCHAIN_FILE) - set(_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE "-DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE}") -endif() + # Add common once at the top level so both C++ and Python clients share the + # same triton-common-json / proto-py-library targets without duplicate definitions. + if(TRITON_COMMON_SOURCE_DIR) + set(TRITON_COMMON_ENABLE_JSON ON) + if(TRITON_ENABLE_CC_GRPC OR TRITON_ENABLE_PYTHON_GRPC) + set(TRITON_COMMON_ENABLE_PROTOBUF ON) + set(TRITON_COMMON_ENABLE_GRPC ON) + endif() + add_subdirectory(${TRITON_COMMON_SOURCE_DIR} triton-common-build) + # Compatibility shim so sub-projects that reference repo-common_SOURCE_DIR still resolve. + set(repo-common_SOURCE_DIR ${TRITON_COMMON_SOURCE_DIR}) + endif() -set(_CMAKE_ARGS_VCPKG_TARGET_TRIPLET "") -if (VCPKG_TARGET_TRIPLET) - set(_CMAKE_ARGS_VCPKG_TARGET_TRIPLET "-DVCPKG_TARGET_TRIPLET:STRING=${VCPKG_TARGET_TRIPLET}") -endif() + if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC) + add_subdirectory(src/c++) + endif() + + if(TRITON_ENABLE_PYTHON_HTTP OR TRITON_ENABLE_PYTHON_GRPC) + add_subdirectory(src/python) + endif() + + if(TRITON_ENABLE_JAVA_HTTP) + add_subdirectory(src/java) + endif() + + # Java client uses Maven (mvn clean install) internally; Maven and a JDK must be + # present in the build environment (see Dockerfile.sdk build stage). -# Location where protobuf-config.cmake will be installed varies by -# platform -if (WIN32) - set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${TRITON_THIRD_PARTY_INSTALL_PREFIX}/protobuf/cmake") else() - set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${TRITON_THIRD_PARTY_INSTALL_PREFIX}/protobuf/${LIB_DIR}/cmake/protobuf") -endif() + # Legacy mode: fetch third_party from GitHub and build via ExternalProject. + include(FetchContent) -if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC) - - set(_cc_client_depends re2) - if(${TRITON_ENABLE_CC_HTTP}) - set(_cc_client_depends ${_cc_client_depends} curl) - endif() # TRITON_ENABLE_CC_HTTP - if(${TRITON_ENABLE_CC_GRPC}) - set(_cc_client_depends ${_cc_client_depends} grpc protobuf) - endif() # TRITON_ENABLE_CC_GRPC - - ExternalProject_Add(cc-clients - PREFIX cc-clients - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/c++" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cc-clients" - CMAKE_CACHE_ARGS - ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} - ${_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE} - ${_CMAKE_ARGS_VCPKG_TARGET_TRIPLET} - -DCURL_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/curl/${LIB_DIR}/cmake/CURL - -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} - -DgRPC_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/grpc/lib/cmake/grpc - -Dabsl_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/absl/${LIB_DIR}/cmake/absl - -Dre2_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/re2/${LIB_DIR}/cmake/re2 - -Dc-ares_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/c-ares/${LIB_DIR}/cmake/c-ares - -DGTEST_ROOT:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/googletest - -DTRITON_REPO_ORGANIZATION:STRING=${TRITON_REPO_ORGANIZATION} - -DTRITON_COMMON_REPO_TAG:STRING=${TRITON_COMMON_REPO_TAG} - -DTRITON_CORE_REPO_TAG:STRING=${TRITON_CORE_REPO_TAG} - -DTRITON_ENABLE_CC_HTTP:BOOL=${TRITON_ENABLE_CC_HTTP} - -DTRITON_ENABLE_CC_GRPC:BOOL=${TRITON_ENABLE_CC_GRPC} - -DTRITON_ENABLE_EXAMPLES:BOOL=${TRITON_ENABLE_EXAMPLES} - -DTRITON_ENABLE_TESTS:BOOL=${TRITON_ENABLE_TESTS} - -DTRITON_ENABLE_GPU:BOOL=${TRITON_ENABLE_GPU} - -DTRITON_ENABLE_ZLIB:BOOL=${TRITON_ENABLE_ZLIB} - -DTRITON_MIN_CXX_STANDARD:STRING=${TRITON_MIN_CXX_STANDARD} - -DLIB_DIR:STRING=${LIB_DIR} - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX:PATH=${TRITON_INSTALL_PREFIX} - DEPENDS ${_cc_client_depends} - ) -endif() # TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC - -if(TRITON_ENABLE_PYTHON_HTTP OR TRITON_ENABLE_PYTHON_GRPC) - set(_py_client_depends re2) - if(${TRITON_ENABLE_PYTHON_GRPC}) - set(_py_client_depends ${_py_client_depends} grpc protobuf) - endif() # TRITON_ENABLE_PYTHON_GRPC - - ExternalProject_Add(python-clients - PREFIX python-clients - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/python" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/python-clients" - CMAKE_CACHE_ARGS - ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} - ${_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE} - ${_CMAKE_ARGS_VCPKG_TARGET_TRIPLET} - -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} - -DgRPC_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/grpc/lib/cmake/grpc - -Dabsl_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/absl/${LIB_DIR}/cmake/absl - -Dc-ares_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/c-ares/${LIB_DIR}/cmake/c-ares - -Dre2_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/re2/${LIB_DIR}/cmake/re2 - -DTRITON_REPO_ORGANIZATION:STRING=${TRITON_REPO_ORGANIZATION} - -DTRITON_COMMON_REPO_TAG:STRING=${TRITON_COMMON_REPO_TAG} - -DTRITON_CORE_REPO_TAG:STRING=${TRITON_CORE_REPO_TAG} - -DTRITON_VERSION:STRING=${TRITON_VERSION} - -DTRITON_ENABLE_PYTHON_HTTP:BOOL=${TRITON_ENABLE_PYTHON_HTTP} - -DTRITON_ENABLE_PYTHON_GRPC:BOOL=${TRITON_ENABLE_PYTHON_GRPC} - -DTRITON_ENABLE_EXAMPLES:BOOL=${TRITON_ENABLE_EXAMPLES} - -DTRITON_ENABLE_TESTS:BOOL=${TRITON_ENABLE_TESTS} - -DTRITON_PACKAGE_PERF_ANALYZER:BOOL=${TRITON_PACKAGE_PERF_ANALYZER} - -DTRITON_ENABLE_GPU:BOOL=${TRITON_ENABLE_GPU} - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX:PATH=${TRITON_INSTALL_PREFIX} - DEPENDS ${_py_client_depends} - ) -endif() # TRITON_ENABLE_PYTHON_HTTP OR TRITON_ENABLE_PYTHON_GRPC - -if(TRITON_ENABLE_JAVA_HTTP) - ExternalProject_Add(java-clients - PREFIX java-clients - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/java" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/java-clients" - CMAKE_CACHE_ARGS - ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} - ${_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE} - ${_CMAKE_ARGS_VCPKG_TARGET_TRIPLET} - -DTRITON_REPO_ORGANIZATION:STRING=${TRITON_REPO_ORGANIZATION} - -DTRITON_VERSION:STRING=${TRITON_VERSION} - -DTRITON_ENABLE_JAVA_HTTP:BOOL=${TRITON_ENABLE_JAVA_HTTP} - -DTRITON_ENABLE_EXAMPLES:BOOL=${TRITON_ENABLE_EXAMPLES} - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX:PATH=${TRITON_INSTALL_PREFIX} - INSTALL_COMMAND "" + FetchContent_Declare( + repo-third-party + GIT_REPOSITORY ${TRITON_REPO_ORGANIZATION}/third_party.git + GIT_TAG ${TRITON_THIRD_PARTY_REPO_TAG} + GIT_SHALLOW ON ) + set(TRITON_THIRD_PARTY_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/third-party) + FetchContent_MakeAvailable(repo-third-party) + + # Some libs are installed to ${TRITON_THIRD_PARTY_INSTALL_PREFIX}/lib64 instead + # of ${TRITON_THIRD_PARTY_INSTALL_PREFIX}/lib on Centos + set (LIB_DIR "lib") + if(LINUX) + file(STRINGS "/etc/os-release" DISTRO_ID_LIKE REGEX "ID_LIKE") + if(${DISTRO_ID_LIKE} MATCHES "rhel|centos") + set (LIB_DIR "lib64") + endif(${DISTRO_ID_LIKE} MATCHES "rhel|centos") + endif(LINUX) + + # Need to use ExternalProject for our builds so that we can get the + # correct dependencies between our components and the ExternalProject + # dependencies (found in the third_party repo) + include(ExternalProject) + + if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(TRITON_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/cc-clients/install) + else() + set(TRITON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) + endif() + + set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "") + if (OPENSSL_ROOT_DIR) + set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}") + endif() + + set(_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE "") + if (CMAKE_TOOLCHAIN_FILE) + set(_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE "-DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE}") + endif() + + set(_CMAKE_ARGS_VCPKG_TARGET_TRIPLET "") + if (VCPKG_TARGET_TRIPLET) + set(_CMAKE_ARGS_VCPKG_TARGET_TRIPLET "-DVCPKG_TARGET_TRIPLET:STRING=${VCPKG_TARGET_TRIPLET}") + endif() + + # Location where protobuf-config.cmake will be installed varies by platform + if (WIN32) + set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${TRITON_THIRD_PARTY_INSTALL_PREFIX}/protobuf/cmake") + else() + set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${TRITON_THIRD_PARTY_INSTALL_PREFIX}/protobuf/${LIB_DIR}/cmake/protobuf") + endif() + + if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC) + + set(_cc_client_depends re2) + if(${TRITON_ENABLE_CC_HTTP}) + set(_cc_client_depends ${_cc_client_depends} curl) + endif() # TRITON_ENABLE_CC_HTTP + if(${TRITON_ENABLE_CC_GRPC}) + set(_cc_client_depends ${_cc_client_depends} grpc protobuf) + endif() # TRITON_ENABLE_CC_GRPC + + ExternalProject_Add(cc-clients + PREFIX cc-clients + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/c++" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cc-clients" + CMAKE_CACHE_ARGS + ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} + ${_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE} + ${_CMAKE_ARGS_VCPKG_TARGET_TRIPLET} + -DCURL_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/curl/${LIB_DIR}/cmake/CURL + -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} + -DgRPC_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/grpc/lib/cmake/grpc + -Dabsl_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/absl/${LIB_DIR}/cmake/absl + -Dre2_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/re2/${LIB_DIR}/cmake/re2 + -Dc-ares_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/c-ares/${LIB_DIR}/cmake/c-ares + -DGTEST_ROOT:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/googletest + -DTRITON_REPO_ORGANIZATION:STRING=${TRITON_REPO_ORGANIZATION} + -DTRITON_COMMON_REPO_TAG:STRING=${TRITON_COMMON_REPO_TAG} + -DTRITON_CORE_REPO_TAG:STRING=${TRITON_CORE_REPO_TAG} + -DTRITON_ENABLE_CC_HTTP:BOOL=${TRITON_ENABLE_CC_HTTP} + -DTRITON_ENABLE_CC_GRPC:BOOL=${TRITON_ENABLE_CC_GRPC} + -DTRITON_ENABLE_EXAMPLES:BOOL=${TRITON_ENABLE_EXAMPLES} + -DTRITON_ENABLE_TESTS:BOOL=${TRITON_ENABLE_TESTS} + -DTRITON_ENABLE_GPU:BOOL=${TRITON_ENABLE_GPU} + -DTRITON_ENABLE_ZLIB:BOOL=${TRITON_ENABLE_ZLIB} + -DTRITON_MIN_CXX_STANDARD:STRING=${TRITON_MIN_CXX_STANDARD} + -DLIB_DIR:STRING=${LIB_DIR} + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH=${TRITON_INSTALL_PREFIX} + DEPENDS ${_cc_client_depends} + ) + endif() # TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC + + if(TRITON_ENABLE_PYTHON_HTTP OR TRITON_ENABLE_PYTHON_GRPC) + set(_py_client_depends re2) + if(${TRITON_ENABLE_PYTHON_GRPC}) + set(_py_client_depends ${_py_client_depends} grpc protobuf) + endif() # TRITON_ENABLE_PYTHON_GRPC + + ExternalProject_Add(python-clients + PREFIX python-clients + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/python" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/python-clients" + CMAKE_CACHE_ARGS + ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} + ${_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE} + ${_CMAKE_ARGS_VCPKG_TARGET_TRIPLET} + -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} + -DgRPC_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/grpc/lib/cmake/grpc + -Dabsl_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/absl/${LIB_DIR}/cmake/absl + -Dc-ares_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/c-ares/${LIB_DIR}/cmake/c-ares + -Dre2_DIR:PATH=${TRITON_THIRD_PARTY_INSTALL_PREFIX}/re2/${LIB_DIR}/cmake/re2 + -DTRITON_REPO_ORGANIZATION:STRING=${TRITON_REPO_ORGANIZATION} + -DTRITON_COMMON_REPO_TAG:STRING=${TRITON_COMMON_REPO_TAG} + -DTRITON_CORE_REPO_TAG:STRING=${TRITON_CORE_REPO_TAG} + -DTRITON_VERSION:STRING=${TRITON_VERSION} + -DTRITON_ENABLE_PYTHON_HTTP:BOOL=${TRITON_ENABLE_PYTHON_HTTP} + -DTRITON_ENABLE_PYTHON_GRPC:BOOL=${TRITON_ENABLE_PYTHON_GRPC} + -DTRITON_ENABLE_EXAMPLES:BOOL=${TRITON_ENABLE_EXAMPLES} + -DTRITON_ENABLE_TESTS:BOOL=${TRITON_ENABLE_TESTS} + -DTRITON_PACKAGE_PERF_ANALYZER:BOOL=${TRITON_PACKAGE_PERF_ANALYZER} + -DTRITON_ENABLE_GPU:BOOL=${TRITON_ENABLE_GPU} + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH=${TRITON_INSTALL_PREFIX} + DEPENDS ${_py_client_depends} + ) + endif() # TRITON_ENABLE_PYTHON_HTTP OR TRITON_ENABLE_PYTHON_GRPC + + if(TRITON_ENABLE_JAVA_HTTP) + ExternalProject_Add(java-clients + PREFIX java-clients + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/java" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/java-clients" + CMAKE_CACHE_ARGS + ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} + ${_CMAKE_ARGS_CMAKE_TOOLCHAIN_FILE} + ${_CMAKE_ARGS_VCPKG_TARGET_TRIPLET} + -DTRITON_REPO_ORGANIZATION:STRING=${TRITON_REPO_ORGANIZATION} + -DTRITON_VERSION:STRING=${TRITON_VERSION} + -DTRITON_ENABLE_JAVA_HTTP:BOOL=${TRITON_ENABLE_JAVA_HTTP} + -DTRITON_ENABLE_EXAMPLES:BOOL=${TRITON_ENABLE_EXAMPLES} + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH=${TRITON_INSTALL_PREFIX} + INSTALL_COMMAND "" + ) + + endif() # TRITON_ENABLE_JAVA_HTTP -endif() # TRITON_ENABLE_JAVA_HTTP +endif() # TRITON_SKIP_THIRD_PARTY_FETCH diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000..21b4cd419 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,4 @@ +{ + "version": 6, + "include": ["cmake/CMakePresets.json"] +} diff --git a/Dockerfile.sdk b/Dockerfile.sdk new file mode 100644 index 000000000..240810887 --- /dev/null +++ b/Dockerfile.sdk @@ -0,0 +1,314 @@ +# Copyright 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# Multi-stage Conan-based build of the Triton Client SDK. +# Uses isolated Python 3.12 virtual environments — no system pip installs. +# Designed for parity with server/Dockerfile.sdk (nvcr.io/nvidia/tritonserver:*-py3-sdk). +# +# Build (CPU, from monorepo root): +# DOCKER_BUILDKIT=1 docker build \ +# --secret id=conan_token,src=/path/to/artifactory_token.txt \ +# --build-arg TRITON_CLIENT_REPO_SUBDIR=client \ +# --build-arg TRITON_COMMON_REPO_SUBDIR=common \ +# --build-arg TRITON_SERVER_REPO_SUBDIR=server \ +# -f client/Dockerfile.sdk . +# +# Build (GPU): +# ... --build-arg TRITON_ENABLE_GPU=ON \ +# --build-arg TRITON_CLIENT_PRESET=triton-client-release-cuda-ubuntu-x86_64 ... +# + +ARG BASE_IMAGE=nvcr.io/nvidia/tritonserver:26.03-py3-min + +# Subdirectory paths relative to the Docker build context (monorepo root). +ARG TRITON_CLIENT_REPO_SUBDIR=client +ARG TRITON_COMMON_REPO_SUBDIR=common +ARG TRITON_SERVER_REPO_SUBDIR=server + +# Preset selects the platform / GPU variant. +# CPU: triton-client-release-cpu-ubuntu-x86_64 +# GPU: triton-client-release-cuda-ubuntu-x86_64 +ARG TRITON_CLIENT_PRESET=triton-client-release-cpu-ubuntu-x86_64 + +ARG TRITON_ENABLE_GPU=OFF +ARG DCGM_VERSION=4.5.3-1 + +# Java API bindings parameters (parity with server/Dockerfile.sdk). +ARG JAVA_BINDINGS_MAVEN_VERSION=3.8.4 +ARG JAVA_BINDINGS_JAVACPP_PRESETS_TAG=1.5.8 + +# Model Analyzer — installed only when TRITON_MODEL_ANALYZER_REPO_TAG is set. +ARG TRITON_REPO_ORGANIZATION=http://github.com/triton-inference-server +ARG TRITON_CORE_REPO_TAG=main +ARG TRITON_MODEL_ANALYZER_REPO_TAG= + +# Conan remote credentials (token supplied via Docker BuildKit secret). +ARG CONAN_USER=triton-sdk +ARG CONAN_REMOTE_NAME=sw-dl-triton-conan-local +ARG CONAN_REMOTE_URL=https://artifactory.nvidia.com/artifactory/api/conan/sw-dl-triton-conan-local + +ARG NVIDIA_TRITON_SERVER_SDK_VERSION=unknown +ARG NVIDIA_BUILD_ID=unknown + +############################################################################ +## Build stage +############################################################################ + +FROM ${BASE_IMAGE} AS sdk_build + +SHELL ["/bin/bash", "-euo", "pipefail", "-c"] + +ARG DEBIAN_FRONTEND=noninteractive + +# C++ build toolchain + Java (for Java API bindings) + Python 3.12 dev headers. +# python3.12-venv provides the venv module used to create the isolated build env. +# Prefer GCC-13 so the Conan profile and the compiler in use agree. +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + gcc-13 \ + g++-13 \ + git \ + libb64-dev \ + libnuma-dev \ + libssl-dev \ + maven \ + ninja-build \ + openjdk-11-jdk \ + pkg-config \ + python3.12 \ + python3.12-dev \ + python3.12-venv && \ + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100 && \ + update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 100 + +# Isolated build-time venv — Conan, CMake, and grpcio-tools live here only. +# Nothing is installed into the system Python. +RUN --mount=type=cache,target=/root/.cache/pip \ + python3.12 -m venv /opt/build-venv && \ + /opt/build-venv/bin/pip install \ + "conan>=2.0,<3.0" \ + "cmake>=3.31.8" \ + "grpcio-tools<1.68" + +ENV PATH=/opt/build-venv/bin:${PATH} + +ARG TRITON_CLIENT_REPO_SUBDIR +ARG TRITON_COMMON_REPO_SUBDIR +ARG TRITON_CLIENT_PRESET +ARG TRITON_ENABLE_GPU +ARG CONAN_USER +ARG CONAN_REMOTE_NAME +ARG CONAN_REMOTE_URL + +WORKDIR /workspace + +# ── Layer 1: Conan dependency resolution ────────────────────────────────── +# Copy only the Conan manifest + profiles so this expensive layer is cached +# as long as conanfile.py and the Conan profiles are unchanged. +COPY ${TRITON_CLIENT_REPO_SUBDIR}/conanfile.py client/conanfile.py +COPY ${TRITON_CLIENT_REPO_SUBDIR}/conan/profiles/ client/conan/profiles/ + +# Register the Artifactory remote (no credentials stored in this layer). +RUN conan remote add ${CONAN_REMOTE_NAME} ${CONAN_REMOTE_URL} + +# Resolve and download all Conan packages. +# The Artifactory token is mounted as a BuildKit secret and is never written +# to any image layer. Pass: --secret id=conan_token,src=/path/to/token.txt +RUN --mount=type=secret,id=conan_token \ + CONAN_GPU=$([ "${TRITON_ENABLE_GPU}" = "ON" ] && echo "True" || echo "False") && \ + conan remote login ${CONAN_REMOTE_NAME} ${CONAN_USER} \ + -p "$(cat /run/secrets/conan_token)" && \ + conan install /workspace/client \ + --profile:host=/workspace/client/conan/profiles/linux-gcc13-release-x86_64 \ + --profile:build=/workspace/client/conan/profiles/linux-gcc13-release-x86_64 \ + -c "tools.cmake:cmake_program=$(which cmake)" \ + -o "&:enable_gpu=${CONAN_GPU}" \ + -o "&:enable_grpc=True" \ + -o "&:enable_http=True" \ + --build=missing \ + -r ${CONAN_REMOTE_NAME} \ + --output-folder=/workspace/client/build/${TRITON_CLIENT_PRESET}/conan && \ + conan remote logout ${CONAN_REMOTE_NAME} + +# ── Layer 2: Full source + cmake build ──────────────────────────────────── +# Copy the full source trees now that Conan deps are cached. +COPY ${TRITON_CLIENT_REPO_SUBDIR} client +COPY ${TRITON_COMMON_REPO_SUBDIR} common + +# Configure, build, and install into /workspace/install. +RUN TRITON_VERSION=$(cat /workspace/client/TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ + cmake --preset ${TRITON_CLIENT_PRESET} \ + -S /workspace/client \ + -DCMAKE_INSTALL_PREFIX=/workspace/install \ + -DTRITON_VERSION=${TRITON_VERSION} && \ + cmake --build --preset ${TRITON_CLIENT_PRESET} && \ + cmake --install /workspace/client/build/${TRITON_CLIENT_PRESET} \ + --prefix /workspace/install + +# ── Layer 3: Java API bindings ──────────────────────────────────────────── +# Parity with server/Dockerfile.sdk; amd64 only (javacpp presets are x86_64). +ARG TARGETPLATFORM +ARG JAVA_BINDINGS_MAVEN_VERSION +ARG JAVA_BINDINGS_JAVACPP_PRESETS_TAG +ARG TRITON_CORE_REPO_TAG +ARG TRITON_REPO_ORGANIZATION + +RUN if [ "${TARGETPLATFORM:-}" = "linux/amd64" ] || \ + ([ -z "${TARGETPLATFORM:-}" ] && [ "$(uname -m)" = "x86_64" ]); then \ + source /workspace/client/src/java-api-bindings/scripts/install_dependencies_and_build.sh \ + --maven-version "${JAVA_BINDINGS_MAVEN_VERSION}" \ + --core-tag "${TRITON_CORE_REPO_TAG}" \ + --javacpp-tag "${JAVA_BINDINGS_JAVACPP_PRESETS_TAG}" \ + --jar-install-path /workspace/install/java-api-bindings; \ + fi + +############################################################################ +## SDK container +############################################################################ + +FROM ${BASE_IMAGE} + +SHELL ["/bin/bash", "-euo", "pipefail", "-c"] + +ARG DEBIAN_FRONTEND=noninteractive +ARG DCGM_VERSION +ARG TRITON_ENABLE_GPU +ARG TRITON_SERVER_REPO_SUBDIR + +# Runtime system packages — aligned with server/Dockerfile.sdk. +# python3.12-venv is required to create the isolated runtime venv below. +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + default-jdk \ + gperf \ + libb64-dev \ + libgoogle-perftools-dev \ + libopencv-core-dev \ + libopencv-dev \ + libssl-dev \ + maven \ + perl \ + python3-pdfkit \ + python3.12 \ + python3.12-dev \ + python3.12-venv + +# Isolated runtime venv — only packages needed to run client examples / tests. +RUN python3.12 -m venv /opt/venv-tritonclient + +ENV PATH=/opt/venv-tritonclient/bin:${PATH} + +# Compatibility: many example scripts call 'python' or 'python3'. +RUN ln -sf "$(which python3.12)" /usr/local/bin/python && \ + ln -sf "$(which python3.12)" /usr/local/bin/python3 + +WORKDIR /workspace + +# Copy built artifacts from the build stage. +COPY --from=sdk_build /workspace/client/TRITON_VERSION client/TRITON_VERSION +COPY --from=sdk_build /workspace/install/ install/ + +# Create the versioned client tarball (same convention as server/Dockerfile.sdk). +RUN cd install && \ + VERSION=$(cat /workspace/client/TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ + tar zcf /workspace/v${VERSION}.clients.tar.gz * + +# QA infrastructure — parity with server/Dockerfile.sdk. +RUN mkdir -p qa +COPY ${TRITON_SERVER_REPO_SUBDIR}/qa/L0_sdk qa/L0_sdk +COPY ${TRITON_SERVER_REPO_SUBDIR}/qa/L0_client_build_variants qa/L0_client_build_variants +COPY ${TRITON_SERVER_REPO_SUBDIR}/qa/images/mug.jpg images/mug.jpg + +# Python client unit tests. +COPY --from=sdk_build /workspace/client/src/python/library/tests/ \ + qa/python_client_unit_tests/ + +# NVIDIA DLC license document. +COPY ${TRITON_SERVER_REPO_SUBDIR}/NVIDIA_Deep_Learning_Container_License.pdf . + +# Install the Python client wheel and its optional runtime dependencies. +# attrdict is included for parity with server/Dockerfile.sdk (used by quickstart examples). +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install \ + "grpcio<1.68" \ + "grpcio-tools<1.68" \ + "numpy<2" \ + attrdict \ + pdfkit \ + pillow \ + genai-perf && \ + find install/python/ -maxdepth 1 -type f -name "tritonclient-*linux*.whl" \ + | xargs printf -- '%s[all]' | xargs pip install --upgrade + +# Install Model Analyzer when a repo tag is supplied. +ARG TRITON_MODEL_ANALYZER_REPO_TAG +ARG TRITON_REPO_ORGANIZATION +RUN if [ -n "${TRITON_MODEL_ANALYZER_REPO_TAG:-}" ]; then \ + pip install "git+${TRITON_REPO_ORGANIZATION}/model_analyzer@${TRITON_MODEL_ANALYZER_REPO_TAG}"; \ + fi + +# Install DCGM for GPU-enabled images. +RUN if [ "${TRITON_ENABLE_GPU}" = "ON" ]; then \ + if [ "$(uname -m)" = "x86_64" ]; then arch="x86_64"; else arch="sbsa"; fi && \ + curl -fsSL -o /tmp/cuda-keyring.deb \ + "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/${arch}/cuda-keyring_1.1-1_all.deb" && \ + apt-get install -y /tmp/cuda-keyring.deb && \ + rm /tmp/cuda-keyring.deb && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + datacenter-gpu-manager-4-core=1:${DCGM_VERSION} \ + datacenter-gpu-manager-4-dev=1:${DCGM_VERSION} && \ + rm -rf /var/lib/apt/lists/*; \ + fi + +# Entrypoint banner — parity with server/Dockerfile.sdk. +COPY ${TRITON_SERVER_REPO_SUBDIR}/docker/entrypoint.d/ /opt/nvidia/entrypoint.d/ +RUN sed 's/Server/Server SDK/' /opt/nvidia/entrypoint.d/10-banner.txt | \ + sed 's/^===/=======/' > /opt/nvidia/entrypoint.d/10-banner.new && \ + mv /opt/nvidia/entrypoint.d/10-banner.new /opt/nvidia/entrypoint.d/10-banner.txt + +ENV NVIDIA_PRODUCT_NAME="Triton Server SDK" + +ARG NVIDIA_TRITON_SERVER_SDK_VERSION +ARG NVIDIA_BUILD_ID +ENV NVIDIA_TRITON_SERVER_SDK_VERSION=${NVIDIA_TRITON_SERVER_SDK_VERSION} +ENV NVIDIA_BUILD_ID=${NVIDIA_BUILD_ID} + +ENV PATH=/workspace/install/bin:${PATH} +ENV LD_LIBRARY_PATH=/workspace/install/lib:${LD_LIBRARY_PATH} + +# DLIS-3631: needed by Perf Analyzer CI. +ENV LD_LIBRARY_PATH=/opt/hpcx/ompi/lib:${LD_LIBRARY_PATH} + +ENV TCMALLOC_RELEASE_RATE=200 diff --git a/Dockerfile.sdk.manylinux b/Dockerfile.sdk.manylinux new file mode 100644 index 000000000..ed1d928fa --- /dev/null +++ b/Dockerfile.sdk.manylinux @@ -0,0 +1,182 @@ +# Copyright 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# Multi-stage Conan-based manylinux wheel build for the Triton Python client. +# Produces a manylinux_2_28 wheel compatible with any Linux distro with glibc >= 2.28. +# +# Base image: quay.io/pypa/manylinux_2_28_x86_64 (AlmaLinux 8). +# Python 3.12 is pre-installed at /opt/python/cp312-cp312/. +# +# Build (from monorepo root): +# DOCKER_BUILDKIT=1 docker build \ +# --secret id=conan_token,src=/path/to/artifactory_token.txt \ +# --build-arg TRITON_CLIENT_REPO_SUBDIR=client \ +# --build-arg TRITON_COMMON_REPO_SUBDIR=common \ +# -f client/Dockerfile.sdk.manylinux . +# +# Extract the repaired wheel: +# docker run --rm -v $(pwd)/dist:/out cp -r /workspace/dist/. /out/ +# + +# quay.io/pypa/manylinux_2_28_x86_64 is the official PyPA image based on AlmaLinux 8. +# It provides Python 3.12 at /opt/python/cp312-cp312/ and auditwheel as a system tool. +ARG BASE_IMAGE=quay.io/pypa/manylinux_2_28_x86_64 + +# Subdirectory paths relative to the Docker build context (monorepo root). +ARG TRITON_CLIENT_REPO_SUBDIR=client +ARG TRITON_COMMON_REPO_SUBDIR=common + +# Conan remote credentials (token supplied via Docker BuildKit secret). +ARG CONAN_USER=triton-sdk +ARG CONAN_REMOTE_NAME=sw-dl-triton-conan-local +ARG CONAN_REMOTE_URL=https://artifactory.nvidia.com/artifactory/api/conan/sw-dl-triton-conan-local + +ARG NVIDIA_TRITON_SERVER_SDK_VERSION=unknown +ARG NVIDIA_BUILD_ID=unknown + +# CMake preset and Conan profile to use for the manylinux build. +# The preset disables examples and tests; the profile uses gcc-toolset-13 paths. +ARG TRITON_CLIENT_PRESET=triton-client-release-cpu-manylinux-x86_64 +ARG CONAN_PROFILE=linux-gcc13-release-manylinux-x86_64 + +############################################################################ +## Build stage +############################################################################ + +FROM ${BASE_IMAGE} AS sdk_build + +SHELL ["/bin/bash", "-euo", "pipefail", "-c"] + +# gcc-toolset-13 provides GCC 13 on AlmaLinux 8 at /opt/rh/gcc-toolset-13/root/usr/bin/. +# EPEL provides libb64-devel (base64 encoding used by the HTTP client). +# ninja-build and numactl-devel are already present on the manylinux_2_28 image; +# install them anyway — dnf is a no-op if already installed. +RUN --mount=type=cache,target=/var/cache/dnf,sharing=locked \ + dnf install -y --nodocs epel-release && \ + dnf install -y --nodocs \ + gcc-toolset-13 \ + libb64-devel \ + ninja-build \ + numactl-devel + +# Put gcc-toolset-13 first on PATH so Conan and CMake detect it automatically. +ENV PATH=/opt/rh/gcc-toolset-13/root/usr/bin:${PATH} +ENV LD_LIBRARY_PATH=/opt/rh/gcc-toolset-13/root/usr/lib64:/opt/rh/gcc-toolset-13/root/usr/lib:${LD_LIBRARY_PATH} + +# Use the pre-built Python 3.12 that ships with the manylinux image. +ARG PYTHON=/opt/python/cp312-cp312/bin/python3 + +# Isolated build-time venv. auditwheel is added here alongside Conan/CMake so +# the repair step runs against the same Python used to build the wheel. +RUN --mount=type=cache,target=/root/.cache/pip \ + ${PYTHON} -m venv /opt/build-venv && \ + /opt/build-venv/bin/pip install \ + "conan>=2.0,<3.0" \ + "cmake>=3.31.8" \ + "grpcio-tools<1.68" \ + auditwheel + +ENV PATH=/opt/build-venv/bin:${PATH} + +ARG TRITON_CLIENT_REPO_SUBDIR +ARG TRITON_COMMON_REPO_SUBDIR +ARG TRITON_CLIENT_PRESET +ARG CONAN_PROFILE +ARG CONAN_USER +ARG CONAN_REMOTE_NAME +ARG CONAN_REMOTE_URL + +WORKDIR /workspace + +# ── Layer 1: Conan dependency resolution ────────────────────────────────── +# Copy only the Conan manifest + profiles so this expensive layer is cached +# as long as conanfile.py and the Conan profiles are unchanged. +COPY ${TRITON_CLIENT_REPO_SUBDIR}/conanfile.py client/conanfile.py +COPY ${TRITON_CLIENT_REPO_SUBDIR}/conan/profiles/ client/conan/profiles/ + +# Register the Artifactory remote (no credentials stored in this layer). +RUN conan remote add ${CONAN_REMOTE_NAME} ${CONAN_REMOTE_URL} + +# Resolve and download all Conan packages. +# The Artifactory token is mounted as a BuildKit secret and is never written +# to any image layer. Pass: --secret id=conan_token,src=/path/to/token.txt +RUN --mount=type=secret,id=conan_token \ + conan remote login ${CONAN_REMOTE_NAME} ${CONAN_USER} \ + -p "$(cat /run/secrets/conan_token)" && \ + conan install /workspace/client \ + --profile:host=/workspace/client/conan/profiles/${CONAN_PROFILE} \ + --profile:build=/workspace/client/conan/profiles/${CONAN_PROFILE} \ + -c "tools.cmake:cmake_program=$(which cmake)" \ + -o "&:enable_gpu=False" \ + -o "&:enable_grpc=True" \ + -o "&:enable_http=True" \ + --build=missing \ + -r ${CONAN_REMOTE_NAME} \ + --output-folder=/workspace/client/build/${TRITON_CLIENT_PRESET}/conan && \ + conan remote logout ${CONAN_REMOTE_NAME} + +# ── Layer 2: Full source + cmake build ──────────────────────────────────── +COPY ${TRITON_CLIENT_REPO_SUBDIR} client +COPY ${TRITON_COMMON_REPO_SUBDIR} common + +# Configure, build, and install. +RUN TRITON_VERSION=$(cat /workspace/client/TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ + cmake --preset ${TRITON_CLIENT_PRESET} \ + -S /workspace/client \ + -DCMAKE_INSTALL_PREFIX=/workspace/install \ + -DTRITON_VERSION=${TRITON_VERSION} && \ + cmake --build --preset ${TRITON_CLIENT_PRESET} && \ + cmake --install /workspace/client/build/${TRITON_CLIENT_PRESET} \ + --prefix /workspace/install + +# ── Layer 3: auditwheel repair ──────────────────────────────────────────── +# Bundle shared-lib dependencies into the wheel and apply the manylinux_2_28 +# platform tag so it is installable on any distro with glibc >= 2.28. +RUN auditwheel repair \ + --plat manylinux_2_28_x86_64 \ + --wheel-dir /workspace/dist \ + "$(find /workspace/install/python/ -maxdepth 1 -name 'tritonclient-*linux*.whl')" + +############################################################################ +## Distribution image — contains only the repaired wheel +############################################################################ + +FROM ${BASE_IMAGE} + +WORKDIR /workspace + +COPY --from=sdk_build /workspace/dist/ dist/ + +ARG NVIDIA_TRITON_SERVER_SDK_VERSION +ARG NVIDIA_BUILD_ID +ENV NVIDIA_TRITON_SERVER_SDK_VERSION=${NVIDIA_TRITON_SERVER_SDK_VERSION} +ENV NVIDIA_BUILD_ID=${NVIDIA_BUILD_ID} + +ENV NVIDIA_PRODUCT_NAME="Triton Client SDK (manylinux)" + +# Usage: docker run --rm -v $(pwd)/dist:/out cp -r /workspace/dist/. /out/ +CMD ["find", "/workspace/dist", "-name", "*.whl", "-exec", "ls", "-lh", "{}", ";"] diff --git a/cmake/CMakePresets.json b/cmake/CMakePresets.json new file mode 100644 index 000000000..58b49f02f --- /dev/null +++ b/cmake/CMakePresets.json @@ -0,0 +1,105 @@ +{ + "version": 6, + "cmakeMinimumRequired": { "major": 3, "minor": 31, "patch": 8 }, + "$comment": "Standalone Conan build presets for triton-client. For integrated monorepo builds see server/cmake/presets/CMakePresets.TritonClient.*.json.", + "configurePresets": [ + { + "name": "conan-base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "toolchainFile": "${sourceDir}/build/${presetName}/conan/generators/conan_toolchain.cmake", + "cacheVariables": { "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" } + }, + { + "name": "triton-client-release-cpu-ubuntu-x86_64", + "inherits": "conan-base", + "displayName": "TritonClient — Release, CPU-only, Ubuntu, x86_64", + "description": "CPU-only client library build for Ubuntu Linux on x86_64. No CUDA required.", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "TRITON_ENABLE_GPU": "OFF", + "TRITON_ENABLE_CC_HTTP": "ON", + "TRITON_ENABLE_CC_GRPC": "ON", + "TRITON_ENABLE_PYTHON_HTTP": "ON", + "TRITON_ENABLE_PYTHON_GRPC": "ON", + "TRITON_ENABLE_JAVA_HTTP": "ON", + "TRITON_ENABLE_EXAMPLES": "ON", + "TRITON_ENABLE_TESTS": "ON" + } + }, + { + "name": "triton-client-release-cuda-ubuntu-x86_64", + "inherits": "conan-base", + "displayName": "TritonClient — Release, CUDA, Ubuntu, x86_64", + "description": "GPU-enabled client library build for Ubuntu Linux on x86_64.", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "TRITON_ENABLE_GPU": "ON", + "TRITON_ENABLE_CC_HTTP": "ON", + "TRITON_ENABLE_CC_GRPC": "ON", + "TRITON_ENABLE_PYTHON_HTTP": "ON", + "TRITON_ENABLE_PYTHON_GRPC": "ON", + "TRITON_ENABLE_JAVA_HTTP": "ON", + "TRITON_ENABLE_EXAMPLES": "ON", + "TRITON_ENABLE_TESTS": "ON", + "CMAKE_CUDA_RUNTIME_LIBRARY": "Shared" + } + }, + { + "name": "triton-client-release-cpu-ubuntu-aarch64", + "inherits": "conan-base", + "displayName": "TritonClient — Release, CPU-only, Ubuntu, aarch64", + "description": "CPU-only client library build for Ubuntu Linux on aarch64 (Graviton, Grace).", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "TRITON_ENABLE_GPU": "OFF", + "TRITON_ENABLE_CC_HTTP": "ON", + "TRITON_ENABLE_CC_GRPC": "ON", + "TRITON_ENABLE_PYTHON_HTTP": "ON", + "TRITON_ENABLE_PYTHON_GRPC": "ON", + "TRITON_ENABLE_JAVA_HTTP": "ON", + "TRITON_ENABLE_EXAMPLES": "ON", + "TRITON_ENABLE_TESTS": "ON" + } + }, + { + "name": "triton-client-release-cpu-manylinux-x86_64", + "inherits": "conan-base", + "displayName": "TritonClient — Release, CPU-only, manylinux, x86_64", + "description": "CPU-only manylinux wheel build for broad pip compatibility.", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "TRITON_ENABLE_GPU": "OFF", + "TRITON_ENABLE_CC_HTTP": "ON", + "TRITON_ENABLE_CC_GRPC": "ON", + "TRITON_ENABLE_PYTHON_HTTP": "ON", + "TRITON_ENABLE_PYTHON_GRPC": "ON", + "TRITON_ENABLE_EXAMPLES": "OFF", + "TRITON_ENABLE_TESTS": "OFF" + } + } + ], + "buildPresets": [ + { "name": "triton-client-release-cpu-ubuntu-x86_64", "configurePreset": "triton-client-release-cpu-ubuntu-x86_64", "jobs": 8 }, + { "name": "triton-client-release-cuda-ubuntu-x86_64", "configurePreset": "triton-client-release-cuda-ubuntu-x86_64", "jobs": 8 }, + { "name": "triton-client-release-cpu-ubuntu-aarch64", "configurePreset": "triton-client-release-cpu-ubuntu-aarch64", "jobs": 8 }, + { "name": "triton-client-release-cpu-manylinux-x86_64", "configurePreset": "triton-client-release-cpu-manylinux-x86_64", "jobs": 8 } + ], + "testPresets": [ + { + "name": "triton-client-release-cpu-ubuntu-x86_64", + "configurePreset": "triton-client-release-cpu-ubuntu-x86_64", + "filter": { "exclude": { "label": "requires-gpu" } } + }, + { + "name": "triton-client-release-cuda-ubuntu-x86_64", + "configurePreset": "triton-client-release-cuda-ubuntu-x86_64" + }, + { + "name": "triton-client-release-cpu-ubuntu-aarch64", + "configurePreset": "triton-client-release-cpu-ubuntu-aarch64", + "filter": { "exclude": { "label": "requires-gpu" } } + } + ] +} diff --git a/conan/profiles/linux-gcc13-debug-x86_64 b/conan/profiles/linux-gcc13-debug-x86_64 new file mode 100644 index 000000000..8a8bc7098 --- /dev/null +++ b/conan/profiles/linux-gcc13-debug-x86_64 @@ -0,0 +1,15 @@ +[settings] +os=Linux +arch=x86_64 +compiler=gcc +compiler.version=13 +compiler.libcxx=libstdc++11 +compiler.cppstd=17 +build_type=Debug + +[conf] +tools.cmake:cmake_program=/home/user/.venv/bin/cmake + +[buildenv] +CC=/usr/bin/gcc-13 +CXX=/usr/bin/g++-13 diff --git a/conan/profiles/linux-gcc13-release-manylinux-x86_64 b/conan/profiles/linux-gcc13-release-manylinux-x86_64 new file mode 100644 index 000000000..16ad960ca --- /dev/null +++ b/conan/profiles/linux-gcc13-release-manylinux-x86_64 @@ -0,0 +1,15 @@ +[settings] +os=Linux +arch=x86_64 +compiler=gcc +compiler.version=13 +compiler.libcxx=libstdc++11 +compiler.cppstd=17 +build_type=Release + +[conf] +tools.cmake:cmake_program=/home/user/.venv/bin/cmake + +[buildenv] +CC=/opt/rh/gcc-toolset-13/root/usr/bin/gcc +CXX=/opt/rh/gcc-toolset-13/root/usr/bin/g++ diff --git a/conan/profiles/linux-gcc13-release-x86_64 b/conan/profiles/linux-gcc13-release-x86_64 new file mode 100644 index 000000000..4ad3b65fc --- /dev/null +++ b/conan/profiles/linux-gcc13-release-x86_64 @@ -0,0 +1,15 @@ +[settings] +os=Linux +arch=x86_64 +compiler=gcc +compiler.version=13 +compiler.libcxx=libstdc++11 +compiler.cppstd=17 +build_type=Release + +[conf] +tools.cmake:cmake_program=/home/user/.venv/bin/cmake + +[buildenv] +CC=/usr/bin/gcc-13 +CXX=/usr/bin/g++-13 diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 000000000..1503efe02 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,88 @@ +# Copyright 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from conan.errors import ConanInvalidConfiguration +from conan.tools.cmake import CMakeDeps, CMakeToolchain + +from conan import ConanFile + + +class TritonClientConan(ConanFile): + name = "triton-client" + version = "2.68.0" + settings = "os", "compiler", "build_type", "arch" + options = { + "enable_gpu": [True, False], + "enable_grpc": [True, False], + "enable_http": [True, False], + } + default_options = { + "enable_gpu": False, + "enable_grpc": True, + "enable_http": True, + } + + def validate(self): + if self.settings.os != "Linux": + raise ConanInvalidConfiguration("triton-client only supports Linux") + + def requirements(self): + self.requires("rapidjson/cci.20230929") + self.requires("gtest/1.14.0") + if self.options.enable_http: + self.requires("libcurl/8.18.0") + if self.options.enable_grpc: + self.requires("grpc/1.54.3") + self.requires("protobuf/3.21.12") + self.requires("re2/20230301") + + def configure(self): + if self.options.enable_http: + self.options["libcurl"].shared = False + self.options["libcurl"].with_ssl = "openssl" + if self.options.enable_grpc: + self.options["grpc"].shared = False + self.options["grpc"].cpp_plugin = True + + def layout(self): + # Flat generators folder so CMakePresets toolchainFile path resolves + # as build//conan/generators/conan_toolchain.cmake. + self.folders.generators = "generators" + + def generate(self): + tc = CMakeToolchain(self) + ws = self.recipe_folder + "/.." + # Point to the monorepo sibling so common targets (triton-common-json, + # proto-py-library) are built via add_subdirectory without a network fetch. + tc.variables["TRITON_COMMON_SOURCE_DIR"] = ws + "/common" + tc.variables["TRITON_SKIP_THIRD_PARTY_FETCH"] = True + tc.variables["TRITON_ENABLE_GPU"] = self.options.enable_gpu + tc.variables["TRITON_ENABLE_CC_HTTP"] = self.options.enable_http + tc.variables["TRITON_ENABLE_CC_GRPC"] = self.options.enable_grpc + tc.variables["TRITON_ENABLE_PYTHON_HTTP"] = self.options.enable_http + tc.variables["TRITON_ENABLE_PYTHON_GRPC"] = self.options.enable_grpc + tc.generate() + CMakeDeps(self).generate() diff --git a/src/c++/CMakeLists.txt b/src/c++/CMakeLists.txt index dcd87c10e..f798cb8d0 100644 --- a/src/c++/CMakeLists.txt +++ b/src/c++/CMakeLists.txt @@ -57,39 +57,54 @@ endif() # # Dependencies # -include(FetchContent) -FetchContent_Declare( - repo-common - GIT_REPOSITORY ${TRITON_REPO_ORGANIZATION}/common.git - GIT_TAG ${TRITON_COMMON_REPO_TAG} - GIT_SHALLOW ON -) +if(TRITON_COMMON_SOURCE_DIR) + # Conan mode: common (triton-common-json, proto targets) already added by + # the parent CMakeLists.txt via add_subdirectory(${TRITON_COMMON_SOURCE_DIR}). + # GTest comes from the Conan-provided package; create a compatibility alias + # for the legacy lowercase 'gtest' target name used by tests/. + if(TRITON_ENABLE_TESTS) + find_package(GTest REQUIRED) + if(NOT TARGET gtest) + add_library(gtest ALIAS GTest::gtest) + endif() + endif() +else() + # Legacy mode: fetch repo-common and googletest from the network. + include(FetchContent) + + FetchContent_Declare( + repo-common + GIT_REPOSITORY ${TRITON_REPO_ORGANIZATION}/common.git + GIT_TAG ${TRITON_COMMON_REPO_TAG} + GIT_SHALLOW ON + ) -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/9406a60c7839052e4944ea4dbc8344762a89f9bd.zip -) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/9406a60c7839052e4944ea4dbc8344762a89f9bd.zip + ) -if(TRITON_ENABLE_CC_GRPC) - set(TRITON_COMMON_ENABLE_PROTOBUF ON) - set(TRITON_COMMON_ENABLE_GRPC ON) -endif() # TRITON_ENABLE_CC_GRPC + if(TRITON_ENABLE_CC_GRPC) + set(TRITON_COMMON_ENABLE_PROTOBUF ON) + set(TRITON_COMMON_ENABLE_GRPC ON) + endif() # TRITON_ENABLE_CC_GRPC -if(NOT TRITON_ENABLE_CC_HTTP AND NOT TRITON_ENABLE_EXAMPLES) - set(TRITON_COMMON_ENABLE_JSON OFF) -endif() + if(NOT TRITON_ENABLE_CC_HTTP AND NOT TRITON_ENABLE_EXAMPLES) + set(TRITON_COMMON_ENABLE_JSON OFF) + endif() -if(TRITON_ENABLE_TESTS) - FetchContent_MakeAvailable(googletest) -endif() -FetchContent_MakeAvailable(repo-common) + if(TRITON_ENABLE_TESTS) + FetchContent_MakeAvailable(googletest) + endif() + FetchContent_MakeAvailable(repo-common) -if(TRITON_ENABLE_TESTS) - include_directories( - ${repo-common_SOURCE_DIR}/include - ) -endif() # TRITON_ENABLE_TESTS + if(TRITON_ENABLE_TESTS) + include_directories( + ${repo-common_SOURCE_DIR}/include + ) + endif() # TRITON_ENABLE_TESTS +endif() # # CUDA diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 42ca2c42a..4a0a90d83 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -49,21 +49,28 @@ endif() # # Dependencies # -include(FetchContent) -FetchContent_Declare( - repo-common - GIT_REPOSITORY ${TRITON_REPO_ORGANIZATION}/common.git - GIT_TAG ${TRITON_COMMON_REPO_TAG} - GIT_SHALLOW ON -) +if(TRITON_COMMON_SOURCE_DIR) + # Conan mode: common (proto-py-library, grpc-service-py-library) already + # added by the parent CMakeLists.txt via add_subdirectory(${TRITON_COMMON_SOURCE_DIR}). +else() + # Legacy mode: fetch repo-common from GitHub. + include(FetchContent) -if(TRITON_ENABLE_PYTHON_GRPC) - set(TRITON_COMMON_ENABLE_PROTOBUF ON) - set(TRITON_COMMON_ENABLE_GRPC ON) -endif() # TRITON_ENABLE_PYTHON_GRPC + FetchContent_Declare( + repo-common + GIT_REPOSITORY ${TRITON_REPO_ORGANIZATION}/common.git + GIT_TAG ${TRITON_COMMON_REPO_TAG} + GIT_SHALLOW ON + ) -FetchContent_MakeAvailable(repo-common) + if(TRITON_ENABLE_PYTHON_GRPC) + set(TRITON_COMMON_ENABLE_PROTOBUF ON) + set(TRITON_COMMON_ENABLE_GRPC ON) + endif() # TRITON_ENABLE_PYTHON_GRPC + + FetchContent_MakeAvailable(repo-common) +endif() # # CUDA From a6a75998d4387cfaa1ff7a27a97aa20c1fa9d747 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Mon, 20 Apr 2026 19:17:45 +0000 Subject: [PATCH 02/18] fix(cmake): remove invalid \$comment field from CMakePresets.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CMake rejects unknown top-level keys in CMakePresets.json with "Invalid extra field" — \$comment is not part of the spec. --- cmake/CMakePresets.json | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/CMakePresets.json b/cmake/CMakePresets.json index 58b49f02f..c129e55de 100644 --- a/cmake/CMakePresets.json +++ b/cmake/CMakePresets.json @@ -1,7 +1,6 @@ { "version": 6, "cmakeMinimumRequired": { "major": 3, "minor": 31, "patch": 8 }, - "$comment": "Standalone Conan build presets for triton-client. For integrated monorepo builds see server/cmake/presets/CMakePresets.TritonClient.*.json.", "configurePresets": [ { "name": "conan-base", From b1130240867101214635a1ccc9c3cf697f87fb12 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Mon, 20 Apr 2026 19:21:03 +0000 Subject: [PATCH 03/18] fix(docker): add libopencv-dev to sdk_build stage Examples require OpenCV headers at configure time when TRITON_ENABLE_EXAMPLES=ON; runtime stage already had libopencv-dev. --- Dockerfile.sdk | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile.sdk b/Dockerfile.sdk index 240810887..6e7d92277 100644 --- a/Dockerfile.sdk +++ b/Dockerfile.sdk @@ -97,6 +97,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ g++-13 \ git \ libb64-dev \ + libopencv-dev \ libnuma-dev \ libssl-dev \ maven \ From 44cf25b7193a6f42361cf31e56ee3a64d738fa45 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Mon, 20 Apr 2026 19:35:01 +0000 Subject: [PATCH 04/18] fix(docker): cd to client dir before cmake --preset commands cmake --build --preset resolves CMakePresets.json from CWD, not the source dir. WORKDIR is /workspace so --build --preset was looking for /workspace/CMakePresets.json. Fixed by cd-ing into client/ first. Same fix applied to Dockerfile.sdk.manylinux. --- Dockerfile.sdk | 8 +++++--- Dockerfile.sdk.manylinux | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Dockerfile.sdk b/Dockerfile.sdk index 6e7d92277..70abdeb2b 100644 --- a/Dockerfile.sdk +++ b/Dockerfile.sdk @@ -165,13 +165,15 @@ COPY ${TRITON_CLIENT_REPO_SUBDIR} client COPY ${TRITON_COMMON_REPO_SUBDIR} common # Configure, build, and install into /workspace/install. -RUN TRITON_VERSION=$(cat /workspace/client/TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ +# cmake --preset / --build --preset resolve CMakePresets.json from CWD; +# cd to the client source tree so both commands find client/CMakePresets.json. +RUN cd /workspace/client && \ + TRITON_VERSION=$(cat TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ cmake --preset ${TRITON_CLIENT_PRESET} \ - -S /workspace/client \ -DCMAKE_INSTALL_PREFIX=/workspace/install \ -DTRITON_VERSION=${TRITON_VERSION} && \ cmake --build --preset ${TRITON_CLIENT_PRESET} && \ - cmake --install /workspace/client/build/${TRITON_CLIENT_PRESET} \ + cmake --install build/${TRITON_CLIENT_PRESET} \ --prefix /workspace/install # ── Layer 3: Java API bindings ──────────────────────────────────────────── diff --git a/Dockerfile.sdk.manylinux b/Dockerfile.sdk.manylinux index ed1d928fa..cefc4bde9 100644 --- a/Dockerfile.sdk.manylinux +++ b/Dockerfile.sdk.manylinux @@ -144,13 +144,14 @@ COPY ${TRITON_CLIENT_REPO_SUBDIR} client COPY ${TRITON_COMMON_REPO_SUBDIR} common # Configure, build, and install. -RUN TRITON_VERSION=$(cat /workspace/client/TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ +# cmake --preset / --build --preset resolve CMakePresets.json from CWD. +RUN cd /workspace/client && \ + TRITON_VERSION=$(cat TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ cmake --preset ${TRITON_CLIENT_PRESET} \ - -S /workspace/client \ -DCMAKE_INSTALL_PREFIX=/workspace/install \ -DTRITON_VERSION=${TRITON_VERSION} && \ cmake --build --preset ${TRITON_CLIENT_PRESET} && \ - cmake --install /workspace/client/build/${TRITON_CLIENT_PRESET} \ + cmake --install build/${TRITON_CLIENT_PRESET} \ --prefix /workspace/install # ── Layer 3: auditwheel repair ──────────────────────────────────────────── From ae115a9aa7439b790c64ed60de38291ff876e41c Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Mon, 20 Apr 2026 19:56:17 +0000 Subject: [PATCH 05/18] fix(cmake): hoist RapidJSON include_directories to src/c++ level Examples compile \$ directly into executables; OBJECT library PUBLIC include dirs are not propagated when used as sources rather than via target_link_libraries. Adding find_package + include_directories at the src/c++ level (before library/ and examples/ subdirs) matches the existing pattern for protobuf. --- src/c++/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/c++/CMakeLists.txt b/src/c++/CMakeLists.txt index f798cb8d0..4bba85cd9 100644 --- a/src/c++/CMakeLists.txt +++ b/src/c++/CMakeLists.txt @@ -140,6 +140,15 @@ if(TRITON_ENABLE_CC_GRPC) include_directories($) endif() # TRITON_ENABLE_CC_GRPC +# RapidJSON headers are used via json_utils.h which is compiled directly into +# several example executables via $. +# Use include_directories() here so the path is inherited by all subdirs +# (library/, examples/, tests/), matching the pattern used for protobuf above. +if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_EXAMPLES) + find_package(RapidJSON CONFIG REQUIRED) + include_directories(${RapidJSON_INCLUDE_DIRS}) +endif() + if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC) add_subdirectory(library) endif() # TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC From 6c6ff39157d6ff07d8ea66b5d53810b197d8b088 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Mon, 20 Apr 2026 20:51:25 +0000 Subject: [PATCH 06/18] fix(cmake): use absolute path for ldscript in LINK_FLAGS ninja runs the link command from the preset build root, not from the target's binary subdir. The relative ldscript path works in ExternalProject mode (which sets CWD per-target) but fails in add_subdirectory/preset mode. Use \${CMAKE_CURRENT_BINARY_DIR} for both grpcclient and httpclient. --- src/c++/library/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/c++/library/CMakeLists.txt b/src/c++/library/CMakeLists.txt index a8d0dd9cd..82079bde3 100644 --- a/src/c++/library/CMakeLists.txt +++ b/src/c++/library/CMakeLists.txt @@ -245,7 +245,7 @@ if(TRITON_ENABLE_CC_GRPC) grpcclient PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libgrpcclient.ldscript - LINK_FLAGS "-Wl,--version-script=libgrpcclient.ldscript" + LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libgrpcclient.ldscript" ) endif() # NOT WIN32 AND NOT TRITON_KEEP_TYPEINFO @@ -427,7 +427,7 @@ if(TRITON_ENABLE_CC_HTTP) httpclient PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libhttpclient.ldscript - LINK_FLAGS "-Wl,--version-script=libhttpclient.ldscript" + LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libhttpclient.ldscript" ) endif() # NOT WIN32 From cf437801e066d26e9dbd72734b8918d9cfb3cd96 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Mon, 20 Apr 2026 22:47:12 +0000 Subject: [PATCH 07/18] fix(cmake): set repo-common_BINARY_DIR and add common include path In Conan mode two compat shims were missing after add_subdirectory(common): - repo-common_BINARY_DIR: used by src/python to locate generated model_config_pb2.py (was only found via _deps/repo-common-build in FetchContent mode; now points to triton-common-build). - include_directories(TRITON_COMMON_SOURCE_DIR/include): needed by C++ library and tests for triton/common/triton_json.h. --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3161aacbf..c2cdba570 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,8 +81,12 @@ if(TRITON_SKIP_THIRD_PARTY_FETCH) set(TRITON_COMMON_ENABLE_GRPC ON) endif() add_subdirectory(${TRITON_COMMON_SOURCE_DIR} triton-common-build) - # Compatibility shim so sub-projects that reference repo-common_SOURCE_DIR still resolve. + # Compatibility shims so sub-projects that reference FetchContent variables still resolve. set(repo-common_SOURCE_DIR ${TRITON_COMMON_SOURCE_DIR}) + # repo-common_BINARY_DIR is used by src/python to locate generated protobuf py files. + set(repo-common_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/triton-common-build) + # triton/common/ headers must be on the include path for C++ library and tests. + include_directories(${TRITON_COMMON_SOURCE_DIR}/include) endif() if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC) From ce7bfef588b023afcdd366e542309023abb55f9f Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Tue, 21 Apr 2026 01:44:22 +0000 Subject: [PATCH 08/18] fix(cmake): symlink _deps/repo-common-build for build_wheel.py compat build_wheel.py hardcodes the FetchContent path ../_deps/repo-common-build/ relative to the library binary dir. In Conan/add_subdirectory mode the actual path is triton-common-build/ under the build root. Create a _deps/repo-common-build -> repo-common_BINARY_DIR symlink at configure time so the script finds proto .py files without modification. --- src/python/CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 4a0a90d83..1a85e2601 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -53,6 +53,16 @@ endif() if(TRITON_COMMON_SOURCE_DIR) # Conan mode: common (proto-py-library, grpc-service-py-library) already # added by the parent CMakeLists.txt via add_subdirectory(${TRITON_COMMON_SOURCE_DIR}). + # + # build_wheel.py looks for generated proto .py files via the FetchContent + # convention: ../_deps/repo-common-build/protobuf/ (relative to the library + # binary dir). In Conan mode the actual path is repo-common_BINARY_DIR. + # Create a compatibility symlink so the script finds the files without change. + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_deps") + if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/_deps/repo-common-build") + file(CREATE_LINK "${repo-common_BINARY_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}/_deps/repo-common-build" SYMBOLIC) + endif() else() # Legacy mode: fetch repo-common from GitHub. include(FetchContent) From 868533ce7e4e36a9a2488fe51dbe23a9f49c9f16 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Tue, 21 Apr 2026 05:14:11 +0000 Subject: [PATCH 09/18] fix(conan): disable TRITON_USE_THIRD_PARTY in Conan mode The option defaults to ON and generates cmake --install rules that copy from ../../third-party/grpc/include etc., which don't exist when deps come from Conan packages. Explicitly set it OFF via the toolchain. --- conanfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conanfile.py b/conanfile.py index 1503efe02..be70a7aeb 100644 --- a/conanfile.py +++ b/conanfile.py @@ -79,6 +79,7 @@ def generate(self): # proto-py-library) are built via add_subdirectory without a network fetch. tc.variables["TRITON_COMMON_SOURCE_DIR"] = ws + "/common" tc.variables["TRITON_SKIP_THIRD_PARTY_FETCH"] = True + tc.variables["TRITON_USE_THIRD_PARTY"] = False tc.variables["TRITON_ENABLE_GPU"] = self.options.enable_gpu tc.variables["TRITON_ENABLE_CC_HTTP"] = self.options.enable_http tc.variables["TRITON_ENABLE_CC_GRPC"] = self.options.enable_grpc From 5f74d67dfb54658eab08ad1e02f96efee3b55cb2 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Tue, 21 Apr 2026 16:01:06 +0000 Subject: [PATCH 10/18] fix(java): use rm -f/-rf for optional files in javacpp-presets setup tritondevelopertoolsserver.java may not exist in all javacpp-presets tag versions. Use -f so the script does not fail when the file is absent. --- .../scripts/install_dependencies_and_build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java-api-bindings/scripts/install_dependencies_and_build.sh b/src/java-api-bindings/scripts/install_dependencies_and_build.sh index 73fa30a01..12b690c53 100755 --- a/src/java-api-bindings/scripts/install_dependencies_and_build.sh +++ b/src/java-api-bindings/scripts/install_dependencies_and_build.sh @@ -139,8 +139,8 @@ cd javacpp-presets # Remove developer_tools/server related build if [ ${INCLUDE_DEVELOPER_TOOLS_SERVER} -eq 0 ]; then - rm -r tritonserver/src/gen - rm tritonserver/src/main/java/org/bytedeco/tritonserver/presets/tritondevelopertoolsserver.java + rm -rf tritonserver/src/gen + rm -f tritonserver/src/main/java/org/bytedeco/tritonserver/presets/tritondevelopertoolsserver.java fi mvn clean install --projects .,tritonserver From eb14338bf0c28fe72937a634372e4cc473bdbfdf Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Wed, 22 Apr 2026 00:14:18 +0000 Subject: [PATCH 11/18] fix(docker): skip java bindings when server libs absent; write TRITON_VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Layer 3: check for /opt/tritonserver/lib/libtritonserver.so before running cppbuild.sh — client-only builds skip gracefully with INFO msg. - Layer 2: write TRITON_VERSION file so the runtime COPY succeeds even when client/ has no pre-existing TRITON_VERSION (falls back to 0.0.0). --- Dockerfile.sdk | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Dockerfile.sdk b/Dockerfile.sdk index 70abdeb2b..4711cb0e4 100644 --- a/Dockerfile.sdk +++ b/Dockerfile.sdk @@ -169,6 +169,7 @@ COPY ${TRITON_COMMON_REPO_SUBDIR} common # cd to the client source tree so both commands find client/CMakePresets.json. RUN cd /workspace/client && \ TRITON_VERSION=$(cat TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ + echo "${TRITON_VERSION}" > TRITON_VERSION && \ cmake --preset ${TRITON_CLIENT_PRESET} \ -DCMAKE_INSTALL_PREFIX=/workspace/install \ -DTRITON_VERSION=${TRITON_VERSION} && \ @@ -186,11 +187,15 @@ ARG TRITON_REPO_ORGANIZATION RUN if [ "${TARGETPLATFORM:-}" = "linux/amd64" ] || \ ([ -z "${TARGETPLATFORM:-}" ] && [ "$(uname -m)" = "x86_64" ]); then \ - source /workspace/client/src/java-api-bindings/scripts/install_dependencies_and_build.sh \ - --maven-version "${JAVA_BINDINGS_MAVEN_VERSION}" \ - --core-tag "${TRITON_CORE_REPO_TAG}" \ - --javacpp-tag "${JAVA_BINDINGS_JAVACPP_PRESETS_TAG}" \ - --jar-install-path /workspace/install/java-api-bindings; \ + if [ -f /opt/tritonserver/lib/libtritonserver.so ]; then \ + source /workspace/client/src/java-api-bindings/scripts/install_dependencies_and_build.sh \ + --maven-version "${JAVA_BINDINGS_MAVEN_VERSION}" \ + --core-tag "${TRITON_CORE_REPO_TAG}" \ + --javacpp-tag "${JAVA_BINDINGS_JAVACPP_PRESETS_TAG}" \ + --jar-install-path /workspace/install/java-api-bindings; \ + else \ + echo "INFO: Skipping Java API bindings — libtritonserver.so not found in base image (client-only build)"; \ + fi; \ fi ############################################################################ From 509916923bb7bfa19e8c637e0bd52f647b2207a4 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Wed, 22 Apr 2026 01:01:15 +0000 Subject: [PATCH 12/18] fix(docker): default TRITON_MODEL_ANALYZER_REPO_TAG to main --- Dockerfile.sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.sdk b/Dockerfile.sdk index 4711cb0e4..724ba7222 100644 --- a/Dockerfile.sdk +++ b/Dockerfile.sdk @@ -64,7 +64,7 @@ ARG JAVA_BINDINGS_JAVACPP_PRESETS_TAG=1.5.8 # Model Analyzer — installed only when TRITON_MODEL_ANALYZER_REPO_TAG is set. ARG TRITON_REPO_ORGANIZATION=http://github.com/triton-inference-server ARG TRITON_CORE_REPO_TAG=main -ARG TRITON_MODEL_ANALYZER_REPO_TAG= +ARG TRITON_MODEL_ANALYZER_REPO_TAG=main # Conan remote credentials (token supplied via Docker BuildKit secret). ARG CONAN_USER=triton-sdk From aa666f0ed2d1dfc80aa3d02ea802cc4bd702e4f1 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Wed, 22 Apr 2026 01:16:25 +0000 Subject: [PATCH 13/18] fix(manylinux): force protobuf source build to avoid glibc mismatch The Conan-cached protobuf/3.21.12 binary (built on Ubuntu) ships a protoc that requires GLIBC_2.33/2.34 and GLIBCXX_3.4.29/3.4.32. AlmaLinux 8 (manylinux_2_28 base) only provides glibc 2.28, so protoc crashes when gRPC tries to run it during its build step. Add --build=protobuf to force protoc to compile natively on the AlmaLinux 8 build machine, where it will link against glibc 2.28. --- Dockerfile.sdk.manylinux | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile.sdk.manylinux b/Dockerfile.sdk.manylinux index cefc4bde9..c09eac1b0 100644 --- a/Dockerfile.sdk.manylinux +++ b/Dockerfile.sdk.manylinux @@ -135,6 +135,7 @@ RUN --mount=type=secret,id=conan_token \ -o "&:enable_grpc=True" \ -o "&:enable_http=True" \ --build=missing \ + --build=protobuf \ -r ${CONAN_REMOTE_NAME} \ --output-folder=/workspace/client/build/${TRITON_CLIENT_PRESET}/conan && \ conan remote logout ${CONAN_REMOTE_NAME} From 9882d749bd8f18a2b9a9cddff818f71db6209a4c Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Wed, 22 Apr 2026 04:58:40 +0000 Subject: [PATCH 14/18] fix(manylinux): build protobuf/grpc/gtest from source; skip auditwheel for pure-Python wheel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three root causes diagnosed and fixed: 1. Conan --build=protobuf was silently ignored — Conan 2 uses fnmatch so the bare name "protobuf" does not match "protobuf/3.21.12"; changed to '--build=protobuf*', added '--build=grpc*' and '--build=gtest*' so all three packages that were downloaded as Ubuntu-compiled binaries (glibc 2.38+) are now rebuilt from source on AlmaLinux 8 (glibc 2.28), eliminating GLIBC_2.33 / __isoc23_strtol linker errors. 2. Conan profile cppstd=17 caused protobuf package ID to differ from the Artifactory record (gnu17), so the --build flag hit a compatible-package fallback and was bypassed. Changed to cppstd=gnu17 to align IDs. 3. auditwheel repair was called on a pure-Python wheel (py3-none-any); it requires ELF binaries inside the wheel. tritonclient has no compiled C extensions — stubs are generated Python. Replace repair with a direct cp of the any-platform wheel. --- Dockerfile.sdk.manylinux | 22 ++++++++++--------- .../linux-gcc13-release-manylinux-x86_64 | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Dockerfile.sdk.manylinux b/Dockerfile.sdk.manylinux index c09eac1b0..fc2f89979 100644 --- a/Dockerfile.sdk.manylinux +++ b/Dockerfile.sdk.manylinux @@ -97,8 +97,7 @@ RUN --mount=type=cache,target=/root/.cache/pip \ /opt/build-venv/bin/pip install \ "conan>=2.0,<3.0" \ "cmake>=3.31.8" \ - "grpcio-tools<1.68" \ - auditwheel + "grpcio-tools<1.68" ENV PATH=/opt/build-venv/bin:${PATH} @@ -135,7 +134,9 @@ RUN --mount=type=secret,id=conan_token \ -o "&:enable_grpc=True" \ -o "&:enable_http=True" \ --build=missing \ - --build=protobuf \ + '--build=protobuf*' \ + '--build=grpc*' \ + '--build=gtest*' \ -r ${CONAN_REMOTE_NAME} \ --output-folder=/workspace/client/build/${TRITON_CLIENT_PRESET}/conan && \ conan remote logout ${CONAN_REMOTE_NAME} @@ -155,13 +156,14 @@ RUN cd /workspace/client && \ cmake --install build/${TRITON_CLIENT_PRESET} \ --prefix /workspace/install -# ── Layer 3: auditwheel repair ──────────────────────────────────────────── -# Bundle shared-lib dependencies into the wheel and apply the manylinux_2_28 -# platform tag so it is installable on any distro with glibc >= 2.28. -RUN auditwheel repair \ - --plat manylinux_2_28_x86_64 \ - --wheel-dir /workspace/dist \ - "$(find /workspace/install/python/ -maxdepth 1 -name 'tritonclient-*linux*.whl')" +# ── Layer 3: place wheel in dist/ ───────────────────────────────────────── +# tritonclient is a pure-Python wheel (gRPC stubs + pure-Python HTTP client +# wrappers; no compiled C extensions). auditwheel repair requires ELF +# binaries inside the wheel and cannot process a py3-none-any wheel. +# Copy it directly; pip install works on any platform without repair. +RUN mkdir -p /workspace/dist && \ + cp "$(find /workspace/install/python/ -maxdepth 1 -name 'tritonclient-*-any.whl' | head -1)" \ + /workspace/dist/ ############################################################################ ## Distribution image — contains only the repaired wheel diff --git a/conan/profiles/linux-gcc13-release-manylinux-x86_64 b/conan/profiles/linux-gcc13-release-manylinux-x86_64 index 16ad960ca..6e1d0491b 100644 --- a/conan/profiles/linux-gcc13-release-manylinux-x86_64 +++ b/conan/profiles/linux-gcc13-release-manylinux-x86_64 @@ -4,7 +4,7 @@ arch=x86_64 compiler=gcc compiler.version=13 compiler.libcxx=libstdc++11 -compiler.cppstd=17 +compiler.cppstd=gnu17 build_type=Release [conf] From c7a0f3c29068e28f49ad3060837d1d98649ceb4a Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Wed, 22 Apr 2026 05:01:32 +0000 Subject: [PATCH 15/18] =?UTF-8?q?chore(issues):=20save=20context=20for=20T?= =?UTF-8?q?RI-971=20=E2=80=94=20cmake-client-dependency-management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-971.cmake-client-dependency-management.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 issues/TRI-971/TRI-971.cmake-client-dependency-management.md diff --git a/issues/TRI-971/TRI-971.cmake-client-dependency-management.md b/issues/TRI-971/TRI-971.cmake-client-dependency-management.md new file mode 100644 index 000000000..0f7810dab --- /dev/null +++ b/issues/TRI-971/TRI-971.cmake-client-dependency-management.md @@ -0,0 +1,30 @@ + + +## Summary + +### Manylinux build fixed (Dockerfile.sdk.manylinux) + +Three root causes diagnosed and fixed across multiple build attempts (v2–v6): + +**Fix 1 — Conan profile cppstd=gnu17** (`conan/profiles/linux-gcc13-release-manylinux-x86_64`): +- `cppstd=17` produced a different Conan package ID from the Artifactory record (which uses `gnu17`), causing Conan's compatible-package fallback to bypass `--build` flags entirely. +- Changed to `compiler.cppstd=gnu17`. + +**Fix 2 — `--build` glob patterns for source builds**: +- Conan 2 uses fnmatch, so `--build=protobuf` does NOT match `protobuf/3.21.12`. Changed to `'--build=protobuf*'`. +- Ubuntu-compiled Conan packages (protobuf, grpc, gtest) reference `GLIBC_2.33`/`__isoc23_strtol` (glibc 2.38+) which is absent on AlmaLinux 8 (glibc 2.28). Added `'--build=grpc*'` and `'--build=gtest*'` to force all three to build from source. + +**Fix 3 — Remove auditwheel, copy wheel directly**: +- `auditwheel repair` requires ELF binaries inside the wheel. `tritonclient` is a pure-Python wheel (gRPC stubs + pure-Python HTTP client wrappers, no compiled C extensions). Replaced with `cp` of the `py3-none-any.whl`. +- Also removed `auditwheel` from the pip install in the venv. + +### Commits in this session +- `b7828840` — fix(manylinux): build protobuf/grpc/gtest from source; skip auditwheel for pure-Python wheel + +### Branch +`mchornyi/tri-971-cmake-client-dependency-management` — pushed to origin. + +### Open items +- The manylinux Dockerfile now works but produces a `py3-none-any.whl` (pure Python). If compiled C extensions are ever added to tritonclient, auditwheel should be re-introduced. +- The `common/src/CMakeLists.txt` unconditionally includes tests (`add_subdirectory(test)`) regardless of `TRITON_ENABLE_TESTS=OFF` in the client preset. Consider fixing this upstream in the common repo. +- `gtest/1.14.0` is an unconditional Conan dependency in `conanfile.py` regardless of whether tests are enabled — should be made conditional on an `enable_tests` option. From 5c6b024456718980740f01966d9fa4af61847e36 Mon Sep 17 00:00:00 2001 From: Misha Chornyi Date: Thu, 30 Apr 2026 00:46:56 +0000 Subject: [PATCH 16/18] fix(cmake): backfill legacy include-dir vars for common subdirectory; guard GTest re-find Conan 2 creates imported targets but does not set the legacy CMake variables (RAPIDJSON_INCLUDE_DIRS, Protobuf_INCLUDE_DIRS) that common/CMakeLists.txt uses in target_include_directories / include_directories. Pre-find both packages in the Conan mode block of the root CMakeLists.txt and populate the variables from the imported target's INTERFACE_INCLUDE_DIRECTORIES so the common subdirectory compiles correctly. Guard find_package(GTest) in src/c++/CMakeLists.txt with if(NOT TARGET GTest::gtest): common unconditionally finds GTest, so a second find_package call triggers Conan's GTest-Target-release.cmake to call set_property on already-defined ALIAS targets, which CMake rejects. Also bump Dockerfile.sdk base image to 26.04-py3-min and fix the wheel glob to match the py3-none-any wheel produced by the pure-Python tritonclient build. --- CMakeLists.txt | 16 ++++++++++++++++ Dockerfile.sdk | 4 ++-- src/c++/CMakeLists.txt | 4 +++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c2cdba570..836b3400f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,22 @@ if(TRITON_SKIP_THIRD_PARTY_FETCH) set(TRITON_COMMON_ENABLE_PROTOBUF ON) set(TRITON_COMMON_ENABLE_GRPC ON) endif() + # Conan creates imported targets for its packages but does not set the + # legacy cmake variables (RAPIDJSON_INCLUDE_DIRS, Protobuf_INCLUDE_DIRS) + # that common/CMakeLists.txt uses for target_include_directories / include_directories. + # Pre-find the packages here and backfill those variables from the imported + # targets so the common subdirectory compiles correctly. + find_package(RapidJSON CONFIG REQUIRED) + if(NOT RAPIDJSON_INCLUDE_DIRS AND TARGET rapidjson) + get_target_property(RAPIDJSON_INCLUDE_DIRS rapidjson INTERFACE_INCLUDE_DIRECTORIES) + endif() + if(TRITON_ENABLE_CC_GRPC OR TRITON_ENABLE_PYTHON_GRPC) + set(protobuf_MODULE_COMPATIBLE TRUE CACHE BOOL "protobuf_MODULE_COMPATIBLE" FORCE) + find_package(Protobuf CONFIG REQUIRED) + if(NOT Protobuf_INCLUDE_DIRS AND TARGET protobuf::libprotobuf) + get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) + endif() + endif() add_subdirectory(${TRITON_COMMON_SOURCE_DIR} triton-common-build) # Compatibility shims so sub-projects that reference FetchContent variables still resolve. set(repo-common_SOURCE_DIR ${TRITON_COMMON_SOURCE_DIR}) diff --git a/Dockerfile.sdk b/Dockerfile.sdk index 724ba7222..08bafbd88 100644 --- a/Dockerfile.sdk +++ b/Dockerfile.sdk @@ -42,7 +42,7 @@ # --build-arg TRITON_CLIENT_PRESET=triton-client-release-cuda-ubuntu-x86_64 ... # -ARG BASE_IMAGE=nvcr.io/nvidia/tritonserver:26.03-py3-min +ARG BASE_IMAGE=nvcr.io/nvidia/tritonserver:26.04-py3-min # Subdirectory paths relative to the Docker build context (monorepo root). ARG TRITON_CLIENT_REPO_SUBDIR=client @@ -276,7 +276,7 @@ RUN --mount=type=cache,target=/root/.cache/pip \ pdfkit \ pillow \ genai-perf && \ - find install/python/ -maxdepth 1 -type f -name "tritonclient-*linux*.whl" \ + find install/python/ -maxdepth 1 -type f -name "tritonclient-*any*.whl" \ | xargs printf -- '%s[all]' | xargs pip install --upgrade # Install Model Analyzer when a repo tag is supplied. diff --git a/src/c++/CMakeLists.txt b/src/c++/CMakeLists.txt index 4bba85cd9..6bf3b403c 100644 --- a/src/c++/CMakeLists.txt +++ b/src/c++/CMakeLists.txt @@ -64,7 +64,9 @@ if(TRITON_COMMON_SOURCE_DIR) # GTest comes from the Conan-provided package; create a compatibility alias # for the legacy lowercase 'gtest' target name used by tests/. if(TRITON_ENABLE_TESTS) - find_package(GTest REQUIRED) + if(NOT TARGET GTest::gtest) + find_package(GTest REQUIRED) + endif() if(NOT TARGET gtest) add_library(gtest ALIAS GTest::gtest) endif() From e407db1b5fb90c8d8e5574383f1405e371137a4f Mon Sep 17 00:00:00 2001 From: "M. Chornyi" <99709299+mc-nv@users.noreply.github.com> Date: Thu, 14 May 2026 17:40:19 +0000 Subject: [PATCH 17/18] fix(docker): full L0_sdk parity with reference py3-sdk container Five fixes uncovered by running qa/L0_sdk against the Conan-based SDK image: * Source the authoritative TRITON_VERSION from server/TRITON_VERSION in both Dockerfile.sdk and Dockerfile.sdk.manylinux. The tarball (v.clients.tar.gz), wheel (tritonclient-), and /workspace/TRITON_VERSION now ship the real release version instead of "0.0.0". * Run `conan install --deployer=full_deploy` and copy every Conan package include/ and lib*/ tree into /workspace/install. This brings grpc/grpc++/grpcpp/absl/google/curl/openssl headers plus the static archives that qa/L0_sdk compiles and links against. Without this, the legacy ExternalProject layout could not be reproduced. * Symlink perf_analyzer into /usr/local/bin/. The pip-installed perf_analyzer entry point lives at /opt/venv-tritonclient/bin/; the L0_sdk wheel-install check requires the exact path /usr/local/bin/ perf_analyzer. * Pin setuptools<80 in the runtime venv. setuptools 80+ no longer ships bundled pkg_resources, which tritonclient.utils.cuda_shared_ memory still imports. * Mirror Conan's libssl.a / libcrypto.a into /usr/lib/x86_64-linux-gnu/ and remove the unversioned libssl.so / libcrypto.so symlinks. Conan-built libcurl.a uses OpenSSL 3.2 symbols (SSL_get0_group_name) that are absent from Ubuntu's OpenSSL 3.0 .a; gcc -lssl -lcrypto now resolves to our archives. The .so.3 SONAME is preserved for Python's ssl module. L0_sdk now reports "*** Test Passed ***" inside triton-client-sdk:tri-971-local (grpc_test, grpc_test_static, http_test, http_test_static all green). --- Dockerfile.sdk | 44 ++++++++++++++++++++++++++++++++++++---- Dockerfile.sdk.manylinux | 6 +++++- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/Dockerfile.sdk b/Dockerfile.sdk index 08bafbd88..63a11de92 100644 --- a/Dockerfile.sdk +++ b/Dockerfile.sdk @@ -156,6 +156,8 @@ RUN --mount=type=secret,id=conan_token \ -o "&:enable_http=True" \ --build=missing \ -r ${CONAN_REMOTE_NAME} \ + --deployer=full_deploy \ + --deployer-folder=/workspace/conan-deploy \ --output-folder=/workspace/client/build/${TRITON_CLIENT_PRESET}/conan && \ conan remote logout ${CONAN_REMOTE_NAME} @@ -163,13 +165,15 @@ RUN --mount=type=secret,id=conan_token \ # Copy the full source trees now that Conan deps are cached. COPY ${TRITON_CLIENT_REPO_SUBDIR} client COPY ${TRITON_COMMON_REPO_SUBDIR} common +# Authoritative version is owned by the server repo; copy it into client/. +ARG TRITON_SERVER_REPO_SUBDIR +COPY ${TRITON_SERVER_REPO_SUBDIR}/TRITON_VERSION client/TRITON_VERSION # Configure, build, and install into /workspace/install. # cmake --preset / --build --preset resolve CMakePresets.json from CWD; # cd to the client source tree so both commands find client/CMakePresets.json. RUN cd /workspace/client && \ - TRITON_VERSION=$(cat TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ - echo "${TRITON_VERSION}" > TRITON_VERSION && \ + TRITON_VERSION=$(cat TRITON_VERSION) && \ cmake --preset ${TRITON_CLIENT_PRESET} \ -DCMAKE_INSTALL_PREFIX=/workspace/install \ -DTRITON_VERSION=${TRITON_VERSION} && \ @@ -177,6 +181,21 @@ RUN cd /workspace/client && \ cmake --install build/${TRITON_CLIENT_PRESET} \ --prefix /workspace/install +# Propagate Conan dependency headers + libs into /workspace/install so the +# bundled SDK tarball matches the legacy ExternalProject layout consumed by +# qa/L0_sdk (which compiles against grpcpp/grpcpp.h and links libcurl.a). +RUN set -e; \ + DEPLOY=/workspace/conan-deploy/full_deploy/host; \ + mkdir -p /workspace/install/include /workspace/install/lib; \ + for inc in $(find $DEPLOY -mindepth 3 -name include -type d); do \ + cp -rn "$inc/." /workspace/install/include/ 2>/dev/null || true; \ + done; \ + for lib in $(find $DEPLOY -mindepth 3 \( -name lib -o -name lib64 \) -type d); do \ + find "$lib" -maxdepth 1 -type f \ + \( -name '*.a' -o -name '*.so' -o -name '*.so.*' \) \ + -exec cp -P {} /workspace/install/lib/ \; ; \ + done + # ── Layer 3: Java API bindings ──────────────────────────────────────────── # Parity with server/Dockerfile.sdk; amd64 only (javacpp presets are x86_64). ARG TARGETPLATFORM @@ -244,12 +263,26 @@ RUN ln -sf "$(which python3.12)" /usr/local/bin/python && \ WORKDIR /workspace # Copy built artifacts from the build stage. +# /workspace/TRITON_VERSION mirrors the convention used by server/Dockerfile.sdk. COPY --from=sdk_build /workspace/client/TRITON_VERSION client/TRITON_VERSION +COPY --from=sdk_build /workspace/client/TRITON_VERSION TRITON_VERSION COPY --from=sdk_build /workspace/install/ install/ +# Conan's libcurl.a is built against OpenSSL 3.2 (uses SSL_get0_group_name), +# which is newer than the OpenSSL 3.0.x archives shipped by Ubuntu's +# libssl-dev. When tests link with `-lssl -lcrypto`, gcc prefers the +# unversioned libssl.so symlink (-> 3.0) over the .a archive. Make `-lssl` +# resolve to our static archive instead: copy our .a files into the multiarch +# search dir and drop the unversioned .so symlinks (the .so.3 SONAME stays for +# runtime consumers like Python's ssl module). +RUN cp /workspace/install/lib/libssl.a /workspace/install/lib/libcrypto.a \ + /usr/lib/x86_64-linux-gnu/ && \ + rm -f /usr/lib/x86_64-linux-gnu/libssl.so \ + /usr/lib/x86_64-linux-gnu/libcrypto.so + # Create the versioned client tarball (same convention as server/Dockerfile.sdk). RUN cd install && \ - VERSION=$(cat /workspace/client/TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ + VERSION=$(cat /workspace/TRITON_VERSION) && \ tar zcf /workspace/v${VERSION}.clients.tar.gz * # QA infrastructure — parity with server/Dockerfile.sdk. @@ -267,6 +300,7 @@ COPY ${TRITON_SERVER_REPO_SUBDIR}/NVIDIA_Deep_Learning_Container_License.pdf . # Install the Python client wheel and its optional runtime dependencies. # attrdict is included for parity with server/Dockerfile.sdk (used by quickstart examples). +# setuptools provides pkg_resources, used by tritonclient.utils.cuda_shared_memory. RUN --mount=type=cache,target=/root/.cache/pip \ pip install \ "grpcio<1.68" \ @@ -275,9 +309,11 @@ RUN --mount=type=cache,target=/root/.cache/pip \ attrdict \ pdfkit \ pillow \ + "setuptools<80" \ genai-perf && \ find install/python/ -maxdepth 1 -type f -name "tritonclient-*any*.whl" \ - | xargs printf -- '%s[all]' | xargs pip install --upgrade + | xargs printf -- '%s[all]' | xargs pip install --upgrade && \ + ln -sf /opt/venv-tritonclient/bin/perf_analyzer /usr/local/bin/perf_analyzer # Install Model Analyzer when a repo tag is supplied. ARG TRITON_MODEL_ANALYZER_REPO_TAG diff --git a/Dockerfile.sdk.manylinux b/Dockerfile.sdk.manylinux index fc2f89979..1bf2d4ee3 100644 --- a/Dockerfile.sdk.manylinux +++ b/Dockerfile.sdk.manylinux @@ -49,6 +49,8 @@ ARG BASE_IMAGE=quay.io/pypa/manylinux_2_28_x86_64 # Subdirectory paths relative to the Docker build context (monorepo root). ARG TRITON_CLIENT_REPO_SUBDIR=client ARG TRITON_COMMON_REPO_SUBDIR=common +# Authoritative TRITON_VERSION lives in the server repo. +ARG TRITON_SERVER_REPO_SUBDIR=server # Conan remote credentials (token supplied via Docker BuildKit secret). ARG CONAN_USER=triton-sdk @@ -144,11 +146,13 @@ RUN --mount=type=secret,id=conan_token \ # ── Layer 2: Full source + cmake build ──────────────────────────────────── COPY ${TRITON_CLIENT_REPO_SUBDIR} client COPY ${TRITON_COMMON_REPO_SUBDIR} common +ARG TRITON_SERVER_REPO_SUBDIR +COPY ${TRITON_SERVER_REPO_SUBDIR}/TRITON_VERSION client/TRITON_VERSION # Configure, build, and install. # cmake --preset / --build --preset resolve CMakePresets.json from CWD. RUN cd /workspace/client && \ - TRITON_VERSION=$(cat TRITON_VERSION 2>/dev/null || echo "0.0.0") && \ + TRITON_VERSION=$(cat TRITON_VERSION) && \ cmake --preset ${TRITON_CLIENT_PRESET} \ -DCMAKE_INSTALL_PREFIX=/workspace/install \ -DTRITON_VERSION=${TRITON_VERSION} && \ From fe8ed98884f625a4210a965d8504c408b9d888ea Mon Sep 17 00:00:00 2001 From: "M. Chornyi" <99709299+mc-nv@users.noreply.github.com> Date: Thu, 14 May 2026 18:25:55 +0000 Subject: [PATCH 18/18] fix(docker): address code-review feedback on L0_sdk parity commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-ups from code review of e407db1: * Multi-arch guard for the OpenSSL .a override in the final stage. Resolve the multiarch directory from `uname -m` instead of hardcoding `/usr/lib/x86_64-linux-gnu/`, so a future arm64 build fails fast with a clear message instead of a confusing `cp` error. * Replace `for X in $(find ...)` with `while IFS= read -r X` + process substitution in the Conan dep-copy step. Word-split-safe if a future Conan package name ever contains whitespace. * Drop `2>/dev/null` from the `cp -rn` calls so genuine errors (no-space, permission, etc.) surface in build logs. The `|| true` already covers the expected `cp -n` collision exits. * Tighten the `setuptools<80` comment to state the actual reason (80+ removed bundled `pkg_resources`). * Document `--build-arg TRITON_SERVER_REPO_SUBDIR=server` in the Dockerfile.sdk.manylinux header so the example invocation matches Dockerfile.sdk. * Bump copyright year on both Dockerfiles to 2025-2026. Rebuilt and re-ran qa/L0_sdk inside the image — all four sub-tests remain green. --- Dockerfile.sdk | 30 +++++++++++++++++++----------- Dockerfile.sdk.manylinux | 3 ++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Dockerfile.sdk b/Dockerfile.sdk index 63a11de92..aff887b37 100644 --- a/Dockerfile.sdk +++ b/Dockerfile.sdk @@ -1,4 +1,4 @@ -# Copyright 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -184,17 +184,19 @@ RUN cd /workspace/client && \ # Propagate Conan dependency headers + libs into /workspace/install so the # bundled SDK tarball matches the legacy ExternalProject layout consumed by # qa/L0_sdk (which compiles against grpcpp/grpcpp.h and links libcurl.a). +# `cp -rn` exits 1 when -n skips a colliding file; allow that specific exit +# but surface other errors (no-space, permission, etc.). RUN set -e; \ DEPLOY=/workspace/conan-deploy/full_deploy/host; \ mkdir -p /workspace/install/include /workspace/install/lib; \ - for inc in $(find $DEPLOY -mindepth 3 -name include -type d); do \ - cp -rn "$inc/." /workspace/install/include/ 2>/dev/null || true; \ - done; \ - for lib in $(find $DEPLOY -mindepth 3 \( -name lib -o -name lib64 \) -type d); do \ + while IFS= read -r inc; do \ + cp -rn "$inc/." /workspace/install/include/ || true; \ + done < <(find "$DEPLOY" -mindepth 3 -name include -type d); \ + while IFS= read -r lib; do \ find "$lib" -maxdepth 1 -type f \ \( -name '*.a' -o -name '*.so' -o -name '*.so.*' \) \ -exec cp -P {} /workspace/install/lib/ \; ; \ - done + done < <(find "$DEPLOY" -mindepth 3 \( -name lib -o -name lib64 \) -type d) # ── Layer 3: Java API bindings ──────────────────────────────────────────── # Parity with server/Dockerfile.sdk; amd64 only (javacpp presets are x86_64). @@ -275,10 +277,15 @@ COPY --from=sdk_build /workspace/install/ install/ # resolve to our static archive instead: copy our .a files into the multiarch # search dir and drop the unversioned .so symlinks (the .so.3 SONAME stays for # runtime consumers like Python's ssl module). -RUN cp /workspace/install/lib/libssl.a /workspace/install/lib/libcrypto.a \ - /usr/lib/x86_64-linux-gnu/ && \ - rm -f /usr/lib/x86_64-linux-gnu/libssl.so \ - /usr/lib/x86_64-linux-gnu/libcrypto.so +RUN case "$(uname -m)" in \ + x86_64) MULTIARCH=x86_64-linux-gnu ;; \ + aarch64) MULTIARCH=aarch64-linux-gnu ;; \ + *) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;; \ + esac && \ + cp /workspace/install/lib/libssl.a /workspace/install/lib/libcrypto.a \ + "/usr/lib/${MULTIARCH}/" && \ + rm -f "/usr/lib/${MULTIARCH}/libssl.so" \ + "/usr/lib/${MULTIARCH}/libcrypto.so" # Create the versioned client tarball (same convention as server/Dockerfile.sdk). RUN cd install && \ @@ -300,7 +307,8 @@ COPY ${TRITON_SERVER_REPO_SUBDIR}/NVIDIA_Deep_Learning_Container_License.pdf . # Install the Python client wheel and its optional runtime dependencies. # attrdict is included for parity with server/Dockerfile.sdk (used by quickstart examples). -# setuptools provides pkg_resources, used by tritonclient.utils.cuda_shared_memory. +# setuptools<80: setuptools 80+ removed the bundled pkg_resources module, which +# tritonclient.utils.cuda_shared_memory still imports at module load time. RUN --mount=type=cache,target=/root/.cache/pip \ pip install \ "grpcio<1.68" \ diff --git a/Dockerfile.sdk.manylinux b/Dockerfile.sdk.manylinux index 1bf2d4ee3..8f33cd29c 100644 --- a/Dockerfile.sdk.manylinux +++ b/Dockerfile.sdk.manylinux @@ -1,4 +1,4 @@ -# Copyright 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -36,6 +36,7 @@ # --secret id=conan_token,src=/path/to/artifactory_token.txt \ # --build-arg TRITON_CLIENT_REPO_SUBDIR=client \ # --build-arg TRITON_COMMON_REPO_SUBDIR=common \ +# --build-arg TRITON_SERVER_REPO_SUBDIR=server \ # -f client/Dockerfile.sdk.manylinux . # # Extract the repaired wheel: