This is an automated email from the ASF dual-hosted git repository.
junrushao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new 437323c doc: Merge C++ tooling and C++ packaging (#429)
437323c is described below
commit 437323c9aecce445409820527abcf237c1c66dc1
Author: Junru Shao <[email protected]>
AuthorDate: Thu Feb 5 14:35:20 2026 -0800
doc: Merge C++ tooling and C++ packaging (#429)
---
docs/index.rst | 1 -
docs/packaging/cpp_packaging.md | 90 ------------------
docs/packaging/cpp_tooling.rst | 205 ++++++++++++++++++++++++++--------------
3 files changed, 134 insertions(+), 162 deletions(-)
diff --git a/docs/index.rst b/docs/index.rst
index a3570ef..62768c7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -72,7 +72,6 @@ Table of Contents
packaging/python_packaging.rst
packaging/stubgen.rst
packaging/cpp_tooling.rst
- packaging/cpp_packaging.md
.. toctree::
:maxdepth: 1
diff --git a/docs/packaging/cpp_packaging.md b/docs/packaging/cpp_packaging.md
deleted file mode 100644
index 585536f..0000000
--- a/docs/packaging/cpp_packaging.md
+++ /dev/null
@@ -1,90 +0,0 @@
-<!--- Licensed to the Apache Software Foundation (ASF) under one -->
-<!--- or more contributor license agreements. See the NOTICE file -->
-<!--- distributed with this work for additional information -->
-<!--- regarding copyright ownership. The ASF licenses this file -->
-<!--- to you under the Apache License, Version 2.0 (the -->
-<!--- "License"); you may not use this file except in compliance -->
-<!--- with the License. You may obtain a copy of the License at -->
-
-<!--- http://www.apache.org/licenses/LICENSE-2.0 -->
-
-<!--- Unless required by applicable law or agreed to in writing, -->
-<!--- software distributed under the License is distributed on an -->
-<!--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -->
-<!--- KIND, either express or implied. See the License for the -->
-<!--- specific language governing permissions and limitations -->
-<!--- under the License. -->
-# C++ Packaging and Distribution
-
-This guide explains how to package and distribute C++ libraries that use
tvm-ffi, with a focus on ABI compatibility and cross-platform distribution.
-
-## Distribution and ABI Compatibility
-
-When distributing kernels or libraries that use tvm-ffi, it's important to
understand the ABI compatibility challenges that arise from glibc versioning.
This section provides guidance for kernel authors and library distributors.
-
-### Understanding the ABI Challenge
-
-While tvm-ffi uses a C ABI at the interface level (through DLTensor,
TVMFFISafeCallType, etc.), the tvm-ffi library itself is written in C++ and
depends on specific versions of glibc and the C++ standard library. This
creates potential compatibility issues from two perspectives:
-
-**Consumer Perspective:**
-Applications that link against `libtvm_ffi.so` must use a compatible glibc
version. If the glibc version mismatches, STL and glibc function symbols may be
incompatible, leading to runtime errors or undefined behavior.
-
-**Producer/Kernel Distributor Perspective:**
-Even when kernel authors expose their functionality through the tvm-ffi
interface (which solves cross-framework ABI issues like tensor representation),
if their compiled `kernel.so` shared library contains ANY glibc or tvm_ffi
symbols, consumers with different glibc versions may encounter undefined symbol
errors at load time.
-
-### The manylinux Solution
-
-The recommended solution is to use the
[manylinux](https://github.com/pypa/manylinux) approach, which is the standard
way Python packages handle cross-platform binary distribution. The key
principle is to build on an old glibc version and run on newer versions.
-
-Since glibc maintains forward compatibility (mostly), libraries built against
an older glibc version will work on systems with newer glibc versions. The
`apache-tvm-ffi` Python wheel is already built using manylinux-compatible
environments.
-
-### Practical Guidance for Kernel Distributors
-
-#### For Pure C++ Library Distribution
-
-If you're distributing C++ libraries or CUDA kernels:
-
-1. **Use a Docker image with an old glibc version** for building:
-
- ```bash
- # See CONTRIBUTING.md for pre-built Docker images
- # Or use manylinux Docker images as a base
- docker pull quay.io/pypa/manylinux2014_x86_64
- ```
-
-2. **For CUDA kernels**, ensure both your host launching code and the kernel
are built in this environment:
-
- ```bash
- # Inside the container
- nvcc -shared -Xcompiler -fPIC your_cuda_kernel.cu -o kernel.so \
- $(tvm-ffi-config --cxxflags) \
- $(tvm-ffi-config --ldflags) \
- $(tvm-ffi-config --libs)
- ```
-
-3. **Link against manylinux-compatible tvm_ffi.so**: Use the tvm-ffi library
from the `apache-tvm-ffi` wheel, which is already manylinux-compatible.
-
-#### Build System Considerations
-
-- **Containerized builds**: Many C++ projects use containerized build systems.
Adapt your existing Docker setup to use manylinux base images or images with
older glibc versions.
-- **CI/CD pipelines**: Configure your continuous integration to build in
manylinux environments. GitHub Actions and other CI services support
Docker-based builds.
-- **Testing**: Always test your distributed binaries on multiple Linux
distributions to verify compatibility.
-
-### Verification
-
-To check the glibc version your binary depends on:
-
-```bash
-objdump -T your_kernel.so | grep GLIBC_
-```
-
-This shows the minimum glibc version required. Ensure it's compatible with
your target deployment environments.
-
-### Summary
-
-- **Build on old glibc** (via manylinux or old Linux distributions)
-- **Run on new glibc** (forward compatibility guaranteed)
-- **Use containerized builds** for reproducible environments
-- **Test across distributions** to verify compatibility
-
-For more details on setting up development environments, see `CONTRIBUTING.md`.
diff --git a/docs/packaging/cpp_tooling.rst b/docs/packaging/cpp_tooling.rst
index 2e1e920..4dbad2d 100644
--- a/docs/packaging/cpp_tooling.rst
+++ b/docs/packaging/cpp_tooling.rst
@@ -18,8 +18,10 @@
C++ Tooling
===========
-This guide covers the TVM-FFI C++ toolchain, focusing on header layout, CMake
-integration, and editor setup for a smooth local workflow.
+This guide covers the TVM-FFI C++ toolchain: header layout, build integration,
+library distribution, and editor setup.
+For an end-to-end walkthrough that builds, loads, and calls a C++/CUDA kernel,
+see :doc:`../get_started/quickstart`.
.. admonition:: Prerequisite
:class: hint
@@ -36,54 +38,52 @@ integration, and editor setup for a smooth local workflow.
C++ Headers
-----------
-**Core APIs.** Most of the APIs are exposed via a single umbrella header.
+**Core APIs.** A single umbrella header exposes most of the API surface,
+including :doc:`functions <../concepts/func_module>`,
+:doc:`objects <../concepts/object_and_class>`,
+:doc:`Any/AnyView <../concepts/any>`,
+:doc:`tensors <../concepts/tensor>`, and
+:doc:`exception handling <../concepts/exception_handling>`.
.. code-block:: cpp
#include <tvm/ffi/tvm_ffi.h>
-Extra features live in dedicated headers under the
+Extra features live in dedicated headers under
`tvm/ffi/extra/
<https://github.com/apache/tvm-ffi/tree/main/include/tvm/ffi/extra>`_
-subdirectory and should be included only when needed.
+and should be included only when needed:
-**Environment API**. Use the environment API to access the caller's allocator,
-stream, and device:
+- **Environment API** -- allocator, stream, and device access
+ (see :doc:`../concepts/tensor` for usage):
+ ``#include <tvm/ffi/extra/c_env_api.h>``
+- **Dynamic module loading** (see :ref:`sec:module`):
+ ``#include <tvm/ffi/extra/module.h>``
+- **CUBIN launcher** (see :doc:`../guides/cubin_launcher`):
+ ``#include <tvm/ffi/extra/cuda/cubin_launcher.h>``
-.. code-block:: cpp
-
- #include <tvm/ffi/extra/c_env_api.h>
-
-
-**Dynamic module loading**. Dynamic module loading lives in the extra API and
-requires its own header:
-
-.. code-block:: cpp
-
- #include <tvm/ffi/extra/module.h>
+Build with TVM-FFI
+------------------
-**CUBIN launcher**. See :doc:`CUBIN launching utilities
<../guides/cubin_launcher>`; the header is:
-
-.. code-block:: cpp
-
- #include <tvm/ffi/extra/cuda/cubin_launcher.h>
-
-
-CMake Usage
------------
+CMake
+~~~~~
TVM-FFI ships CMake utilities and imported targets through its package
configuration.
The two primary functions are ``tvm_ffi_configure_target`` and
``tvm_ffi_install``,
both defined in ``cmake/Utils/Library.cmake``.
+.. hint::
+
+ See `examples/python_packaging/CMakeLists.txt
<https://github.com/apache/tvm-ffi/blob/main/examples/python_packaging/CMakeLists.txt>`_
+ for a complete working example.
+
Configure Target
-~~~~~~~~~~~~~~~~
+""""""""""""""""
-The configure helper wires a target to TVM-FFI and provides sensible defaults.
-It links the TVM-FFI headers and shared library, and it configures debug
symbol handling.
-Optionally, it runs the Python :ref:`stub generation <sec-stubgen>` tool after
-the build completes.
+``tvm_ffi_configure_target`` wires a CMake target to TVM-FFI with sensible
+defaults: it links headers and the shared library, configures debug symbols,
+and optionally runs :ref:`stub generation <sec-stubgen>` as a post-build step.
.. code-block:: cmake
@@ -116,14 +116,16 @@ the build completes.
:STUB_PREFIX: (default: "") Module prefix passed to the stub generator.
Requires
``STUB_DIR`` and ``STUB_INIT=ON``.
+See :ref:`sec-stubgen-cmake` for a detailed explanation of each ``STUB_*``
option
+and the generation modes they control.
+
Install Target
-~~~~~~~~~~~~~~
+""""""""""""""
-The install helper handles extra artifacts associated with a target.
-``DESTINATION`` defaults to ``.`` (relative to ``CMAKE_INSTALL_PREFIX``).
-On Apple platforms the target ``.dSYM`` bundle is installed when present.
-On non-Apple platforms, this is currently a no-op.
+``tvm_ffi_install`` installs platform-specific artifacts for a target.
+On Apple platforms it installs the ``.dSYM`` bundle when present;
+on other platforms this is currently a no-op.
.. code-block:: cmake
@@ -135,47 +137,104 @@ On non-Apple platforms, this is currently a no-op.
:DESTINATION: Install destination directory relative to
``CMAKE_INSTALL_PREFIX``.
-CMake Example
-~~~~~~~~~~~~~
+Set ``tvm_ffi_ROOT``
+""""""""""""""""""""
-.. code-block:: cmake
+If ``find_package(tvm_ffi CONFIG REQUIRED)`` fails because CMake cannot locate
+the package, pass ``tvm_ffi_ROOT`` explicitly:
- find_package(tvm_ffi CONFIG REQUIRED) # requires tvm_ffi_ROOT
- tvm_ffi_configure_target(my-shared-lib) # configure TVM-FFI linkage
- install(TARGETS my-shared-lib DESTINATION .)
- tvm_ffi_install(my-shared-lib DESTINATION .) # install extra artifacts
+.. code-block:: bash
+ cmake -S . -B build \
+ -Dtvm_ffi_ROOT="$(tvm-ffi-config --cmakedir)"
-Set ``tvm_ffi_ROOT``
-~~~~~~~~~~~~~~~~~~~~
+.. note::
+
+ When packaging Python wheels with scikit-build-core, ``tvm_ffi_ROOT`` is
+ discovered automatically from the active Python environment.
-For a pure C++ build, CMake may fail when it reaches
-.. code-block:: cmake
+GCC/NVCC
+~~~~~~~~
+
+For quick prototyping or CI scripts without CMake, invoke ``g++`` or ``nvcc``
+directly with flags from ``tvm-ffi-config``.
+The examples below are from the :doc:`Quick Start <../get_started/quickstart>`
tutorial:
- find_package(tvm_ffi CONFIG REQUIRED)
+.. tabs::
-if it cannot locate the TVM-FFI package. In that case, set
-``tvm_ffi_ROOT`` to the TVM-FFI CMake package directory.
+ .. group-tab:: C++
+
+ .. literalinclude:: ../../examples/quickstart/raw_compile.sh
+ :language: bash
+ :start-after: [cpp_compile.begin]
+ :end-before: [cpp_compile.end]
+
+ .. group-tab:: CUDA
+
+ .. literalinclude:: ../../examples/quickstart/raw_compile.sh
+ :language: bash
+ :start-after: [cuda_compile.begin]
+ :end-before: [cuda_compile.end]
+
+The three ``tvm-ffi-config`` flags provide:
+
+:``--cxxflags``: Include paths and compile definitions (``-I...``, ``-D...``)
+:``--ldflags``: Library search paths (``-L...``, ``-Wl,-rpath,...``)
+:``--libs``: Libraries to link (``-ltvm_ffi``)
+
+**RPATH handling.** The resulting shared library links against
``libtvm_ffi.so``,
+so the dynamic linker must be able to find it at load time:
+
+- **Python distribution.** ``import tvm_ffi`` preloads ``libtvm_ffi.so`` into
the
+ process before any user library is loaded, so the RPATH requirement is
already
+ satisfied without additional linker flags.
+- **Pure C++ distribution.** You must ensure ``libtvm_ffi.so`` is on the
library
+ search path. Either set ``-Wl,-rpath,$(tvm-ffi-config --libdir)`` at link
time,
+ or place ``libtvm_ffi.so`` alongside your binary.
+
+
+Library Distribution
+--------------------
+
+When distributing pre-built shared libraries on Linux, glibc symbol versioning
+can cause load-time failures on systems with a different glibc version.
+The standard solution is the `manylinux <https://github.com/pypa/manylinux>`_
+approach: **build on old glibc, run on new**.
+
+**Build environment.** Use a manylinux Docker image:
.. code-block:: bash
- cmake -S . -B build \
- -Dtvm_ffi_ROOT="$(tvm-ffi-config --cmakedir)"
+ docker pull quay.io/pypa/manylinux2014_x86_64
+Build host and device code inside the container. For CUDA:
-.. note::
+.. code-block:: bash
- When packaging Python wheels with scikit-build-core, ``tvm_ffi_ROOT`` is
- discovered automatically from the active Python environment, so you usually
- do not need to set it explicitly.
+ nvcc -shared -Xcompiler -fPIC your_kernel.cu -o kernel.so \
+ $(tvm-ffi-config --cxxflags) \
+ $(tvm-ffi-config --ldflags) \
+ $(tvm-ffi-config --libs)
+
+**Verify glibc requirements.** Inspect the minimum glibc version your binary
requires:
+
+.. code-block:: bash
+
+ objdump -T your_kernel.so | grep GLIBC_
+
+The ``apache-tvm-ffi`` wheel is already manylinux-compatible, so linking
against
+it inside a manylinux build environment produces portable binaries.
-VSCode/Cursor
--------------
+Editor Setup
+------------
-The following settings help CMake Tools integrate with TVM-FFI and generate the
-``compile_commands.json`` used by clangd:
+The following configuration enables code completion and diagnostics in
+VSCode, Cursor, or any editor backed by clangd.
+
+**CMake Tools (VSCode/Cursor).** Add these workspace settings so CMake Tools
+can locate TVM-FFI and generate ``compile_commands.json``:
.. code-block:: json
@@ -190,19 +249,14 @@ The following settings help CMake Tools integrate with
TVM-FFI and generate the
}
}
-
.. important::
Make sure ``Python_EXECUTABLE`` and ``tvm_ffi_ROOT`` match the virtual
environment you intend to use.
-
-clangd
-------
-
-Create a ``.clangd`` file at your project root and point it to the CMake
-compilation database. The snippet below also removes NVCC flags that clangd
-does not understand:
+**clangd.** Create a ``.clangd`` file at the project root pointing to the CMake
+compilation database. The snippet below also strips NVCC flags that clangd
+does not recognize:
.. code-block:: yaml
@@ -213,5 +267,14 @@ does not understand:
- --generate-code*
- -Xcompiler*
-Make sure your CMake configure step enables ``compile_commands.json`` via
-``-DCMAKE_EXPORT_COMPILE_COMMANDS=ON``.
+
+Further Reading
+---------------
+
+- :doc:`../get_started/quickstart`: End-to-end walkthrough building and
shipping a C++/CUDA kernel
+- :doc:`stubgen`: Generating Python type stubs from C++ reflection metadata
+- :doc:`python_packaging`: Packaging shared libraries as Python wheels
+- :doc:`../concepts/func_module`: Defining and exporting TVM-FFI functions
+- :doc:`../concepts/object_and_class`: Defining C++ classes with
cross-language reflection
+- :doc:`../concepts/exception_handling`: Error handling across language
boundaries
+- :doc:`../concepts/abi_overview`: Low-level C ABI details