Library packaging
September 18, 2026 ยท View on GitHub
Python wheels and native archives use separate, standards-appropriate workflows. Terminology in this document follows the canonical definitions of carrier, adapter, and wrapper.
Python wheels
Every independently shippable distribution owns a pyproject.toml at its package root. Package discovery supports
the normal two-component layout, such as isaacsim/common/pyproject.toml, and named flat roots, such as
isaacsim_deprecated/pyproject.toml. That file is authoritative for the Python project name, dynamic version,
supported Python version, runtime dependencies, and PEP 517 backend. CMake remains authoritative for the wheel payload.
Build requirements and runtime requirements are different contracts: [build-system].requires advertises the backend
versions that can build the project from source, while [project].dependencies becomes public Requires-Dist wheel
metadata. Internal source/libraries dependency names are listed in the isaacsim_libraries_metadata dynamic provider,
which appends exact requirements derived from the shared VERSION; external requirements remain static and may use
supported ranges. Concrete tools selected for an Isaac Sim release do not replace either published contract.
Authored Python project and requirement names use canonical PEP 508 hyphens, such as isaacsim-common; CMake group
selectors retain their underscore form, such as --group isaacsim_common.
Build the libraries and assemble their wheels:
cd source/libraries
./build.sh -r --wheel
Select distributions by repeating --group and override the output directory when needed:
./build.sh -r --wheel --group isaacsim_common --output-dir ../../_cmake_build/my-wheelhouse
Exercise the supported lower bounds with separate environments and build trees:
./build.sh -r --test --wheel --dependency-profile minimum
locked is the default and uses the concrete versions selected for ordinary release production. minimum pins
direct build/test tools to their declared lower bounds. Newer versions are evaluated only by updating and reviewing
pixi.lock; ordinary builds never perform a floating solve. Test and wheel subprocesses isolate PYTHONPATH to the
selected profile. The selected versions affect artifact production and validation, not wheel runtime metadata.
Without --group, the tool assembles every discovered package whose generated manifest declares at least one Python
import. It skips C- and C++-only packages. Explicitly selecting a native-only package is an error rather than an empty
wheel.
The standalone command configures and builds the complete module graph in
_cmake_build/isaacsim-libraries-release. Wheel assembly validates the CMake source directory, configuration, Python
executable, and required package options before installing anything. Rerun the matching standalone build after
changing compiled module sources or CMake configuration.
For each package, the wheel tool creates a unique temporary directory under
_cmake_build/isaacsim-libraries-wheel-stage, installs only the already-built <group>-python CMake component, and
invokes python -m build --wheel with scikit-build-core's CMake integration disabled. Scikit-build-core owns Python
core metadata, wheel tags, WHEEL, RECORD, archive layout, and future wheel-specification changes; it never
configures or compiles CMake. The tool validates the completed wheel and atomically publishes it to the output
directory. Temporary installation and backend output directories are removed after assembly, including after a
failure. Separate packages can be assembled concurrently.
Schema projects may declare named wheel variants in [tool.isaacsim-library]. Their standalone default installs the
matching <group>-python-<variant> component and receives a PEP 427 build tag such as 1usd2505; carrier manifests
select their required variant explicitly, such as usd2511. Schema wheels remain py3-none-any because their payload
contains Python and USD data rather than native code. Keep variants in separate wheelhouses for general pip consumers:
wheel build tags distinguish artifacts but do not express runtime compatibility to pip's resolver. Carrier staging
selects the exact version, build tag, and pure-wheel tag before exposing a one-wheel local index to pip.
Validation checks the distribution name and version, exact internal package requirements, registered imports,
py.typed markers, implicit namespace layout, and the installed package manifest. Requirement names and specifiers
are normalized with the standard packaging parser. Internal wheel requirements must exist in the native package
graph and must be unconditional exact shared-version pins. A native-only dependency may be omitted from wheel
metadata. Source tests, tool caches, bytecode, and symlinks are also rejected. Additional external Python requirements
and their supported ranges remain owned by pyproject.toml.
Use the wheel tool instead of invoking python -m build directly. The frontend needs the private CMake component stage
that the tool supplies through backend configuration; pyproject.toml intentionally contains no source-tree or build-
tree payload paths.
For wheels containing native code, the backend-generated platform tag describes the build host. Producing a wheel for a release portability policy, such as manylinux, is a separate CI repair and validation step performed with the platform's standard wheel tooling; do not change the filename or metadata tag manually.
Validate a wheel by installing it into a clean environment without the source or build tree on PYTHONPATH, importing
each module, querying its version through importlib.metadata, and checking its installed files. Source tests, caches,
and symlinks must not be present.
The command writes wheels to _cmake_build/isaacsim-libraries-artifacts/<configuration> by default. Backend scratch
trees, CMake install stages, and generated artifacts are not part of a package's source layout. Do not commit them.
Run the packaging unit tests without a compiled library build:
PYTHONPATH=<python-test-deps> <library-python> -m unittest discover -s packaging/tests -v
Here, <library-python> is the locked interpreter in .pixi/envs/build-driver, and <python-test-deps> is the
site-packages directory in the selected locked or minimum Pixi test environment.
Kit carrier artifacts
Use a carrier build when a Kit extension needs both the Python wheel and compile-time native SDK for one distribution:
./build.sh -r --test --carrier isaacsim.common
The carrier build configures the complete native module graph, then creates a standards-based wheel and installs only
the selected distribution's native runtime and development CMake components into the carrier stage. A carrier may
declare a disjoint Python-module projection when multiple Kit extensions reuse one complete wheel; only those leaf
packages enter that extension's pip_prebundle. It validates the wheel and SDK's shared package manifests. SDK
archives are produced only by the explicit native archive workflow below.
See Kit carrier extensions for the carrier layout, root-build integration,
dependency ownership, and validation contract.
Native archives
package.py creates native artifacts from CMake install components. It uses only the Python standard library and the
CMake executable that configured the build.
runtimecreates a platform-specific.tar.gzwith shared libraries, registered runtime data, package metadata, the repository release version, and per-module native ABI metadata.sdkcombines the runtime and development components, adding public headers, import libraries, and the relocatable CMake package.
Build the native-only profile before packaging:
./build.sh -r --profile cpp-library
python packaging/package.py runtime \
--build-dir ../../_cmake_build/isaacsim-libraries-cpp-library \
--output-dir ../../_cmake_build/isaacsim-libraries-artifacts/release --group isaacsim_common
python packaging/package.py sdk \
--build-dir ../../_cmake_build/isaacsim-libraries-cpp-library \
--output-dir ../../_cmake_build/isaacsim-libraries-artifacts/release --group isaacsim_common
--build-dir, --output-dir, and --group are required. Use --config with a multi-configuration generator and
--cmake only when the configuring CMake executable is not on PATH. The tool recreates a private .staging
directory below the output directory and removes it before returning.
The tool reads the artifact version from the installed package manifest. It has no version override, so artifact names
cannot diverge from source/libraries/VERSION. Artifact names are
<group>-<version>-<platform>-runtime.tar.gz or <group>-<version>-<platform>-sdk.tar.gz. Native archives are ordinary
install prefixes; validate an SDK by extracting it and using find_package(<group> CONFIG REQUIRED) from a separate
consumer project. An archive contains only the selected distribution. For a package with exact internal dependencies,
extract the dependency runtime or SDK archives into the same prefix, or provide their prefixes through
CMAKE_PREFIX_PATH; the generated package configuration discovers and version-checks them rather than copying them
into the dependent archive. Archive creation also verifies that every internal manifest dependency requires the
package's exact shared version.