From f003ec71d9061294231936ae675bc6b4d8bedf1b Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 17:07:48 +0000 Subject: [PATCH 01/33] Bump usd-core dependency to 26.05 to fix USD physics crash Resolves a fatal crash in libusd_ms triggered by LoadUsdPhysicsFromRange, caused by ABI incompatibility in the 25.11 USD library (nvbugspro #6441062). --- pyproject.toml | 2 +- .../isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst | 5 +++++ source/isaaclab/test/cli/test_source_package_metadata.py | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst diff --git a/pyproject.toml b/pyproject.toml index 97a50399e946..61918159799f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,7 @@ dependencies = [ # OpenUSD (kit-less mode). Both packages vendor a complete ``pxr`` runtime, so # they must never co-install: usd-core supplies pxr where it has wheels (x86_64), # usd-exchange supplies it on aarch64 (where usd-core has no wheel). - "usd-core>=25.11,<26.0 ; platform_machine in 'x86_64 AMD64'", + "usd-core>=26.05,<27.0 ; platform_machine in 'x86_64 AMD64'", "usd-exchange>=2.2 ; platform_machine in 'aarch64 arm64'", # avoid broken hf-xet pre-release cached on NVIDIA Artifactory "hf-xet>=1.4.1,<2.0.0 ; platform_machine in 'x86_64 AMD64 aarch64 arm64'", diff --git a/source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst b/source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst new file mode 100644 index 000000000000..a6c3ee0fe9dc --- /dev/null +++ b/source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst @@ -0,0 +1,5 @@ +Changed +^^^^^^^ + +* Bumped ``usd-core`` dependency from ``>=25.11,<26.0`` to ``>=26.05,<27.0`` on x86_64 to resolve + a crash in ``libusd_ms`` triggered by USD physics loading (``LoadUsdPhysicsFromRange``). diff --git a/source/isaaclab/test/cli/test_source_package_metadata.py b/source/isaaclab/test/cli/test_source_package_metadata.py index 5f2ff176899f..f25634f8fff6 100644 --- a/source/isaaclab/test/cli/test_source_package_metadata.py +++ b/source/isaaclab/test/cli/test_source_package_metadata.py @@ -23,8 +23,8 @@ def _repo_root() -> Path: raise RuntimeError("Could not find Isaac Lab repository root.") -def test_isaaclab_usd_core_pin_stays_on_isaacsim_compatible_usd25_abi(): - """The kit-less USD package must stay on the Isaac Sim compatible USD 25 ABI.""" +def test_isaaclab_usd_core_pin_stays_on_isaacsim_compatible_usd26_abi(): + """The kit-less USD package must stay on the Isaac Sim compatible USD 26 ABI.""" with (_repo_root() / "pyproject.toml").open("rb") as f: pyproject = tomllib.load(f) @@ -32,7 +32,7 @@ def test_isaaclab_usd_core_pin_stays_on_isaacsim_compatible_usd25_abi(): dependency for dependency in pyproject["project"]["dependencies"] if dependency.startswith("usd-core") ] - assert usd_core_dependencies == ["usd-core>=25.11,<26.0 ; platform_machine in 'x86_64 AMD64'"] + assert usd_core_dependencies == ["usd-core>=26.05,<27.0 ; platform_machine in 'x86_64 AMD64'"] def test_isaaclab_standalone_usd_providers_are_platform_disjoint(): From b9883d4e765801b091f0b28ab07e34b66da3941f Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 17:20:02 +0000 Subject: [PATCH 02/33] Fix benchmark test fixture expecting stale usd-core 25.11 version Update the hardcoded usd_core_version fixture value to 26.05 to match the dependency pin bumped in the previous commit. --- source/isaaclab/test/benchmark/test_capture.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/isaaclab/test/benchmark/test_capture.py b/source/isaaclab/test/benchmark/test_capture.py index 01c3ba794a7e..5a2644bd789f 100644 --- a/source/isaaclab/test/benchmark/test_capture.py +++ b/source/isaaclab/test/benchmark/test_capture.py @@ -72,7 +72,7 @@ def test_capture_versions_preserves_runtime_packages(): StringMetadata(name="ovphysx_version", data="3.0.5"), StringMetadata(name="mujoco_version", data="3.8.1"), StringMetadata(name="cuda_bindings_version", data="12.9.4"), - StringMetadata(name="usd_core_version", data="25.11"), + StringMetadata(name="usd_core_version", data="26.05"), StringMetadata(name="isaaclab_release_version", data="3.0.0"), ] bm = _Bm({"VersionInfo": _Rec(MeasurementData(measurements=[], metadata=md, artefacts=[]))}) @@ -89,7 +89,7 @@ def test_capture_versions_preserves_runtime_packages(): assert versions.ovphysx == "3.0.5" assert versions.mujoco == "3.8.1" assert versions.cuda_bindings == "12.9.4" - assert versions.usd_core == "25.11" + assert versions.usd_core == "26.05" assert versions.isaaclab_release == "3.0.0" From b639c8aea19538b8289aa17e0615f9a9e3a28bde Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 19:17:19 +0000 Subject: [PATCH 03/33] patch usd-core ext path --- isaaclab.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/isaaclab.sh b/isaaclab.sh index 941dba9e462e..3896328fe467 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -55,6 +55,16 @@ if [ -d "$ISAACLAB_PATH/_isaac_sim" ]; then export PYTHONPATH="$env_site_packages:$PYTHONPATH" fi fi + # In OV/Isaac Sim environments omni.usd.libs ships the authoritative pxr + # runtime (NVIDIA-patched OpenUSD). usd-core is a kit-less fallback + # installed for environments without Isaac Sim. When both are present, + # omni.usd.libs must take precedence so that Isaac Sim's pxr patches and + # schema customisations are active rather than the vanilla usd-core build. + _omni_usd_libs=$(ls -d "$ISAACLAB_PATH/_isaac_sim/extscache/omni.usd.libs-"*/ 2>/dev/null | sort -V | tail -1) + if [ -n "$_omni_usd_libs" ]; then + export PYTHONPATH="$_omni_usd_libs:$PYTHONPATH" + fi + unset _omni_usd_libs else echo "[WARNING] _isaac_sim is present but _isaac_sim/setup_conda_env.sh or _isaac_sim/setup_python_env.sh is missing; Isaac Sim env vars not exported." >&2 echo "[WARNING] Re-extract the Isaac Sim binary zip if you intend to use the bundled binary." >&2 From 45d5da8b8fbad601561d557f711509b849f3124d Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 19:20:37 +0000 Subject: [PATCH 04/33] bat usd-core patch --- isaaclab.bat | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/isaaclab.bat b/isaaclab.bat index 131c75e16e01..28ef202c75e1 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -39,6 +39,14 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( echo [WARNING] _isaac_sim is present but _isaac_sim\setup_conda_env.bat is missing; Isaac Sim env vars not exported. 1>&2 echo [WARNING] Re-extract the Isaac Sim Windows zip if you intend to use the bundled binary. 1>&2 ) + rem In OV/Isaac Sim environments omni.usd.libs ships the authoritative pxr + rem runtime (NVIDIA-patched OpenUSD). usd-core is a kit-less fallback + rem installed for environments without Isaac Sim. When both are present, + rem omni.usd.libs must take precedence so that Isaac Sim's pxr patches and + rem schema customisations are active rather than the vanilla usd-core build. + for /d %%D in ("%ISAACLAB_PATH%\_isaac_sim\extscache\omni.usd.libs-*") do ( + set "PYTHONPATH=%%D;!PYTHONPATH!" + ) ) rem Execute CLI. From 1279e7e0d2882f6a1c909d1125f9feba9eecf490 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 19:53:16 +0000 Subject: [PATCH 05/33] update --- isaaclab.bat | 8 ----- isaaclab.sh | 10 ------- .../isaaclab/isaaclab/cli/commands/install.py | 29 +++++++++++++++++++ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 28ef202c75e1..131c75e16e01 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -39,14 +39,6 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( echo [WARNING] _isaac_sim is present but _isaac_sim\setup_conda_env.bat is missing; Isaac Sim env vars not exported. 1>&2 echo [WARNING] Re-extract the Isaac Sim Windows zip if you intend to use the bundled binary. 1>&2 ) - rem In OV/Isaac Sim environments omni.usd.libs ships the authoritative pxr - rem runtime (NVIDIA-patched OpenUSD). usd-core is a kit-less fallback - rem installed for environments without Isaac Sim. When both are present, - rem omni.usd.libs must take precedence so that Isaac Sim's pxr patches and - rem schema customisations are active rather than the vanilla usd-core build. - for /d %%D in ("%ISAACLAB_PATH%\_isaac_sim\extscache\omni.usd.libs-*") do ( - set "PYTHONPATH=%%D;!PYTHONPATH!" - ) ) rem Execute CLI. diff --git a/isaaclab.sh b/isaaclab.sh index 3896328fe467..941dba9e462e 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -55,16 +55,6 @@ if [ -d "$ISAACLAB_PATH/_isaac_sim" ]; then export PYTHONPATH="$env_site_packages:$PYTHONPATH" fi fi - # In OV/Isaac Sim environments omni.usd.libs ships the authoritative pxr - # runtime (NVIDIA-patched OpenUSD). usd-core is a kit-less fallback - # installed for environments without Isaac Sim. When both are present, - # omni.usd.libs must take precedence so that Isaac Sim's pxr patches and - # schema customisations are active rather than the vanilla usd-core build. - _omni_usd_libs=$(ls -d "$ISAACLAB_PATH/_isaac_sim/extscache/omni.usd.libs-"*/ 2>/dev/null | sort -V | tail -1) - if [ -n "$_omni_usd_libs" ]; then - export PYTHONPATH="$_omni_usd_libs:$PYTHONPATH" - fi - unset _omni_usd_libs else echo "[WARNING] _isaac_sim is present but _isaac_sim/setup_conda_env.sh or _isaac_sim/setup_python_env.sh is missing; Isaac Sim env vars not exported." >&2 echo "[WARNING] Re-extract the Isaac Sim binary zip if you intend to use the bundled binary." >&2 diff --git a/source/isaaclab/isaaclab/cli/commands/install.py b/source/isaaclab/isaaclab/cli/commands/install.py index 6ba086a9a35d..24d25879f020 100644 --- a/source/isaaclab/isaaclab/cli/commands/install.py +++ b/source/isaaclab/isaaclab/cli/commands/install.py @@ -138,6 +138,28 @@ def _torch_first_on_sys_path_is_prebundle(python_exe: str, *, env: dict[str, str return result.returncode == 1 +def _maybe_uninstall_kitless_pxr(pip_cmd: list[str]) -> None: + """Uninstall kit-less pxr packages when Isaac Sim's omni.usd.libs is present. + + ``usd-core`` (x86_64) and ``usd-exchange`` (aarch64) provide a standalone + pxr runtime for use in kit-less environments. When a full Isaac Sim + installation is present, its ``omni.usd.libs`` extension supplies the + authoritative NVIDIA-patched pxr instead. Having both on ``sys.path`` + causes pxr schema conflicts. Remove the kit-less packages + so ``omni.usd.libs`` is the sole pxr provider in OV environments. + """ + isaacsim_path = extract_isaacsim_path(required=False) + if isaacsim_path is None: + return + if not list(isaacsim_path.glob("extscache/omni.usd.libs-*")): + return + print_info( + "Isaac Sim's omni.usd.libs provides the authoritative pxr runtime. " + "Uninstalling kit-less pxr packages (usd-core, usd-exchange) to avoid conflicts." + ) + run_command(pip_cmd + ["uninstall", "-y", "usd-core", "usd-exchange"], check=False) + + def _maybe_uninstall_prebundled_torch( python_exe: str, pip_cmd: list[str], @@ -1317,6 +1339,13 @@ def append_submodules_once(package_dirs: tuple[str, ...]) -> None: # root pyproject. torch is excluded — it is handled by _ensure_cuda_torch. _install_centralized_dependencies(pip_cmd, requested_optional_submodules) + # In OV/Isaac Sim environments omni.usd.libs ships the authoritative pxr + # runtime (NVIDIA-patched OpenUSD). usd-core is a kit-less fallback + # installed for environments without Isaac Sim. When both are present, + # omni.usd.libs must take precedence so that Isaac Sim's pxr patches and + # schema customisations are active rather than the vanilla usd-core build. + _maybe_uninstall_kitless_pxr(pip_cmd) + # Isaac Sim's bundled newton==1.2.0 satisfies the loose core bound, so force the # pinned Newton git build (the default physics engine) over it. _ensure_newton() From 052b52fed4a504aa7e9f8a1f5e6d29f043eec594 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 21:05:39 +0000 Subject: [PATCH 06/33] Fix pxr conflict with omni.usd.schema.usd_particle_field in OV environments The previous fix uninstalled usd-core when omni.usd.libs was detected, which removed pxr from sys.path entirely. OV tests run via pytest without Kit startup, so omni.usd.libs pxr is never loaded by the extension system, causing ModuleNotFoundError: No module named 'pxr'. Replace _maybe_uninstall_kitless_pxr with _maybe_configure_ov_pxr, which installs a .pth file in site-packages instead. The .pth file prepends omni.usd.libs to sys.path at Python startup, ensuring the NVIDIA-patched pxr (which removes the UsdVol ParticleField alias) is found before usd-core. usd-core stays installed as a fallback for kit-less environments. --- .../isaaclab/isaaclab/cli/commands/install.py | 67 ++++++++++++++----- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/source/isaaclab/isaaclab/cli/commands/install.py b/source/isaaclab/isaaclab/cli/commands/install.py index 24d25879f020..bc99a955f217 100644 --- a/source/isaaclab/isaaclab/cli/commands/install.py +++ b/source/isaaclab/isaaclab/cli/commands/install.py @@ -138,26 +138,58 @@ def _torch_first_on_sys_path_is_prebundle(python_exe: str, *, env: dict[str, str return result.returncode == 1 -def _maybe_uninstall_kitless_pxr(pip_cmd: list[str]) -> None: - """Uninstall kit-less pxr packages when Isaac Sim's omni.usd.libs is present. - - ``usd-core`` (x86_64) and ``usd-exchange`` (aarch64) provide a standalone - pxr runtime for use in kit-less environments. When a full Isaac Sim - installation is present, its ``omni.usd.libs`` extension supplies the - authoritative NVIDIA-patched pxr instead. Having both on ``sys.path`` - causes pxr schema conflicts. Remove the kit-less packages - so ``omni.usd.libs`` is the sole pxr provider in OV environments. +def _maybe_configure_ov_pxr(python_exe: str) -> None: + """Prioritize omni.usd.libs pxr over usd-core in OV/Isaac Sim environments. + + ``usd-core`` 26.x added a backward-compatibility ``TfType`` alias for + ``"ParticleField"`` in ``UsdVol``. When ``omni.usd.schema.usd_particle_field`` + (shipped by the ``ovrtx``/``ovphysx`` extras) is also present, both packages + try to register the same alias and ``pxr.Tf.ErrorException: TfType::AddAlias`` + is raised on import. + + Isaac Sim's ``omni.usd.libs`` extension supplies NVIDIA's patched OpenUSD + build which removes the conflicting alias. A ``.pth`` file installed in + site-packages prepends ``omni.usd.libs`` to ``sys.path`` at Python startup + so the patched pxr is found before usd-core's pxr, eliminating the conflict. + Kit-less environments (no ``omni.usd.libs``) continue using usd-core unaffected. """ isaacsim_path = extract_isaacsim_path(required=False) if isaacsim_path is None: return if not list(isaacsim_path.glob("extscache/omni.usd.libs-*")): return + + result = run_command( + [python_exe, "-c", "import site; print(site.getsitepackages()[0])"], + capture_output=True, + text=True, + check=False, + ) + if result.returncode != 0 or not result.stdout.strip(): + print_warning("Could not determine site-packages path; skipping pxr priority configuration.") + return + + site_packages = Path(result.stdout.strip()) + if not site_packages.is_dir(): + return + + # Single-line .pth executed by site at Python startup. Dynamically resolves + # omni.usd.libs via ISAACLAB_PATH so the path stays valid across version bumps. + # The explicit ISAACLAB_PATH guard avoids an accidental relative-path glob + # when the variable is absent (e.g. when Python is invoked outside isaaclab.sh). + pth_content = ( + "import sys, os, glob as _g; " + "_b = os.environ.get('ISAACLAB_PATH'); " + "_dirs = sorted(d for d in _g.glob(" + "os.path.join(_b, '_isaac_sim', 'extscache', 'omni.usd.libs-*')) " + "if os.path.isdir(d)) if _b else []; " + "_dirs and sys.path.insert(0, _dirs[-1])\n" + ) + pth_file = site_packages / "omni_usd_libs_pxr.pth" + pth_file.write_text(pth_content) print_info( - "Isaac Sim's omni.usd.libs provides the authoritative pxr runtime. " - "Uninstalling kit-less pxr packages (usd-core, usd-exchange) to avoid conflicts." + f"Installed {pth_file.name} in site-packages to prioritize omni.usd.libs pxr over usd-core in OV environments." ) - run_command(pip_cmd + ["uninstall", "-y", "usd-core", "usd-exchange"], check=False) def _maybe_uninstall_prebundled_torch( @@ -1339,12 +1371,11 @@ def append_submodules_once(package_dirs: tuple[str, ...]) -> None: # root pyproject. torch is excluded — it is handled by _ensure_cuda_torch. _install_centralized_dependencies(pip_cmd, requested_optional_submodules) - # In OV/Isaac Sim environments omni.usd.libs ships the authoritative pxr - # runtime (NVIDIA-patched OpenUSD). usd-core is a kit-less fallback - # installed for environments without Isaac Sim. When both are present, - # omni.usd.libs must take precedence so that Isaac Sim's pxr patches and - # schema customisations are active rather than the vanilla usd-core build. - _maybe_uninstall_kitless_pxr(pip_cmd) + # In OV/Isaac Sim environments omni.usd.libs ships NVIDIA's patched pxr + # which removes schema aliases that conflict with omni.usd.schema packages + # bundled in ovrtx/ovphysx extras. Install a .pth file so the patched pxr + # is found before usd-core on sys.path. + _maybe_configure_ov_pxr(python_exe) # Isaac Sim's bundled newton==1.2.0 satisfies the loose core bound, so force the # pinned Newton git build (the default physics engine) over it. From 1e280e39ee0fa20d312c659eeb3e52d117b37e92 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 22:58:52 +0000 Subject: [PATCH 07/33] revert --- isaaclab.bat | 13 ++++ isaaclab.sh | 13 ++++ .../isaaclab/isaaclab/cli/commands/install.py | 64 +------------------ 3 files changed, 28 insertions(+), 62 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 131c75e16e01..9e05418af996 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -41,6 +41,19 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( ) ) +rem If omni.usd.libs is present, prepend the latest version to PYTHONPATH so its +rem patched pxr is found before usd-core's pxr, resolving TfType::AddAlias conflicts. +set "_ov_usd_libs_dir=" +if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( + "%python_exe%" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')" > "%TEMP%\ov_usd_libs.tmp" 2>nul + set /p _ov_usd_libs_dir=<"%TEMP%\ov_usd_libs.tmp" + del "%TEMP%\ov_usd_libs.tmp" >nul 2>&1 +) +if defined _ov_usd_libs_dir ( + set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" +) +set "_ov_usd_libs_dir=" + rem Execute CLI. "%python_exe%" -c "from isaaclab.cli import cli; cli()" %* diff --git a/isaaclab.sh b/isaaclab.sh index 941dba9e462e..c9b08bf37074 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -61,5 +61,18 @@ if [ -d "$ISAACLAB_PATH/_isaac_sim" ]; then fi fi +# If omni.usd.libs is present, prepend it to PYTHONPATH so its patched pxr is +# found before usd-core's pxr. This resolves TfType::AddAlias conflicts when +# omni.usd.schema packages (ovrtx/ovphysx) are also installed. Done here rather +# than via a .pth file so that LD_LIBRARY_PATH (set above by setup_*_env.sh) +# is already in effect, keeping kit-less environments unaffected. +if [ -d "$ISAACLAB_PATH/_isaac_sim/extscache" ]; then + _ov_usd_libs_dir=$(find "$ISAACLAB_PATH/_isaac_sim/extscache" -maxdepth 1 -name "omni.usd.libs-*" -type d 2>/dev/null | sort | tail -1) + if [ -n "$_ov_usd_libs_dir" ]; then + export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" + fi + unset _ov_usd_libs_dir +fi + # Execute CLI. exec "$python_exe" -c "from isaaclab.cli import cli; cli()" "$@" diff --git a/source/isaaclab/isaaclab/cli/commands/install.py b/source/isaaclab/isaaclab/cli/commands/install.py index bc99a955f217..97a7fc83da92 100644 --- a/source/isaaclab/isaaclab/cli/commands/install.py +++ b/source/isaaclab/isaaclab/cli/commands/install.py @@ -53,8 +53,8 @@ def _install_system_deps() -> None: run_command(["sudo"] + cmd if os.geteuid() != 0 else cmd) # On ARM Linux (e.g. DGX Spark), Python dev headers (Python.h) are needed - # to build Python packages with native extensions. They are typically - # pre-installed in x86 Docker images but missing on bare-metal ARM systems. + # to build C extensions such as quadprog. They are typically pre-installed + # in x86 Docker images but missing on bare-metal ARM systems. if is_arm(): python_dev_pkg = f"python{sys.version_info.major}.{sys.version_info.minor}-dev" try: @@ -138,60 +138,6 @@ def _torch_first_on_sys_path_is_prebundle(python_exe: str, *, env: dict[str, str return result.returncode == 1 -def _maybe_configure_ov_pxr(python_exe: str) -> None: - """Prioritize omni.usd.libs pxr over usd-core in OV/Isaac Sim environments. - - ``usd-core`` 26.x added a backward-compatibility ``TfType`` alias for - ``"ParticleField"`` in ``UsdVol``. When ``omni.usd.schema.usd_particle_field`` - (shipped by the ``ovrtx``/``ovphysx`` extras) is also present, both packages - try to register the same alias and ``pxr.Tf.ErrorException: TfType::AddAlias`` - is raised on import. - - Isaac Sim's ``omni.usd.libs`` extension supplies NVIDIA's patched OpenUSD - build which removes the conflicting alias. A ``.pth`` file installed in - site-packages prepends ``omni.usd.libs`` to ``sys.path`` at Python startup - so the patched pxr is found before usd-core's pxr, eliminating the conflict. - Kit-less environments (no ``omni.usd.libs``) continue using usd-core unaffected. - """ - isaacsim_path = extract_isaacsim_path(required=False) - if isaacsim_path is None: - return - if not list(isaacsim_path.glob("extscache/omni.usd.libs-*")): - return - - result = run_command( - [python_exe, "-c", "import site; print(site.getsitepackages()[0])"], - capture_output=True, - text=True, - check=False, - ) - if result.returncode != 0 or not result.stdout.strip(): - print_warning("Could not determine site-packages path; skipping pxr priority configuration.") - return - - site_packages = Path(result.stdout.strip()) - if not site_packages.is_dir(): - return - - # Single-line .pth executed by site at Python startup. Dynamically resolves - # omni.usd.libs via ISAACLAB_PATH so the path stays valid across version bumps. - # The explicit ISAACLAB_PATH guard avoids an accidental relative-path glob - # when the variable is absent (e.g. when Python is invoked outside isaaclab.sh). - pth_content = ( - "import sys, os, glob as _g; " - "_b = os.environ.get('ISAACLAB_PATH'); " - "_dirs = sorted(d for d in _g.glob(" - "os.path.join(_b, '_isaac_sim', 'extscache', 'omni.usd.libs-*')) " - "if os.path.isdir(d)) if _b else []; " - "_dirs and sys.path.insert(0, _dirs[-1])\n" - ) - pth_file = site_packages / "omni_usd_libs_pxr.pth" - pth_file.write_text(pth_content) - print_info( - f"Installed {pth_file.name} in site-packages to prioritize omni.usd.libs pxr over usd-core in OV environments." - ) - - def _maybe_uninstall_prebundled_torch( python_exe: str, pip_cmd: list[str], @@ -1371,12 +1317,6 @@ def append_submodules_once(package_dirs: tuple[str, ...]) -> None: # root pyproject. torch is excluded — it is handled by _ensure_cuda_torch. _install_centralized_dependencies(pip_cmd, requested_optional_submodules) - # In OV/Isaac Sim environments omni.usd.libs ships NVIDIA's patched pxr - # which removes schema aliases that conflict with omni.usd.schema packages - # bundled in ovrtx/ovphysx extras. Install a .pth file so the patched pxr - # is found before usd-core on sys.path. - _maybe_configure_ov_pxr(python_exe) - # Isaac Sim's bundled newton==1.2.0 satisfies the loose core bound, so force the # pinned Newton git build (the default physics engine) over it. _ensure_newton() From c8e15950ba85d82ebcc74e41699bfb5d6da45487 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 14 Jul 2026 23:07:01 +0000 Subject: [PATCH 08/33] fix --- isaaclab.bat | 6 ++++-- isaaclab.sh | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 9e05418af996..7bfc0323ec33 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -41,8 +41,9 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( ) ) -rem If omni.usd.libs is present, prepend the latest version to PYTHONPATH so its -rem patched pxr is found before usd-core's pxr, resolving TfType::AddAlias conflicts. +rem If omni.usd.libs is present, prepend it to PYTHONPATH and its bin\ to PATH +rem so its patched pxr is found before usd-core's pxr and the native USD shared +rem libraries are resolvable, resolving TfType::AddAlias conflicts. set "_ov_usd_libs_dir=" if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( "%python_exe%" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')" > "%TEMP%\ov_usd_libs.tmp" 2>nul @@ -51,6 +52,7 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( ) if defined _ov_usd_libs_dir ( set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" + set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" ) set "_ov_usd_libs_dir=" diff --git a/isaaclab.sh b/isaaclab.sh index c9b08bf37074..38c9f93fed69 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -61,15 +61,15 @@ if [ -d "$ISAACLAB_PATH/_isaac_sim" ]; then fi fi -# If omni.usd.libs is present, prepend it to PYTHONPATH so its patched pxr is -# found before usd-core's pxr. This resolves TfType::AddAlias conflicts when -# omni.usd.schema packages (ovrtx/ovphysx) are also installed. Done here rather -# than via a .pth file so that LD_LIBRARY_PATH (set above by setup_*_env.sh) -# is already in effect, keeping kit-less environments unaffected. +# If omni.usd.libs is present, prepend it to PYTHONPATH and its bin/ to +# LD_LIBRARY_PATH so its patched pxr is found before usd-core's pxr and the +# native USD shared libraries are resolvable. This resolves TfType::AddAlias +# conflicts when omni.usd.schema packages (ovrtx/ovphysx) are also installed. if [ -d "$ISAACLAB_PATH/_isaac_sim/extscache" ]; then _ov_usd_libs_dir=$(find "$ISAACLAB_PATH/_isaac_sim/extscache" -maxdepth 1 -name "omni.usd.libs-*" -type d 2>/dev/null | sort | tail -1) if [ -n "$_ov_usd_libs_dir" ]; then export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" + export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" fi unset _ov_usd_libs_dir fi From 3c0deaac632b51ec23bf2cbd1ce1d26ed74f049d Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 15 Jul 2026 02:10:55 +0000 Subject: [PATCH 09/33] update --- isaaclab.bat | 10 ++++++++++ isaaclab.sh | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/isaaclab.bat b/isaaclab.bat index 7bfc0323ec33..10bfa2350a79 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -44,6 +44,11 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( rem If omni.usd.libs is present, prepend it to PYTHONPATH and its bin\ to PATH rem so its patched pxr is found before usd-core's pxr and the native USD shared rem libraries are resolvable, resolving TfType::AddAlias conflicts. +rem +rem omni.usd.libs\pxr\ is a namespace package (no __init__.py), but Python +rem prefers a regular package (with __init__.py) over a namespace package +rem regardless of sys.path order. Write a minimal __init__.py to promote it +rem to a regular package so the PYTHONPATH prepend actually takes effect. set "_ov_usd_libs_dir=" if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( "%python_exe%" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')" > "%TEMP%\ov_usd_libs.tmp" 2>nul @@ -51,6 +56,11 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( del "%TEMP%\ov_usd_libs.tmp" >nul 2>&1 ) if defined _ov_usd_libs_dir ( + if exist "!_ov_usd_libs_dir!\pxr\" ( + if not exist "!_ov_usd_libs_dir!\pxr\__init__.py" ( + type nul > "!_ov_usd_libs_dir!\pxr\__init__.py" 2>nul + ) + ) set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" ) diff --git a/isaaclab.sh b/isaaclab.sh index 38c9f93fed69..bd2bd905daec 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -65,9 +65,19 @@ fi # LD_LIBRARY_PATH so its patched pxr is found before usd-core's pxr and the # native USD shared libraries are resolvable. This resolves TfType::AddAlias # conflicts when omni.usd.schema packages (ovrtx/ovphysx) are also installed. +# +# omni.usd.libs/pxr/ is a namespace package (no __init__.py), but Python's +# import system always prefers a regular package (with __init__.py) over a +# namespace package, regardless of sys.path order. Since usd-core installs a +# regular pxr package, prepending omni.usd.libs to PYTHONPATH alone does nothing. +# We write a minimal __init__.py into omni.usd.libs/pxr/ to promote it to a +# regular package, making the sys.path order actually take effect. if [ -d "$ISAACLAB_PATH/_isaac_sim/extscache" ]; then _ov_usd_libs_dir=$(find "$ISAACLAB_PATH/_isaac_sim/extscache" -maxdepth 1 -name "omni.usd.libs-*" -type d 2>/dev/null | sort | tail -1) if [ -n "$_ov_usd_libs_dir" ]; then + if [ -d "$_ov_usd_libs_dir/pxr" ] && [ ! -f "$_ov_usd_libs_dir/pxr/__init__.py" ]; then + printf '' > "$_ov_usd_libs_dir/pxr/__init__.py" 2>/dev/null || true + fi export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" fi From bb65e2e49f4c5f01d247a0c82d8ca908869aa166 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 15 Jul 2026 18:37:59 -0400 Subject: [PATCH 10/33] cleanup --- source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst | 2 +- source/isaaclab/isaaclab/cli/commands/install.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst b/source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst index a6c3ee0fe9dc..b2f022bb5fc7 100644 --- a/source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst +++ b/source/isaaclab/changelog.d/mataylor-golden-sim-usd.minor.rst @@ -2,4 +2,4 @@ Changed ^^^^^^^ * Bumped ``usd-core`` dependency from ``>=25.11,<26.0`` to ``>=26.05,<27.0`` on x86_64 to resolve - a crash in ``libusd_ms`` triggered by USD physics loading (``LoadUsdPhysicsFromRange``). + a crash in ``libusd_ms`` triggered by USD physics loading (``LoadUsdPhysicsFromRange``) for kitless runs. diff --git a/source/isaaclab/isaaclab/cli/commands/install.py b/source/isaaclab/isaaclab/cli/commands/install.py index 97a7fc83da92..6ba086a9a35d 100644 --- a/source/isaaclab/isaaclab/cli/commands/install.py +++ b/source/isaaclab/isaaclab/cli/commands/install.py @@ -53,8 +53,8 @@ def _install_system_deps() -> None: run_command(["sudo"] + cmd if os.geteuid() != 0 else cmd) # On ARM Linux (e.g. DGX Spark), Python dev headers (Python.h) are needed - # to build C extensions such as quadprog. They are typically pre-installed - # in x86 Docker images but missing on bare-metal ARM systems. + # to build Python packages with native extensions. They are typically + # pre-installed in x86 Docker images but missing on bare-metal ARM systems. if is_arm(): python_dev_pkg = f"python{sys.version_info.major}.{sys.version_info.minor}-dev" try: From c7757b6b33595681648a9567112eb0505a668fbc Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 00:25:49 +0000 Subject: [PATCH 11/33] use small python script --- isaaclab.bat | 13 +++---------- isaaclab.sh | 15 +++++---------- tools/setup_usd_libs.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 tools/setup_usd_libs.py diff --git a/isaaclab.bat b/isaaclab.bat index 10bfa2350a79..13bb390a3d4e 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -50,17 +50,10 @@ rem prefers a regular package (with __init__.py) over a namespace package rem regardless of sys.path order. Write a minimal __init__.py to promote it rem to a regular package so the PYTHONPATH prepend actually takes effect. set "_ov_usd_libs_dir=" -if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( - "%python_exe%" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')" > "%TEMP%\ov_usd_libs.tmp" 2>nul - set /p _ov_usd_libs_dir=<"%TEMP%\ov_usd_libs.tmp" - del "%TEMP%\ov_usd_libs.tmp" >nul 2>&1 -) +"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" > "%TEMP%\ov_usd_libs.tmp" 2>nul +set /p _ov_usd_libs_dir=<"%TEMP%\ov_usd_libs.tmp" +del "%TEMP%\ov_usd_libs.tmp" >nul 2>&1 if defined _ov_usd_libs_dir ( - if exist "!_ov_usd_libs_dir!\pxr\" ( - if not exist "!_ov_usd_libs_dir!\pxr\__init__.py" ( - type nul > "!_ov_usd_libs_dir!\pxr\__init__.py" 2>nul - ) - ) set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" ) diff --git a/isaaclab.sh b/isaaclab.sh index bd2bd905daec..0017b67fbbdb 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -72,17 +72,12 @@ fi # regular pxr package, prepending omni.usd.libs to PYTHONPATH alone does nothing. # We write a minimal __init__.py into omni.usd.libs/pxr/ to promote it to a # regular package, making the sys.path order actually take effect. -if [ -d "$ISAACLAB_PATH/_isaac_sim/extscache" ]; then - _ov_usd_libs_dir=$(find "$ISAACLAB_PATH/_isaac_sim/extscache" -maxdepth 1 -name "omni.usd.libs-*" -type d 2>/dev/null | sort | tail -1) - if [ -n "$_ov_usd_libs_dir" ]; then - if [ -d "$_ov_usd_libs_dir/pxr" ] && [ ! -f "$_ov_usd_libs_dir/pxr/__init__.py" ]; then - printf '' > "$_ov_usd_libs_dir/pxr/__init__.py" 2>/dev/null || true - fi - export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" - export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" - fi - unset _ov_usd_libs_dir +_ov_usd_libs_dir=$("$python_exe" "$ISAACLAB_PATH/tools/setup_usd_libs.py" 2>/dev/null) +if [ -n "$_ov_usd_libs_dir" ]; then + export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" + export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" fi +unset _ov_usd_libs_dir # Execute CLI. exec "$python_exe" -c "from isaaclab.cli import cli; cli()" "$@" diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py new file mode 100644 index 000000000000..175d1e6f1021 --- /dev/null +++ b/tools/setup_usd_libs.py @@ -0,0 +1,29 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Locate the omni.usd.libs extension and promote its pxr package to a regular package. + +Prints the resolved directory path to stdout (empty string if not found). +Called by isaaclab.sh / isaaclab.bat before launching the CLI so that the +shell can prepend the path to PYTHONPATH / LD_LIBRARY_PATH / PATH. +""" + +import glob +import os + +extscache = os.path.join(os.environ.get("ISAACLAB_PATH", ""), "_isaac_sim", "extscache") +candidates = sorted(glob.glob(os.path.join(extscache, "omni.usd.libs-*"))) +if not candidates: + print("", end="") +else: + usd_libs_dir = candidates[-1] + pxr_dir = os.path.join(usd_libs_dir, "pxr") + init_py = os.path.join(pxr_dir, "__init__.py") + if os.path.isdir(pxr_dir) and not os.path.isfile(init_py): + try: + open(init_py, "w").close() + except OSError: + pass + print(usd_libs_dir, end="") From e8500851999bb9d6b7d2d003b318c795f019e2f3 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 00:30:23 +0000 Subject: [PATCH 12/33] cleanup --- isaaclab.bat | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 13bb390a3d4e..6d34989eec93 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -49,15 +49,10 @@ rem omni.usd.libs\pxr\ is a namespace package (no __init__.py), but Python rem prefers a regular package (with __init__.py) over a namespace package rem regardless of sys.path order. Write a minimal __init__.py to promote it rem to a regular package so the PYTHONPATH prepend actually takes effect. -set "_ov_usd_libs_dir=" -"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" > "%TEMP%\ov_usd_libs.tmp" 2>nul -set /p _ov_usd_libs_dir=<"%TEMP%\ov_usd_libs.tmp" -del "%TEMP%\ov_usd_libs.tmp" >nul 2>&1 -if defined _ov_usd_libs_dir ( - set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" - set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" +for /f "delims=" %%d in ('"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" 2^>nul') do ( + set "PYTHONPATH=%%d;!PYTHONPATH!" + set "PATH=%%d\bin;!PATH!" ) -set "_ov_usd_libs_dir=" rem Execute CLI. "%python_exe%" -c "from isaaclab.cli import cli; cli()" %* From b755878f17de7c175ba1c7e04ab6f54d9c621b09 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 00:32:40 +0000 Subject: [PATCH 13/33] fix format --- tools/setup_usd_libs.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py index 175d1e6f1021..6b1375e5c7cc 100644 --- a/tools/setup_usd_libs.py +++ b/tools/setup_usd_libs.py @@ -10,6 +10,7 @@ shell can prepend the path to PYTHONPATH / LD_LIBRARY_PATH / PATH. """ +import contextlib import glob import os @@ -22,8 +23,6 @@ pxr_dir = os.path.join(usd_libs_dir, "pxr") init_py = os.path.join(pxr_dir, "__init__.py") if os.path.isdir(pxr_dir) and not os.path.isfile(init_py): - try: + with contextlib.suppress(OSError): open(init_py, "w").close() - except OSError: - pass print(usd_libs_dir, end="") From 328fb7f1e9aa6f3c5fcbaab635340a84de5ab1df Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 00:35:09 +0000 Subject: [PATCH 14/33] fix --- tools/setup_usd_libs.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py index 6b1375e5c7cc..2dd233e79126 100644 --- a/tools/setup_usd_libs.py +++ b/tools/setup_usd_libs.py @@ -10,7 +10,6 @@ shell can prepend the path to PYTHONPATH / LD_LIBRARY_PATH / PATH. """ -import contextlib import glob import os @@ -22,7 +21,8 @@ usd_libs_dir = candidates[-1] pxr_dir = os.path.join(usd_libs_dir, "pxr") init_py = os.path.join(pxr_dir, "__init__.py") - if os.path.isdir(pxr_dir) and not os.path.isfile(init_py): - with contextlib.suppress(OSError): - open(init_py, "w").close() + try: + open(init_py, "w").close() + except OSError as exc: + raise RuntimeError(f"Failed to promote {pxr_dir!r} to a regular pxr package") from exc print(usd_libs_dir, end="") From 29a0fb5d8085c4143a5fdd8df76fc522a25aed41 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 00:44:07 +0000 Subject: [PATCH 15/33] fix --- isaaclab.bat | 2 +- tools/setup_usd_libs.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 6d34989eec93..40f9f84c45f8 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -49,7 +49,7 @@ rem omni.usd.libs\pxr\ is a namespace package (no __init__.py), but Python rem prefers a regular package (with __init__.py) over a namespace package rem regardless of sys.path order. Write a minimal __init__.py to promote it rem to a regular package so the PYTHONPATH prepend actually takes effect. -for /f "delims=" %%d in ('"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" 2^>nul') do ( +for /f "delims=" %%d in ('"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py"') do ( set "PYTHONPATH=%%d;!PYTHONPATH!" set "PATH=%%d\bin;!PATH!" ) diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py index 2dd233e79126..661caf2b4b21 100644 --- a/tools/setup_usd_libs.py +++ b/tools/setup_usd_libs.py @@ -21,8 +21,9 @@ usd_libs_dir = candidates[-1] pxr_dir = os.path.join(usd_libs_dir, "pxr") init_py = os.path.join(pxr_dir, "__init__.py") - try: - open(init_py, "w").close() - except OSError as exc: - raise RuntimeError(f"Failed to promote {pxr_dir!r} to a regular pxr package") from exc + if os.path.isdir(pxr_dir) and not os.path.isfile(init_py): + try: + open(init_py, "w").close() + except OSError as exc: + raise RuntimeError(f"Failed to promote {pxr_dir!r} to a regular pxr package") from exc print(usd_libs_dir, end="") From 2c3a0527d0ab2ac0b0855fa7501f5570cc04e2ab Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 00:49:20 +0000 Subject: [PATCH 16/33] fix --- isaaclab.bat | 26 ++++++++++++++++++++------ isaaclab.sh | 13 ++++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 40f9f84c45f8..2722286232c0 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -43,17 +43,31 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( rem If omni.usd.libs is present, prepend it to PYTHONPATH and its bin\ to PATH rem so its patched pxr is found before usd-core's pxr and the native USD shared -rem libraries are resolvable, resolving TfType::AddAlias conflicts. +rem libraries are resolvable. This resolves TfType::AddAlias conflicts when +rem omni.usd.schema packages (ovrtx/ovphysx) are also installed. rem rem omni.usd.libs\pxr\ is a namespace package (no __init__.py), but Python rem prefers a regular package (with __init__.py) over a namespace package -rem regardless of sys.path order. Write a minimal __init__.py to promote it -rem to a regular package so the PYTHONPATH prepend actually takes effect. -for /f "delims=" %%d in ('"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py"') do ( - set "PYTHONPATH=%%d;!PYTHONPATH!" - set "PATH=%%d\bin;!PATH!" +rem regardless of sys.path order. Since usd-core installs a regular pxr +rem package, prepending omni.usd.libs to PYTHONPATH alone does nothing. +rem We write a minimal __init__.py to promote it to a regular package so the +rem PYTHONPATH prepend actually takes effect. +if exist "%ISAACLAB_PATH%\omni.usd.libs\" ( + "%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" > "%TEMP%\_isaaclab_usd_libs.tmp" + if errorlevel 1 ( + echo [WARNING] Failed to configure omni.usd.libs USD path; continuing without it. 1>&2 + ) else ( + set /p _usd_libs_dir=<"%TEMP%\_isaaclab_usd_libs.tmp" + if defined _usd_libs_dir ( + set "PYTHONPATH=!_usd_libs_dir!;!PYTHONPATH!" + set "PATH=!_usd_libs_dir!\bin;!PATH!" + ) + set "_usd_libs_dir=" + ) + del "%TEMP%\_isaaclab_usd_libs.tmp" 2>nul ) + rem Execute CLI. "%python_exe%" -c "from isaaclab.cli import cli; cli()" %* diff --git a/isaaclab.sh b/isaaclab.sh index 0017b67fbbdb..4f58f8a860d9 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -72,12 +72,15 @@ fi # regular pxr package, prepending omni.usd.libs to PYTHONPATH alone does nothing. # We write a minimal __init__.py into omni.usd.libs/pxr/ to promote it to a # regular package, making the sys.path order actually take effect. -_ov_usd_libs_dir=$("$python_exe" "$ISAACLAB_PATH/tools/setup_usd_libs.py" 2>/dev/null) -if [ -n "$_ov_usd_libs_dir" ]; then - export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" - export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" +if [ -d "$ISAACLAB_PATH/omni.usd.libs" ]; then + if ! usd_libs_dir="$("$python_exe" "$ISAACLAB_PATH/tools/setup_usd_libs.py")"; then + echo "[WARNING] Failed to configure omni.usd.libs USD path; continuing without it." >&2 + elif [ -n "$usd_libs_dir" ]; then + export PYTHONPATH="$usd_libs_dir:$PYTHONPATH" + export LD_LIBRARY_PATH="$usd_libs_dir/bin:$LD_LIBRARY_PATH" + fi fi -unset _ov_usd_libs_dir + # Execute CLI. exec "$python_exe" -c "from isaaclab.cli import cli; cli()" "$@" From 8d6a5426ddb05bb38e684f38b184f4254c2a00eb Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 00:54:09 +0000 Subject: [PATCH 17/33] fix --- isaaclab.bat | 22 ++++++++++------------ isaaclab.sh | 12 +++++------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 2722286232c0..0243fe14f5d6 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -52,20 +52,18 @@ rem regardless of sys.path order. Since usd-core installs a regular pxr rem package, prepending omni.usd.libs to PYTHONPATH alone does nothing. rem We write a minimal __init__.py to promote it to a regular package so the rem PYTHONPATH prepend actually takes effect. -if exist "%ISAACLAB_PATH%\omni.usd.libs\" ( - "%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" > "%TEMP%\_isaaclab_usd_libs.tmp" - if errorlevel 1 ( - echo [WARNING] Failed to configure omni.usd.libs USD path; continuing without it. 1>&2 - ) else ( - set /p _usd_libs_dir=<"%TEMP%\_isaaclab_usd_libs.tmp" - if defined _usd_libs_dir ( - set "PYTHONPATH=!_usd_libs_dir!;!PYTHONPATH!" - set "PATH=!_usd_libs_dir!\bin;!PATH!" - ) - set "_usd_libs_dir=" +"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" > "%TEMP%\_isaaclab_usd_libs.tmp" +if errorlevel 1 ( + echo [WARNING] Failed to configure omni.usd.libs USD path; continuing without it. 1>&2 +) else ( + set /p _usd_libs_dir=<"%TEMP%\_isaaclab_usd_libs.tmp" + if defined _usd_libs_dir ( + set "PYTHONPATH=!_usd_libs_dir!;!PYTHONPATH!" + set "PATH=!_usd_libs_dir!\bin;!PATH!" ) - del "%TEMP%\_isaaclab_usd_libs.tmp" 2>nul + set "_usd_libs_dir=" ) +del "%TEMP%\_isaaclab_usd_libs.tmp" 2>nul rem Execute CLI. diff --git a/isaaclab.sh b/isaaclab.sh index 4f58f8a860d9..e888666df224 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -72,13 +72,11 @@ fi # regular pxr package, prepending omni.usd.libs to PYTHONPATH alone does nothing. # We write a minimal __init__.py into omni.usd.libs/pxr/ to promote it to a # regular package, making the sys.path order actually take effect. -if [ -d "$ISAACLAB_PATH/omni.usd.libs" ]; then - if ! usd_libs_dir="$("$python_exe" "$ISAACLAB_PATH/tools/setup_usd_libs.py")"; then - echo "[WARNING] Failed to configure omni.usd.libs USD path; continuing without it." >&2 - elif [ -n "$usd_libs_dir" ]; then - export PYTHONPATH="$usd_libs_dir:$PYTHONPATH" - export LD_LIBRARY_PATH="$usd_libs_dir/bin:$LD_LIBRARY_PATH" - fi +if ! usd_libs_dir="$("$python_exe" "$ISAACLAB_PATH/tools/setup_usd_libs.py")"; then + echo "[WARNING] Failed to configure omni.usd.libs USD path; continuing without it." >&2 +elif [ -n "$usd_libs_dir" ]; then + export PYTHONPATH="$usd_libs_dir:$PYTHONPATH" + export LD_LIBRARY_PATH="$usd_libs_dir/bin:$LD_LIBRARY_PATH" fi From 812c51bff03bb3903bd31e84d660ffb54d264ff1 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 01:03:52 +0000 Subject: [PATCH 18/33] fix --- isaaclab.bat | 34 +++++++++++++++++----------------- isaaclab.sh | 16 ++++++++++------ tools/setup_usd_libs.py | 29 ----------------------------- 3 files changed, 27 insertions(+), 52 deletions(-) delete mode 100644 tools/setup_usd_libs.py diff --git a/isaaclab.bat b/isaaclab.bat index 0243fe14f5d6..10bfa2350a79 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -43,28 +43,28 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( rem If omni.usd.libs is present, prepend it to PYTHONPATH and its bin\ to PATH rem so its patched pxr is found before usd-core's pxr and the native USD shared -rem libraries are resolvable. This resolves TfType::AddAlias conflicts when -rem omni.usd.schema packages (ovrtx/ovphysx) are also installed. +rem libraries are resolvable, resolving TfType::AddAlias conflicts. rem rem omni.usd.libs\pxr\ is a namespace package (no __init__.py), but Python rem prefers a regular package (with __init__.py) over a namespace package -rem regardless of sys.path order. Since usd-core installs a regular pxr -rem package, prepending omni.usd.libs to PYTHONPATH alone does nothing. -rem We write a minimal __init__.py to promote it to a regular package so the -rem PYTHONPATH prepend actually takes effect. -"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py" > "%TEMP%\_isaaclab_usd_libs.tmp" -if errorlevel 1 ( - echo [WARNING] Failed to configure omni.usd.libs USD path; continuing without it. 1>&2 -) else ( - set /p _usd_libs_dir=<"%TEMP%\_isaaclab_usd_libs.tmp" - if defined _usd_libs_dir ( - set "PYTHONPATH=!_usd_libs_dir!;!PYTHONPATH!" - set "PATH=!_usd_libs_dir!\bin;!PATH!" +rem regardless of sys.path order. Write a minimal __init__.py to promote it +rem to a regular package so the PYTHONPATH prepend actually takes effect. +set "_ov_usd_libs_dir=" +if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( + "%python_exe%" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')" > "%TEMP%\ov_usd_libs.tmp" 2>nul + set /p _ov_usd_libs_dir=<"%TEMP%\ov_usd_libs.tmp" + del "%TEMP%\ov_usd_libs.tmp" >nul 2>&1 +) +if defined _ov_usd_libs_dir ( + if exist "!_ov_usd_libs_dir!\pxr\" ( + if not exist "!_ov_usd_libs_dir!\pxr\__init__.py" ( + type nul > "!_ov_usd_libs_dir!\pxr\__init__.py" 2>nul + ) ) - set "_usd_libs_dir=" + set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" + set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" ) -del "%TEMP%\_isaaclab_usd_libs.tmp" 2>nul - +set "_ov_usd_libs_dir=" rem Execute CLI. "%python_exe%" -c "from isaaclab.cli import cli; cli()" %* diff --git a/isaaclab.sh b/isaaclab.sh index e888666df224..34902c8e177b 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -72,13 +72,17 @@ fi # regular pxr package, prepending omni.usd.libs to PYTHONPATH alone does nothing. # We write a minimal __init__.py into omni.usd.libs/pxr/ to promote it to a # regular package, making the sys.path order actually take effect. -if ! usd_libs_dir="$("$python_exe" "$ISAACLAB_PATH/tools/setup_usd_libs.py")"; then - echo "[WARNING] Failed to configure omni.usd.libs USD path; continuing without it." >&2 -elif [ -n "$usd_libs_dir" ]; then - export PYTHONPATH="$usd_libs_dir:$PYTHONPATH" - export LD_LIBRARY_PATH="$usd_libs_dir/bin:$LD_LIBRARY_PATH" +if [ -d "$ISAACLAB_PATH/_isaac_sim/extscache" ]; then + _ov_usd_libs_dir=$("$python_exe" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')") + if [ -n "$_ov_usd_libs_dir" ]; then + if [ -d "$_ov_usd_libs_dir/pxr" ] && [ ! -f "$_ov_usd_libs_dir/pxr/__init__.py" ]; then + printf '' > "$_ov_usd_libs_dir/pxr/__init__.py" 2>/dev/null || true + fi + export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" + export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" + fi + unset _ov_usd_libs_dir fi - # Execute CLI. exec "$python_exe" -c "from isaaclab.cli import cli; cli()" "$@" diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py deleted file mode 100644 index 661caf2b4b21..000000000000 --- a/tools/setup_usd_libs.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -"""Locate the omni.usd.libs extension and promote its pxr package to a regular package. - -Prints the resolved directory path to stdout (empty string if not found). -Called by isaaclab.sh / isaaclab.bat before launching the CLI so that the -shell can prepend the path to PYTHONPATH / LD_LIBRARY_PATH / PATH. -""" - -import glob -import os - -extscache = os.path.join(os.environ.get("ISAACLAB_PATH", ""), "_isaac_sim", "extscache") -candidates = sorted(glob.glob(os.path.join(extscache, "omni.usd.libs-*"))) -if not candidates: - print("", end="") -else: - usd_libs_dir = candidates[-1] - pxr_dir = os.path.join(usd_libs_dir, "pxr") - init_py = os.path.join(pxr_dir, "__init__.py") - if os.path.isdir(pxr_dir) and not os.path.isfile(init_py): - try: - open(init_py, "w").close() - except OSError as exc: - raise RuntimeError(f"Failed to promote {pxr_dir!r} to a regular pxr package") from exc - print(usd_libs_dir, end="") From 9975b674693c97128494bec7c03628c61218d8a0 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 02:43:45 +0000 Subject: [PATCH 19/33] Surface read-only pxr promotion failure with a warning --- isaaclab.bat | 12 +++++++++--- isaaclab.sh | 11 ++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/isaaclab.bat b/isaaclab.bat index 10bfa2350a79..6d89cd429466 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -58,11 +58,17 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( if defined _ov_usd_libs_dir ( if exist "!_ov_usd_libs_dir!\pxr\" ( if not exist "!_ov_usd_libs_dir!\pxr\__init__.py" ( - type nul > "!_ov_usd_libs_dir!\pxr\__init__.py" 2>nul + type nul > "!_ov_usd_libs_dir!\pxr\__init__.py" + if errorlevel 1 ( + echo [WARNING] Cannot promote omni.usd.libs\pxr to a regular package (read-only cache^); skipping USD path setup. 1>&2 + set "_ov_usd_libs_dir=" + ) ) ) - set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" - set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" + if defined _ov_usd_libs_dir ( + set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" + set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" + ) ) set "_ov_usd_libs_dir=" diff --git a/isaaclab.sh b/isaaclab.sh index 34902c8e177b..3f45f884c73a 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -76,10 +76,15 @@ if [ -d "$ISAACLAB_PATH/_isaac_sim/extscache" ]; then _ov_usd_libs_dir=$("$python_exe" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')") if [ -n "$_ov_usd_libs_dir" ]; then if [ -d "$_ov_usd_libs_dir/pxr" ] && [ ! -f "$_ov_usd_libs_dir/pxr/__init__.py" ]; then - printf '' > "$_ov_usd_libs_dir/pxr/__init__.py" 2>/dev/null || true + if ! printf '' > "$_ov_usd_libs_dir/pxr/__init__.py" 2>/dev/null; then + echo "[WARNING] Cannot promote omni.usd.libs/pxr to a regular package (read-only cache); skipping USD path setup." >&2 + unset _ov_usd_libs_dir + fi + fi + if [ -n "$_ov_usd_libs_dir" ]; then + export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" + export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" fi - export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" - export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" fi unset _ov_usd_libs_dir fi From 8d97c56c02414b70cc7e8548f36231603233b35b Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 02:58:03 +0000 Subject: [PATCH 20/33] fix --- isaaclab.bat | 31 +++---------------------------- isaaclab.sh | 35 +++++++++-------------------------- tools/setup_usd_libs.py | 27 +++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 54 deletions(-) create mode 100644 tools/setup_usd_libs.py diff --git a/isaaclab.bat b/isaaclab.bat index 6d89cd429466..d754cfd95abf 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -41,34 +41,9 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( ) ) -rem If omni.usd.libs is present, prepend it to PYTHONPATH and its bin\ to PATH -rem so its patched pxr is found before usd-core's pxr and the native USD shared -rem libraries are resolvable, resolving TfType::AddAlias conflicts. -rem -rem omni.usd.libs\pxr\ is a namespace package (no __init__.py), but Python -rem prefers a regular package (with __init__.py) over a namespace package -rem regardless of sys.path order. Write a minimal __init__.py to promote it -rem to a regular package so the PYTHONPATH prepend actually takes effect. -set "_ov_usd_libs_dir=" -if exist "%ISAACLAB_PATH%\_isaac_sim\extscache\" ( - "%python_exe%" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')" > "%TEMP%\ov_usd_libs.tmp" 2>nul - set /p _ov_usd_libs_dir=<"%TEMP%\ov_usd_libs.tmp" - del "%TEMP%\ov_usd_libs.tmp" >nul 2>&1 -) -if defined _ov_usd_libs_dir ( - if exist "!_ov_usd_libs_dir!\pxr\" ( - if not exist "!_ov_usd_libs_dir!\pxr\__init__.py" ( - type nul > "!_ov_usd_libs_dir!\pxr\__init__.py" - if errorlevel 1 ( - echo [WARNING] Cannot promote omni.usd.libs\pxr to a regular package (read-only cache^); skipping USD path setup. 1>&2 - set "_ov_usd_libs_dir=" - ) - ) - ) - if defined _ov_usd_libs_dir ( - set "PYTHONPATH=!_ov_usd_libs_dir!;!PYTHONPATH!" - set "PATH=!_ov_usd_libs_dir!\bin;!PATH!" - ) +for /f "delims=" %%d in ('"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py"') do ( + set "PYTHONPATH=%%d;!PYTHONPATH!" + set "PATH=%%d\bin;!PATH!" ) set "_ov_usd_libs_dir=" diff --git a/isaaclab.sh b/isaaclab.sh index 3f45f884c73a..bdb1cfac6906 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -61,33 +61,16 @@ if [ -d "$ISAACLAB_PATH/_isaac_sim" ]; then fi fi -# If omni.usd.libs is present, prepend it to PYTHONPATH and its bin/ to -# LD_LIBRARY_PATH so its patched pxr is found before usd-core's pxr and the -# native USD shared libraries are resolvable. This resolves TfType::AddAlias -# conflicts when omni.usd.schema packages (ovrtx/ovphysx) are also installed. -# -# omni.usd.libs/pxr/ is a namespace package (no __init__.py), but Python's -# import system always prefers a regular package (with __init__.py) over a -# namespace package, regardless of sys.path order. Since usd-core installs a -# regular pxr package, prepending omni.usd.libs to PYTHONPATH alone does nothing. -# We write a minimal __init__.py into omni.usd.libs/pxr/ to promote it to a -# regular package, making the sys.path order actually take effect. -if [ -d "$ISAACLAB_PATH/_isaac_sim/extscache" ]; then - _ov_usd_libs_dir=$("$python_exe" -c "import glob,os,sys; d=sorted(glob.glob(os.path.join(os.environ.get('ISAACLAB_PATH',''),'_isaac_sim','extscache','omni.usd.libs-*'))); print(d[-1] if d else '',end='')") - if [ -n "$_ov_usd_libs_dir" ]; then - if [ -d "$_ov_usd_libs_dir/pxr" ] && [ ! -f "$_ov_usd_libs_dir/pxr/__init__.py" ]; then - if ! printf '' > "$_ov_usd_libs_dir/pxr/__init__.py" 2>/dev/null; then - echo "[WARNING] Cannot promote omni.usd.libs/pxr to a regular package (read-only cache); skipping USD path setup." >&2 - unset _ov_usd_libs_dir - fi - fi - if [ -n "$_ov_usd_libs_dir" ]; then - export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" - export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" - fi - fi - unset _ov_usd_libs_dir +# Prefer omni.usd.libs over usd-core for pxr imports to avoid TfType::AddAlias +# conflicts with ovrtx/ovphysx. omni.usd.libs/pxr/ is a namespace package, so +# Python ignores PYTHONPATH order and picks usd-core's regular pxr instead; writing +# a minimal __init__.py promotes it to a regular package so path order takes effect. +_ov_usd_libs_dir=$("$python_exe" "$ISAACLAB_PATH/tools/setup_usd_libs.py") +if [ -n "$_ov_usd_libs_dir" ]; then + export PYTHONPATH="$_ov_usd_libs_dir:$PYTHONPATH" + export LD_LIBRARY_PATH="$_ov_usd_libs_dir/bin:$LD_LIBRARY_PATH" fi +unset _ov_usd_libs_dir # Execute CLI. exec "$python_exe" -c "from isaaclab.cli import cli; cli()" "$@" diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py new file mode 100644 index 000000000000..0af17220723f --- /dev/null +++ b/tools/setup_usd_libs.py @@ -0,0 +1,27 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Locate omni.usd.libs and promote its pxr package to a regular package. + +Prints the extension directory to stdout on success, nothing on failure. +Called by isaaclab.sh / isaaclab.bat to populate PYTHONPATH / LD_LIBRARY_PATH. +""" + +import glob +import os +import sys + +extscache = os.path.join(os.environ.get("ISAACLAB_PATH", ""), "_isaac_sim", "extscache") +candidates = sorted(glob.glob(os.path.join(extscache, "omni.usd.libs-*"))) +if candidates: + usd_libs_dir = candidates[-1] + init_py = os.path.join(usd_libs_dir, "pxr", "__init__.py") + if os.path.exists(os.path.join(usd_libs_dir, "pxr")) and not os.path.isfile(init_py): + try: + open(init_py, "w").close() + except OSError as exc: + print(f"[WARNING] Cannot promote omni.usd.libs/pxr to a regular package; skipping USD path setup: {exc}", file=sys.stderr) + sys.exit(0) + print(usd_libs_dir, end="") From 2e1efd3d801682b88f4ebda6d4e631205ae22cbf Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 02:59:59 +0000 Subject: [PATCH 21/33] fix --- isaaclab.bat | 2 ++ tools/setup_usd_libs.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/isaaclab.bat b/isaaclab.bat index d754cfd95abf..cc614919823d 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -41,6 +41,8 @@ if exist "%ISAACLAB_PATH%\_isaac_sim\" ( ) ) +rem Prefer omni.usd.libs over usd-core for pxr imports to avoid TfType::AddAlias +rem conflicts with ovrtx/ovphysx (see tools/setup_usd_libs.py for details). for /f "delims=" %%d in ('"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.py"') do ( set "PYTHONPATH=%%d;!PYTHONPATH!" set "PATH=%%d\bin;!PATH!" diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py index 0af17220723f..dcbbbeee9109 100644 --- a/tools/setup_usd_libs.py +++ b/tools/setup_usd_libs.py @@ -22,6 +22,9 @@ try: open(init_py, "w").close() except OSError as exc: - print(f"[WARNING] Cannot promote omni.usd.libs/pxr to a regular package; skipping USD path setup: {exc}", file=sys.stderr) + print( + f"[WARNING] Cannot promote omni.usd.libs/pxr to a regular package; skipping USD path setup: {exc}", + file=sys.stderr, + ) sys.exit(0) print(usd_libs_dir, end="") From 6dc7638a2b96de77447b8604d1b52b73f28b274a Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Thu, 16 Jul 2026 03:13:08 +0000 Subject: [PATCH 22/33] fix --- isaaclab.bat | 1 - 1 file changed, 1 deletion(-) diff --git a/isaaclab.bat b/isaaclab.bat index cc614919823d..22c65e9516f0 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -47,7 +47,6 @@ for /f "delims=" %%d in ('"%python_exe%" "%ISAACLAB_PATH%\tools\setup_usd_libs.p set "PYTHONPATH=%%d;!PYTHONPATH!" set "PATH=%%d\bin;!PATH!" ) -set "_ov_usd_libs_dir=" rem Execute CLI. "%python_exe%" -c "from isaaclab.cli import cli; cli()" %* From 437190aa0f2a57d7b25444ce8b7778b6ab26fb06 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Mon, 20 Jul 2026 19:54:01 -0400 Subject: [PATCH 23/33] _find_extscache --- .../isaaclab/test/cli/test_setup_usd_libs.py | 186 ++++++++++++++++++ .../test/cli/test_source_package_metadata.py | 12 -- tools/setup_usd_libs.py | 19 +- 3 files changed, 204 insertions(+), 13 deletions(-) create mode 100644 source/isaaclab/test/cli/test_setup_usd_libs.py diff --git a/source/isaaclab/test/cli/test_setup_usd_libs.py b/source/isaaclab/test/cli/test_setup_usd_libs.py new file mode 100644 index 000000000000..7dc59b3bd59b --- /dev/null +++ b/source/isaaclab/test/cli/test_setup_usd_libs.py @@ -0,0 +1,186 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Tests for tools/setup_usd_libs.py. + +Covers two Isaac Sim install layouts: + +* **Symlink / binary install** — ``ISAACLAB_PATH/_isaac_sim/extscache/omni.usd.libs-/`` +* **Wheel / pip install** — ``isaacsim`` package on ``sys.path``; ``extscache`` lives next + to the package ``__init__.py``. + +Each test runs the script as a subprocess so the module-level code executes in a +clean interpreter. +""" + +from __future__ import annotations + +import os +import sys +from pathlib import Path + +import pytest + +pytestmark = pytest.mark.unit + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _script_path() -> Path: + for parent in Path(__file__).resolve().parents: + candidate = parent / "tools" / "setup_usd_libs.py" + if candidate.is_file(): + return candidate + raise RuntimeError("Could not find tools/setup_usd_libs.py") + + +def _run(env_overrides: dict[str, str], tmp_path: Path) -> tuple[int, str, str]: + """Run setup_usd_libs.py as a subprocess and return (returncode, stdout, stderr).""" + import subprocess + + env = {**os.environ, **env_overrides} + result = subprocess.run( + [sys.executable, str(_script_path())], + capture_output=True, + text=True, + env=env, + ) + return result.returncode, result.stdout, result.stderr + + +def _make_usd_libs(base: Path, version: str = "26.05.0") -> Path: + """Create a minimal omni.usd.libs extension directory under *base*/extscache.""" + usd_libs = base / "extscache" / f"omni.usd.libs-{version}" + (usd_libs / "pxr").mkdir(parents=True) + return usd_libs + + +# --------------------------------------------------------------------------- +# Symlink / binary install +# --------------------------------------------------------------------------- + + +class TestSymlinkInstall: + """ISAACLAB_PATH/_isaac_sim/extscache layout (binary / developer install).""" + + def _isaaclab_env(self, tmp_path: Path) -> dict[str, str]: + return {"ISAACLAB_PATH": str(tmp_path), "PYTHONPATH": ""} + + def test_prints_usd_libs_dir(self, tmp_path: Path) -> None: + """Script prints the usd_libs_dir path when omni.usd.libs exists.""" + usd_libs = _make_usd_libs(tmp_path / "_isaac_sim") + + rc, stdout, _ = _run(self._isaaclab_env(tmp_path), tmp_path) + + assert rc == 0 + assert stdout == str(usd_libs) + + def test_creates_pxr_init_when_missing(self, tmp_path: Path) -> None: + """Script creates pxr/__init__.py so the directory becomes an importable package.""" + usd_libs = _make_usd_libs(tmp_path / "_isaac_sim") + + _run(self._isaaclab_env(tmp_path), tmp_path) + + assert (usd_libs / "pxr" / "__init__.py").is_file() + + def test_leaves_existing_pxr_init_intact(self, tmp_path: Path) -> None: + """Script does not overwrite an existing pxr/__init__.py.""" + usd_libs = _make_usd_libs(tmp_path / "_isaac_sim") + init_py = usd_libs / "pxr" / "__init__.py" + init_py.write_text("# sentinel") + + _run(self._isaaclab_env(tmp_path), tmp_path) + + assert init_py.read_text() == "# sentinel" + + def test_picks_latest_version(self, tmp_path: Path) -> None: + """Script selects the lexicographically last omni.usd.libs version.""" + _make_usd_libs(tmp_path / "_isaac_sim", "25.11.0") + newer = _make_usd_libs(tmp_path / "_isaac_sim", "26.05.0") + + _, stdout, _ = _run(self._isaaclab_env(tmp_path), tmp_path) + + assert stdout == str(newer) + + def test_no_usd_libs_produces_no_output(self, tmp_path: Path) -> None: + """Script exits 0 with no stdout when extscache has no omni.usd.libs dirs.""" + (tmp_path / "_isaac_sim" / "extscache").mkdir(parents=True) + + rc, stdout, _ = _run(self._isaaclab_env(tmp_path), tmp_path) + + assert rc == 0 + assert stdout == "" + + @pytest.mark.skipif(sys.platform == "win32", reason="chmod semantics differ on Windows") + def test_readonly_pxr_dir_warns_and_exits_cleanly(self, tmp_path: Path) -> None: + """Script emits [WARNING] to stderr and exits 0 when pxr/ is not writable.""" + usd_libs = _make_usd_libs(tmp_path / "_isaac_sim") + pxr_dir = usd_libs / "pxr" + pxr_dir.chmod(0o555) + + try: + rc, _, stderr = _run(self._isaaclab_env(tmp_path), tmp_path) + finally: + pxr_dir.chmod(0o755) + + assert rc == 0 + assert "[WARNING]" in stderr + + +# --------------------------------------------------------------------------- +# Wheel / pip install +# --------------------------------------------------------------------------- + + +class TestWheelInstall: + """Wheel install layout: isaacsim on sys.path, extscache next to __init__.py.""" + + def _wheel_env(self, isaacsim_site: Path) -> dict[str, str]: + """Environment that hides the symlink path and exposes a fake isaacsim package.""" + existing = os.environ.get("PYTHONPATH", "") + pythonpath = str(isaacsim_site) + (os.pathsep + existing if existing else "") + return { + "ISAACLAB_PATH": "", # no _isaac_sim symlink + "PYTHONPATH": pythonpath, + } + + def _make_fake_isaacsim(self, base: Path, version: str = "26.05.0") -> Path: + """Create a minimal fake isaacsim package with an extscache directory.""" + pkg = base / "isaacsim" + pkg.mkdir(parents=True, exist_ok=True) + (pkg / "__init__.py").write_text("") + return _make_usd_libs(pkg, version) + + def test_prints_usd_libs_dir(self, tmp_path: Path) -> None: + """Script finds omni.usd.libs via importlib.util.find_spec when no symlink exists.""" + usd_libs = self._make_fake_isaacsim(tmp_path) + + rc, stdout, _ = _run(self._wheel_env(tmp_path), tmp_path) + + assert rc == 0 + assert stdout == str(usd_libs) + + def test_creates_pxr_init_when_missing(self, tmp_path: Path) -> None: + """Script promotes pxr/ to a package in the wheel-install layout too.""" + usd_libs = self._make_fake_isaacsim(tmp_path) + + _run(self._wheel_env(tmp_path), tmp_path) + + assert (usd_libs / "pxr" / "__init__.py").is_file() + + def test_picks_latest_version(self, tmp_path: Path) -> None: + """Script selects the latest omni.usd.libs in the wheel extscache.""" + pkg = tmp_path / "isaacsim" + pkg.mkdir(parents=True) + (pkg / "__init__.py").write_text("") + _make_usd_libs(pkg, "25.11.0") + newer = _make_usd_libs(pkg, "26.05.0") + + _, stdout, _ = _run(self._wheel_env(tmp_path), tmp_path) + + assert stdout == str(newer) diff --git a/source/isaaclab/test/cli/test_source_package_metadata.py b/source/isaaclab/test/cli/test_source_package_metadata.py index f25634f8fff6..eb27a261b544 100644 --- a/source/isaaclab/test/cli/test_source_package_metadata.py +++ b/source/isaaclab/test/cli/test_source_package_metadata.py @@ -23,18 +23,6 @@ def _repo_root() -> Path: raise RuntimeError("Could not find Isaac Lab repository root.") -def test_isaaclab_usd_core_pin_stays_on_isaacsim_compatible_usd26_abi(): - """The kit-less USD package must stay on the Isaac Sim compatible USD 26 ABI.""" - with (_repo_root() / "pyproject.toml").open("rb") as f: - pyproject = tomllib.load(f) - - usd_core_dependencies = [ - dependency for dependency in pyproject["project"]["dependencies"] if dependency.startswith("usd-core") - ] - - assert usd_core_dependencies == ["usd-core>=26.05,<27.0 ; platform_machine in 'x86_64 AMD64'"] - - def test_isaaclab_standalone_usd_providers_are_platform_disjoint(): """Standalone USD packages must not overlap on platforms where both ship ``pxr``.""" with (_repo_root() / "pyproject.toml").open("rb") as f: diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py index dcbbbeee9109..238e85093ef3 100644 --- a/tools/setup_usd_libs.py +++ b/tools/setup_usd_libs.py @@ -10,10 +10,27 @@ """ import glob +import importlib.util import os import sys -extscache = os.path.join(os.environ.get("ISAACLAB_PATH", ""), "_isaac_sim", "extscache") + +def _find_extscache() -> str: + # Binary / symlink install: ISAACLAB_PATH/_isaac_sim/extscache + symlink_path = os.path.join(os.environ.get("ISAACLAB_PATH", ""), "_isaac_sim", "extscache") + if os.path.isdir(symlink_path): + return symlink_path + + # Wheel / pip install: locate the isaacsim package without importing it so + # that this script can run before PYTHONPATH is fully configured. + spec = importlib.util.find_spec("isaacsim") + if spec is not None and spec.origin: + return os.path.join(os.path.dirname(spec.origin), "extscache") + + return symlink_path + + +extscache = _find_extscache() candidates = sorted(glob.glob(os.path.join(extscache, "omni.usd.libs-*"))) if candidates: usd_libs_dir = candidates[-1] From 9391637619c8f4f458b732b83c79e391c01b2c75 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Mon, 20 Jul 2026 20:18:23 -0400 Subject: [PATCH 24/33] update --- .github/workflows/wheel.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index 39be0686637c..087f5886ac10 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -190,9 +190,15 @@ jobs: exit 1 fi + # newton[importers]==1.2.0 pins usd-core<26.5, but isaacsim bundles its + # own pxr at runtime so that upper bound is irrelevant when isaacsim is + # installed. Override it so the resolver accepts usd-core>=26.05. + printf 'usd-core>=26.05\n' > /tmp/usd-override.txt + uv pip install \ --dry-run \ --extra-index-url https://pypi.nvidia.com \ --index-strategy unsafe-best-match \ --prerelease=allow \ + --override /tmp/usd-override.txt \ "${wheel}[isaacsim,all]" From cc3c00fd8000a1859f3e5e64d6c7684c5a911eb8 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 11:07:59 -0400 Subject: [PATCH 25/33] fix --- .github/workflows/wheel.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index 087f5886ac10..39be0686637c 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -190,15 +190,9 @@ jobs: exit 1 fi - # newton[importers]==1.2.0 pins usd-core<26.5, but isaacsim bundles its - # own pxr at runtime so that upper bound is irrelevant when isaacsim is - # installed. Override it so the resolver accepts usd-core>=26.05. - printf 'usd-core>=26.05\n' > /tmp/usd-override.txt - uv pip install \ --dry-run \ --extra-index-url https://pypi.nvidia.com \ --index-strategy unsafe-best-match \ --prerelease=allow \ - --override /tmp/usd-override.txt \ "${wheel}[isaacsim,all]" From ea91a4ceb9062e5c0aa4782c7af32fa921e943d4 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 11:13:26 -0400 Subject: [PATCH 26/33] revert --- .github/workflows/wheel.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index 39be0686637c..087f5886ac10 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -190,9 +190,15 @@ jobs: exit 1 fi + # newton[importers]==1.2.0 pins usd-core<26.5, but isaacsim bundles its + # own pxr at runtime so that upper bound is irrelevant when isaacsim is + # installed. Override it so the resolver accepts usd-core>=26.05. + printf 'usd-core>=26.05\n' > /tmp/usd-override.txt + uv pip install \ --dry-run \ --extra-index-url https://pypi.nvidia.com \ --index-strategy unsafe-best-match \ --prerelease=allow \ + --override /tmp/usd-override.txt \ "${wheel}[isaacsim,all]" From cf0df8519d5160695dce448cf53727a2f24baf39 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 12:51:49 -0400 Subject: [PATCH 27/33] update --- .github/workflows/wheel.yml | 6 ------ pyproject.toml | 10 ++++++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index 087f5886ac10..39be0686637c 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -190,15 +190,9 @@ jobs: exit 1 fi - # newton[importers]==1.2.0 pins usd-core<26.5, but isaacsim bundles its - # own pxr at runtime so that upper bound is irrelevant when isaacsim is - # installed. Override it so the resolver accepts usd-core>=26.05. - printf 'usd-core>=26.05\n' > /tmp/usd-override.txt - uv pip install \ --dry-run \ --extra-index-url https://pypi.nvidia.com \ --index-strategy unsafe-best-match \ --prerelease=allow \ - --override /tmp/usd-override.txt \ "${wheel}[isaacsim,all]" diff --git a/pyproject.toml b/pyproject.toml index 45191adf33e1..a4508779ed4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,10 +83,12 @@ dependencies = [ "onnxscript>=0.5", # ----- newton (default physics engine) ----- # Loose bound so the wheel co-resolves with isaacsim's newton[sim]==1.2.0 pin; the - # exact git commit is forced via [tool.uv].override-dependencies (uv sync only). - # The importers extra carries the mesh-processing deps (coacd, fast-simplification, - # ...) that honoring USD-authored ``physics:approximation`` requires. - "newton[sim,importers]>=1.2.0", + # exact git commit (with the importers extra) is forced via + # [tool.uv].override-dependencies (uv sync only). The importers extra is omitted + # here because every published newton release pins usd-core<26.5 in that extra, + # conflicting with our usd-core>=26.05 requirement; the git override uses a build + # that dropped that upper bound. + "newton[sim]>=1.2.0", # Loose bound co-resolves with isaacsim's ==0.2.0; the override below forces >=0.4.0. "newton-usd-schemas>=0.2.0", "PyOpenGL-accelerate>=3.1.0", From 368476c1176c1eda22dae04860a38777226e9e1f Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 15:38:36 -0400 Subject: [PATCH 28/33] update --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index a4508779ed4e..85d67f0235dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -342,6 +342,10 @@ override-dependencies = [ "newton[sim,importers] @ git+https://github.com/newton-physics/newton.git@81cdcfc2dd89f8b7285e32b5e3853092a97fa6f9", # Force the Newton-matched schemas over isaacsim's ==0.2.0 pin. "newton-usd-schemas>=0.4.0", + # newton[importers] pins usd-core<26.5 in every published release and the current + # dev build; override it so uv accepts our usd-core>=26.05 requirement. + # Remove once newton publishes a release that drops the upper bound. + "usd-core>=26.05,<27.0 ; platform_machine in 'x86_64 AMD64'", "torch==2.11.0", "torchvision==0.26.0", "torchaudio==2.11.0", From f6a6c99e78633d393ecf2cbccbc6c9ca3b17f546 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 16:16:15 -0400 Subject: [PATCH 29/33] undo --- pyproject.toml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 85d67f0235dc..ab6fdf1a7190 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,12 +83,10 @@ dependencies = [ "onnxscript>=0.5", # ----- newton (default physics engine) ----- # Loose bound so the wheel co-resolves with isaacsim's newton[sim]==1.2.0 pin; the - # exact git commit (with the importers extra) is forced via - # [tool.uv].override-dependencies (uv sync only). The importers extra is omitted - # here because every published newton release pins usd-core<26.5 in that extra, - # conflicting with our usd-core>=26.05 requirement; the git override uses a build - # that dropped that upper bound. - "newton[sim]>=1.2.0", + # exact git commit is forced via [tool.uv].override-dependencies (uv sync only). + # The importers extra carries the mesh-processing deps (coacd, fast-simplification, + # ...) that honoring USD-authored ``physics:approximation`` requires. + "newton[sim,importers]>=1.2.0", # Loose bound co-resolves with isaacsim's ==0.2.0; the override below forces >=0.4.0. "newton-usd-schemas>=0.2.0", "PyOpenGL-accelerate>=3.1.0", From 3c5d45b51dc504bc9b8dae083f72363c80c38e39 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 16:23:20 -0400 Subject: [PATCH 30/33] update --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ab6fdf1a7190..3709b0c461dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -86,7 +86,7 @@ dependencies = [ # exact git commit is forced via [tool.uv].override-dependencies (uv sync only). # The importers extra carries the mesh-processing deps (coacd, fast-simplification, # ...) that honoring USD-authored ``physics:approximation`` requires. - "newton[sim,importers]>=1.2.0", + "newton[sim]>=1.2.0", # Loose bound co-resolves with isaacsim's ==0.2.0; the override below forces >=0.4.0. "newton-usd-schemas>=0.2.0", "PyOpenGL-accelerate>=3.1.0", From 294ccf1f761820b04808bfd96f30dd9d17a3df9d Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 17:55:07 -0400 Subject: [PATCH 31/33] update --- uv.lock | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/uv.lock b/uv.lock index 52e48e0304cb..7898817dda4c 100644 --- a/uv.lock +++ b/uv.lock @@ -119,6 +119,7 @@ overrides = [ { name = "torchvision", marker = "platform_machine == 'arm64' and sys_platform == 'linux'", specifier = "==0.26.0", index = "https://download.pytorch.org/whl/cu130" }, { name = "torchvision", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'", specifier = "==0.26.0", index = "https://download.pytorch.org/whl/cu128" }, { name = "torchvision", marker = "sys_platform == 'win32'", specifier = "==0.26.0", index = "https://download.pytorch.org/whl/cu128" }, + { name = "usd-core", marker = "platform_machine in 'x86_64 AMD64'", specifier = ">=26.5,<27.0" }, ] [[package]] @@ -2971,7 +2972,7 @@ requires-dist = [ { name = "lazy-loader", specifier = ">=0.4" }, { name = "matplotlib", specifier = ">=3.10.3" }, { name = "moviepy", specifier = ">=1.0.3,<2.0.0.dev0" }, - { name = "newton", extras = ["sim", "importers"], specifier = ">=1.2.0" }, + { name = "newton", extras = ["sim"], specifier = ">=1.2.0" }, { name = "newton-usd-schemas", specifier = ">=0.2.0" }, { name = "numba", specifier = ">=0.63.1" }, { name = "numpy", specifier = ">=2" }, @@ -3034,7 +3035,7 @@ requires-dist = [ { name = "transformers", specifier = "==4.57.6" }, { name = "trimesh" }, { name = "typing-extensions", specifier = ">=4.12.2" }, - { name = "usd-core", marker = "platform_machine in 'x86_64 AMD64'", specifier = ">=25.11,<26.0" }, + { name = "usd-core", marker = "platform_machine in 'x86_64 AMD64'", specifier = ">=26.5,<27.0" }, { name = "usd-exchange", marker = "platform_machine in 'aarch64 arm64'", specifier = ">=2.2" }, { name = "viser", marker = "extra == 'viser'", specifier = ">=1.0.16" }, { name = "warp-lang", specifier = "==1.15.0.dev20260626" }, @@ -4549,7 +4550,7 @@ importers = [ { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-12-isaaclab-dev-all' or extra != 'extra-12-isaaclab-dev-isaacsim' or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-mimic') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-ov') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-test') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-viser')" }, { name = "trimesh", version = "4.11.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-12-isaaclab-dev-isaacsim' or (extra == 'extra-12-isaaclab-dev-all' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-mimic' and extra == 'extra-12-isaaclab-dev-teleop')" }, { name = "trimesh", version = "4.12.2", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-12-isaaclab-dev-all' or extra != 'extra-12-isaaclab-dev-isaacsim' or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-mimic') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-ov') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-test') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-viser')" }, - { name = "usd-core", marker = "platform_machine != 'aarch64' or (extra == 'extra-12-isaaclab-dev-all' and extra == 'extra-12-isaaclab-dev-isaacsim') or (extra == 'extra-12-isaaclab-dev-all' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-mimic') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-ov') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-test') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-viser') or (extra == 'extra-12-isaaclab-dev-mimic' and extra == 'extra-12-isaaclab-dev-teleop')" }, + { name = "usd-core", marker = "platform_machine in 'x86_64 AMD64' or (extra == 'extra-12-isaaclab-dev-all' and extra == 'extra-12-isaaclab-dev-isaacsim') or (extra == 'extra-12-isaaclab-dev-all' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-mimic') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-ov') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-test') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-viser') or (extra == 'extra-12-isaaclab-dev-mimic' and extra == 'extra-12-isaaclab-dev-teleop')" }, { name = "usd-exchange", marker = "platform_machine == 'aarch64' or (extra == 'extra-12-isaaclab-dev-all' and extra == 'extra-12-isaaclab-dev-isaacsim') or (extra == 'extra-12-isaaclab-dev-all' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-mimic') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-ov') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-teleop') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-test') or (extra == 'extra-12-isaaclab-dev-isaacsim' and extra == 'extra-12-isaaclab-dev-viser') or (extra == 'extra-12-isaaclab-dev-mimic' and extra == 'extra-12-isaaclab-dev-teleop')" }, ] sim = [ @@ -7930,12 +7931,12 @@ wheels = [ [[package]] name = "usd-core" -version = "25.11" +version = "26.8" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6c/a4/92db335084f0de14b5d4e1800b847057e3ef36bdbb211e5617f3d9940e92/usd_core-25.11-cp312-none-macosx_10_9_universal2.whl", hash = "sha256:bbf89d0671e0773b957a5a3a3e0178e13d4318d46fd8201fcf1d87e3d5501556", size = 38511379, upload-time = "2025-10-24T19:01:24.506Z" }, - { url = "https://files.pythonhosted.org/packages/ed/f1/dbf18bee5b569a06119f0cde798daeef4837887594a0caf415eb1d75112a/usd_core-25.11-cp312-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c05c05150f6c4598e0738677f0b7c8f82ff9fc492d040ed78147eb1ad5ce8545", size = 27393145, upload-time = "2025-10-24T19:01:27.841Z" }, - { url = "https://files.pythonhosted.org/packages/48/34/dd9883f27526288de19741100cb5b75f2725423367a999c055a677d1d88a/usd_core-25.11-cp312-none-win_amd64.whl", hash = "sha256:7bc5aaad20287bfc821e73e2ced99123e448e40ffd018acf99b09975eab4012d", size = 13061673, upload-time = "2025-10-24T19:01:30.396Z" }, + { url = "https://files.pythonhosted.org/packages/97/44/fb780d02b04bbebc410bfb6decccc66aec07fb0322172ad019c4579ad80a/usd_core-26.8-cp312-none-macosx_10_15_universal2.whl", hash = "sha256:aaf1a68bf4c7ab959b9f4d3a6e0ef9347ff6135a1452676bb40916060146c53e", size = 40698020, upload-time = "2026-07-20T14:32:20.788Z" }, + { url = "https://files.pythonhosted.org/packages/19/0b/efe5c0d7c273149ac94083831e5b36649925a621a73cd2ddf9616e160c8c/usd_core-26.8-cp312-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:204fb1ef1fc977b827c491f4e9fa39b57518504ed0cacfe12e026e95123cacf1", size = 29530957, upload-time = "2026-07-20T14:32:24.255Z" }, + { url = "https://files.pythonhosted.org/packages/79/d3/749edc4d2eea3ffb94aa0526d5da6f4a3f185ef7004ceeb6b5ecdb6a0c68/usd_core-26.8-cp312-none-win_amd64.whl", hash = "sha256:6db0031224b718cae53e4b19ecd80aea0a7ed4348e330fd82ccfbdc9b8b311ed", size = 13887898, upload-time = "2026-07-20T14:32:27.452Z" }, ] [[package]] From b38daf5ee23f569582887279ecd191d9bccbe623 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 21 Jul 2026 23:11:51 -0400 Subject: [PATCH 32/33] fix --- tools/setup_usd_libs.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/setup_usd_libs.py b/tools/setup_usd_libs.py index 238e85093ef3..c0baee26a233 100644 --- a/tools/setup_usd_libs.py +++ b/tools/setup_usd_libs.py @@ -16,10 +16,15 @@ def _find_extscache() -> str: - # Binary / symlink install: ISAACLAB_PATH/_isaac_sim/extscache - symlink_path = os.path.join(os.environ.get("ISAACLAB_PATH", ""), "_isaac_sim", "extscache") - if os.path.isdir(symlink_path): - return symlink_path + # Binary / symlink install: ISAACLAB_PATH/_isaac_sim/extscache. + # Only probe when ISAACLAB_PATH is set; an empty value would produce a + # relative path that resolves against CWD and may accidentally match a + # _isaac_sim symlink in an unrelated working directory. + isaaclab_path = os.environ.get("ISAACLAB_PATH", "") + if isaaclab_path: + symlink_path = os.path.join(isaaclab_path, "_isaac_sim", "extscache") + if os.path.isdir(symlink_path): + return symlink_path # Wheel / pip install: locate the isaacsim package without importing it so # that this script can run before PYTHONPATH is fully configured. @@ -27,11 +32,11 @@ def _find_extscache() -> str: if spec is not None and spec.origin: return os.path.join(os.path.dirname(spec.origin), "extscache") - return symlink_path + return "" extscache = _find_extscache() -candidates = sorted(glob.glob(os.path.join(extscache, "omni.usd.libs-*"))) +candidates = sorted(glob.glob(os.path.join(extscache, "omni.usd.libs-*"))) if extscache else [] if candidates: usd_libs_dir = candidates[-1] init_py = os.path.join(usd_libs_dir, "pxr", "__init__.py") From ecd7233900ff7e8177f3be810c175e2948d40723 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 22 Jul 2026 11:05:18 -0400 Subject: [PATCH 33/33] fix --- source/isaaclab/test/cli/test_uv_run_pyproject.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/isaaclab/test/cli/test_uv_run_pyproject.py b/source/isaaclab/test/cli/test_uv_run_pyproject.py index b87894fa8bf6..cfd1ff034403 100644 --- a/source/isaaclab/test/cli/test_uv_run_pyproject.py +++ b/source/isaaclab/test/cli/test_uv_run_pyproject.py @@ -153,7 +153,7 @@ def test_uv_run_base_dependencies_cover_newton_rsl_rl_training(): # Newton is the default physics engine and RSL-RL the default training library, # so both ship as core third-party requirements (not opt-in extras). The importers # extra carries the mesh-processing deps that authored collision approximations need. - assert any(dep.startswith("newton[sim,importers]") for dep in dependencies) + assert any(dep.startswith("newton[sim]") for dep in dependencies) assert any(dep.startswith("rsl-rl-lib") for dep in dependencies)