Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions docs/source/setup/installation/include/src_clone_isaaclab.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ We provide helper executables at the repository root — ``./isaaclab.sh`` (Linu

./isaaclab.sh --help

usage: isaaclab.sh [-h] [-i [INSTALL]] [-f] [-p ...] [-s ...] [-t ...] [-o ...] [-v] [-d] [-n ...] [-c [CONDA]] [-u [UV]]
usage: isaaclab.sh [-h] [-i [INSTALL]] [-f] [-p ...] [-s ...] [-t ...] [-o ...] [-v] [-d] [-n ...] [-c [CONDA]] [-u [UV]] [--isaacsim_source PATH]

Isaac Lab CLI

Expand Down Expand Up @@ -55,6 +55,9 @@ We provide helper executables at the repository root — ``./isaaclab.sh`` (Linu
-c [CONDA], --conda [CONDA]
Create a new conda environment for Isaac Lab. Default name is 'env_isaaclab'.
-u [UV], --uv [UV] Create a new uv environment for Isaac Lab. Default name is 'env_isaaclab'.
--isaacsim_source PATH
Incrementally build the Isaac Sim source checkout at PATH and link its live release
tree as '_isaac_sim'. Python commands keep using the active uv environment.

.. tab-item:: :icon:`fa-brands fa-windows` Windows
:sync: windows
Expand All @@ -63,7 +66,7 @@ We provide helper executables at the repository root — ``./isaaclab.sh`` (Linu

isaaclab.bat --help

usage: isaaclab.bat [-h] [-i [INSTALL]] [-f] [-p ...] [-s ...] [-t ...] [-o ...] [-v] [-d] [-n ...] [-c [CONDA]] [-u [UV]]
usage: isaaclab.bat [-h] [-i [INSTALL]] [-f] [-p ...] [-s ...] [-t ...] [-o ...] [-v] [-d] [-n ...] [-c [CONDA]] [-u [UV]] [--isaacsim_source PATH]

Isaac Lab CLI

Expand Down Expand Up @@ -94,3 +97,6 @@ We provide helper executables at the repository root — ``./isaaclab.sh`` (Linu
-c [CONDA], --conda [CONDA]
Create a new conda environment for Isaac Lab. Default name is 'env_isaaclab'.
-u [UV], --uv [UV] Create a new uv environment for Isaac Lab. Default name is 'env_isaaclab'.
--isaacsim_source PATH
Incrementally build the Isaac Sim source checkout at PATH and link its live release
tree as '_isaac_sim'. Python commands keep using the active uv environment.
168 changes: 101 additions & 67 deletions docs/source/setup/installation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -777,98 +777,132 @@ On Windows, enable `long-path support
<https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry#enable-long-paths-in-windows-10-version-1607-and-later>`__
before building.

Choose how to connect the Isaac Sim source build to Isaac Lab:

.. tab-set::
:sync-group: installation-platform
:sync-group: isaacsim-source-installation-method

.. tab-item:: :icon:`fa-brands fa-linux` Linux (x86_64)
:sync: linux-x86_64
.. tab-item:: uv (Recommended)
:sync: uv

.. code-block:: bash
Clone Isaac Sim next to the Isaac Lab checkout. From the Isaac Lab root, run the source-build
command. It incrementally builds Isaac Sim and links the live release tree as ``_isaac_sim``:

git clone https://github.com/isaac-sim/IsaacSim.git
cd IsaacSim
./build.sh
export ISAACSIM_PATH="${PWD}/_build/linux-x86_64/release"
export ISAACSIM_PYTHON_EXE="${ISAACSIM_PATH}/python.sh"
${ISAACSIM_PATH}/isaac-sim.sh
${ISAACSIM_PYTHON_EXE} -c "print('Isaac Sim configuration is now complete.')"
${ISAACSIM_PYTHON_EXE} ${ISAACSIM_PATH}/standalone_examples/api/isaacsim.core.experimental.api/add_cubes.py
.. code-block:: text

.. tab-item:: :icon:`fa-brands fa-linux` Linux (aarch64)
:sync: linux-aarch64
git clone https://github.com/isaac-sim/IsaacSim.git ../IsaacSim
uv run isaaclab --isaacsim_source ../IsaacSim

.. code-block:: bash
Isaac Lab runs the active ``uv`` environment through Isaac Sim's generated Python launcher.
This loads Kit and extensions directly from the source build without creating wheels or
changing ``pyproject.toml`` and ``uv.lock``. Run Isaac Lab against the source build with:

git clone https://github.com/isaac-sim/IsaacSim.git
cd IsaacSim
./build.sh
export ISAACSIM_PATH="${PWD}/_build/linux-aarch64/release"
export ISAACSIM_PYTHON_EXE="${ISAACSIM_PATH}/python.sh"
${ISAACSIM_PATH}/isaac-sim.sh
${ISAACSIM_PYTHON_EXE} -c "print('Isaac Sim configuration is now complete.')"
${ISAACSIM_PYTHON_EXE} ${ISAACSIM_PATH}/standalone_examples/api/isaacsim.core.experimental.api/add_cubes.py
.. code-block:: text

.. tab-item:: :icon:`fa-brands fa-windows` Windows (x86_64)
:sync: windows-x86_64
uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole-Direct physics=isaacsim_physx

.. code-block:: batch
After changing Isaac Sim source, run the same ``--isaacsim_source`` command again. The native
build is incremental, and the link continues to expose the updated build immediately; no
wheel packaging or dependency resolution step is required.

git clone https://github.com/isaac-sim/IsaacSim.git
cd IsaacSim
build.bat
set ISAACSIM_PATH="%cd%\_build\windows-x86_64\release"
set ISAACSIM_PYTHON_EXE="%ISAACSIM_PATH:"=%\python.bat"
%ISAACSIM_PATH%\isaac-sim.bat
%ISAACSIM_PYTHON_EXE% -c "print('Isaac Sim configuration is now complete.')"
%ISAACSIM_PYTHON_EXE% %ISAACSIM_PATH%\standalone_examples\api\isaacsim.core.experimental.api\add_cubes.py
.. tab-item:: isaaclab.sh / isaaclab.bat
:sync: isaaclab-script

Return to the workspace containing the ``IsaacSim`` checkout, then clone Isaac Lab, link it to the
source build, install, and verify:
Build and verify Isaac Sim for your platform:

.. code-block:: text
.. tab-set::
:sync-group: installation-platform

cd ..
.. tab-item:: :icon:`fa-brands fa-linux` Linux (x86_64)
:sync: linux-x86_64

.. isaaclab-clone-commands::
.. code-block:: bash

.. tab-set::
:sync-group: installation-platform
git clone https://github.com/isaac-sim/IsaacSim.git
cd IsaacSim
./build.sh
export ISAACSIM_PATH="${PWD}/_build/linux-x86_64/release"
export ISAACSIM_PYTHON_EXE="${ISAACSIM_PATH}/python.sh"
${ISAACSIM_PATH}/isaac-sim.sh
${ISAACSIM_PYTHON_EXE} -c "print('Isaac Sim configuration is now complete.')"
${ISAACSIM_PYTHON_EXE} ${ISAACSIM_PATH}/standalone_examples/api/isaacsim.core.experimental.api/add_cubes.py

.. tab-item:: :icon:`fa-brands fa-linux` Linux (x86_64)
:sync: linux-x86_64
.. tab-item:: :icon:`fa-brands fa-linux` Linux (aarch64)
:sync: linux-aarch64

.. code-block:: bash
.. code-block:: bash

cd IsaacLab
ln -s ${ISAACSIM_PATH} _isaac_sim
sudo apt install cmake build-essential
./isaaclab.sh -i
./isaaclab.sh -p scripts/tutorials/00_sim/create_empty.py --viz kit
git clone https://github.com/isaac-sim/IsaacSim.git
cd IsaacSim
./build.sh
export ISAACSIM_PATH="${PWD}/_build/linux-aarch64/release"
export ISAACSIM_PYTHON_EXE="${ISAACSIM_PATH}/python.sh"
${ISAACSIM_PATH}/isaac-sim.sh
${ISAACSIM_PYTHON_EXE} -c "print('Isaac Sim configuration is now complete.')"
${ISAACSIM_PYTHON_EXE} ${ISAACSIM_PATH}/standalone_examples/api/isaacsim.core.experimental.api/add_cubes.py

.. tab-item:: :icon:`fa-brands fa-linux` Linux (aarch64)
:sync: linux-aarch64
.. tab-item:: :icon:`fa-brands fa-windows` Windows (x86_64)
:sync: windows-x86_64

.. code-block:: bash
.. code-block:: batch

cd IsaacLab
ln -s ${ISAACSIM_PATH} _isaac_sim
sudo apt install cmake build-essential python3.12-dev libgl1-mesa-dev libx11-dev \
libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev
./isaaclab.sh -i
./isaaclab.sh -p scripts/tutorials/00_sim/create_empty.py --viz kit
git clone https://github.com/isaac-sim/IsaacSim.git
cd IsaacSim
build.bat
set ISAACSIM_PATH="%cd%\_build\windows-x86_64\release"
set ISAACSIM_PYTHON_EXE="%ISAACSIM_PATH:"=%\python.bat"
%ISAACSIM_PATH%\isaac-sim.bat
%ISAACSIM_PYTHON_EXE% -c "print('Isaac Sim configuration is now complete.')"
%ISAACSIM_PYTHON_EXE% %ISAACSIM_PATH%\standalone_examples\api\isaacsim.core.experimental.api\add_cubes.py

.. tab-item:: :icon:`fa-brands fa-windows` Windows (x86_64)
:sync: windows-x86_64
Return to the workspace containing the ``IsaacSim`` checkout, then clone Isaac Lab:

.. code-block:: batch
.. code-block:: text

cd IsaacLab
mklink /D _isaac_sim %ISAACSIM_PATH%
isaaclab.bat -i
isaaclab.bat -p scripts\tutorials\00_sim\create_empty.py --viz kit
cd ..

.. isaaclab-clone-commands::

Link Isaac Lab to the source build, install, and verify:

.. tab-set::
:sync-group: installation-platform

.. tab-item:: :icon:`fa-brands fa-linux` Linux (x86_64)
:sync: linux-x86_64

.. code-block:: bash

cd IsaacLab
ln -s ${ISAACSIM_PATH} _isaac_sim
sudo apt install cmake build-essential
./isaaclab.sh -i
./isaaclab.sh -p scripts/tutorials/00_sim/create_empty.py --viz kit

.. tab-item:: :icon:`fa-brands fa-linux` Linux (aarch64)
:sync: linux-aarch64

.. code-block:: bash

cd IsaacLab
ln -s ${ISAACSIM_PATH} _isaac_sim
sudo apt install cmake build-essential python3.12-dev libgl1-mesa-dev libx11-dev \
libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev
./isaaclab.sh -i
./isaaclab.sh -p scripts/tutorials/00_sim/create_empty.py --viz kit

.. tab-item:: :icon:`fa-brands fa-windows` Windows (x86_64)
:sync: windows-x86_64

.. code-block:: batch

cd IsaacLab
mklink /D _isaac_sim %ISAACSIM_PATH%
isaaclab.bat -i
isaaclab.bat -p scripts\tutorials\00_sim\create_empty.py --viz kit

The tutorial command should open a black simulator viewport. Use the binary-installation
troubleshooting links above if the source build does not launch.
The tutorial command should open a black simulator viewport. Use the binary-installation
troubleshooting links above if the source build does not launch.


.. _installation-method-container:
Expand Down
15 changes: 14 additions & 1 deletion skills/user/install-isaac-lab/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,25 @@ Read `docs/source/setup/installation/index.rst` "System requirements" from the c

Run the docs-defined minimal verification command after every install, before larger tests. The command varies by route:

- Automatic uv (`installation-method-uv`), legacy installer (`installation-legacy-installer`), managed Python env (`installation-method-python-env`), Isaac Lab wheel (`installation-method-wheel`), and Isaac Sim source build (`installation-method-source`) verify Isaac Lab via the tutorial script documented in the section's included verification snippet:
- Automatic uv (`installation-method-uv`), legacy installer (`installation-legacy-installer`), managed Python env (`installation-method-python-env`), and Isaac Lab wheel (`installation-method-wheel`) verify Isaac Lab via the tutorial script documented in the section's included verification snippet:

```bash
uv run python scripts/tutorials/00_sim/create_empty.py --viz kit
```

- Isaac Sim source build (`installation-method-source`) runs the same script against the locally built Isaac Sim wheels:

```bash
uv run --extra isaacsim-local python scripts/tutorials/00_sim/create_empty.py --viz kit
```

This only uses the local build when `pyproject.toml` carries both edits that
`uv run isaaclab --isaacsim_source <path>` writes: `find-links = ["_isaac_sim_wheels"]` under
`[tool.uv]`, and an `isaacsim-local` extra pinning the exact version from
`_isaac_sim_wheels/isaacsim-*.whl`. Without the pin, uv resolves the published wheels from
`pypi.nvidia.com` instead, because source builds carry pre-release local versions that sort below
the release.

- Downloaded Isaac Sim package (`installation-method-binary`) uses the bundled-Python verification documented in the section (launch via `${ISAACSIM_PATH}/isaac-sim.sh`, then run the tutorial script from the checkout).
- Docker (`installation-method-container`) runs the same tutorial verification inside the container as documented in `docs/source/features/docker_cloud.rst`.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Added
^^^^^

* Added the ``--isaacsim_source`` CLI option, which incrementally builds Isaac Sim from a source checkout,
links its live release tree into the repository as ``_isaac_sim``, and runs Python commands with
the active environment through Isaac Sim's generated launcher. This avoided rebuilding and
installing Python wheels after every incremental native build and left ``pyproject.toml`` and
``uv.lock`` unchanged.
12 changes: 12 additions & 0 deletions source/isaaclab/isaaclab/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
)
from .commands.misc import (
command_build_docs,
command_build_isaacsim,
command_new,
command_run_docker,
command_run_isaacsim,
Expand Down Expand Up @@ -262,6 +263,14 @@ def cli() -> None:
const="env_isaaclab",
help="Create a new uv environment for Isaac Lab. Default name is 'env_isaaclab'.",
)
parser.add_argument(
"--isaacsim_source",
metavar="PATH",
help=(
"Incrementally build the Isaac Sim source checkout at PATH and link its live release\n"
"tree as '_isaac_sim'. Python commands keep using the active uv environment."
),
)

args = parser.parse_args()

Expand All @@ -277,6 +286,9 @@ def cli() -> None:
elif args.uv:
command_setup_uv(args.uv)

elif args.isaacsim_source:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Suggestion — --isaacsim_source is silently ignored when combined with an earlier flag

This branch sits in the elif chain after --install, --format, --conda, and --uv. Invoking, for example, isaaclab -i --isaacsim_source ./IsaacSim runs only the install and exits without building or linking anything, with no warning; the user discovers it only when uv run --extra isaacsim-local picks the published release. Since this is an option (not a subcommand) that takes a value, either handle the combination explicitly or fail with a clear mutually-exclusive message.

command_build_isaacsim(args.isaacsim_source)

elif args.vscode:
command_vscode_settings()

Expand Down
80 changes: 80 additions & 0 deletions source/isaaclab/isaaclab/cli/commands/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

"""Misc commands"""

import platform
import shutil
import sys
from pathlib import Path

from ..utils import (
ISAACLAB_ROOT,
Expand Down Expand Up @@ -118,6 +121,83 @@ def command_build_docs() -> None:
print_info(f"Open with: xdg-open {index_path}")


def command_build_isaacsim(source_path: str) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Warning — Add unit tests for the new source-build command

command_build_isaacsim introduces filesystem mutation and several external-command branches that never require a real build: invalid checkout -> SystemExit(1), existing build -> skip build.sh, empty dist -> SystemExit(1), existing real directory at _isaac_sim_wheels -> SystemExit(1) vs. symlink -> replaced, and missing uv -> warning instead of uv lock. None are covered, so inverting a check or dropping a SystemExit would ship unnoticed. Add tests under source/isaaclab/test/cli/ driving the function with tmp_path and monkeypatched run_command, is_windows, shutil.which, and ISAACLAB_ROOT, asserting the exact command sequence (build.sh, then repo.sh python_package --create, repo.sh comment_archive_deps, repo.sh python_package --wheel) and the uv lock environment. Also cover --isaacsim_source parsing/dispatch in the CLI entry point.

"""Build Isaac Sim from source and make it usable through ``uv`` (--isaacsim_source).

Runs Isaac Sim's incremental build and links its release tree into Isaac Lab as ``_isaac_sim``.
Python commands launched through the Isaac Lab CLI use the active environment's interpreter
through Isaac Sim's ``python.sh`` or ``python.bat`` wrapper, so they load the live build without
packaging or installing it as wheels.

Args:
source_path: Path to an Isaac Sim source checkout.
"""
isaacsim_root = Path(source_path).expanduser().resolve()
build_script = isaacsim_root / ("build.bat" if is_windows() else "build.sh")

if not build_script.is_file():
print_error(f"'{isaacsim_root}' is not an Isaac Sim source checkout ({build_script.name} not found).")
print_info("Clone it first with: git clone https://github.com/isaac-sim/IsaacSim.git")
raise SystemExit(1)

print_info("Incrementally building Isaac Sim from source. This may take a while...")
run_command([str(build_script)], cwd=isaacsim_root)

release_dir = _resolve_isaacsim_release_dir(isaacsim_root)
python_launcher = release_dir / ("python.bat" if is_windows() else "python.sh")
if not python_launcher.is_file():
print_error(f"The Isaac Sim build did not produce {python_launcher}.")
raise SystemExit(1)

link_path = ISAACLAB_ROOT / "_isaac_sim"
if link_path.is_symlink() or link_path.exists():
if link_path.is_symlink():
link_path.unlink()
else:
print_error(f"{link_path} exists and is not a symbolic link. Remove it and re-run.")
raise SystemExit(1)
try:
link_path.symlink_to(release_dir, target_is_directory=True)
except OSError as error:
print_error(f"Could not link {link_path} to {release_dir}: {error}")
if is_windows():
print_info("Enable Windows Developer Mode or run from an elevated terminal, then retry.")
raise SystemExit(1) from error
print_info(f"Linked {link_path} -> {release_dir}")
_repoint_source_build_prebundles()

print_info("Isaac Sim is ready. Python commands now use the live source build through '_isaac_sim'.")
print_info("Run Isaac Lab against it with:")
print_info(" uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole-Direct physics=isaacsim_physx")


def _resolve_isaacsim_release_dir(isaacsim_root: Path) -> Path:
"""Resolve the platform-specific Isaac Sim release directory."""
machine = platform.machine().lower()
targets = {
("linux", "amd64"): "linux-x86_64",
("linux", "x86_64"): "linux-x86_64",
("linux", "aarch64"): "linux-aarch64",
("linux", "arm64"): "linux-aarch64",
("win32", "amd64"): "windows-x86_64",
("win32", "x86_64"): "windows-x86_64",
}
target = targets.get((sys.platform, machine))
if target is None:
print_error(f"Isaac Sim source builds are not supported on platform '{sys.platform}' with machine '{machine}'.")
raise SystemExit(1)
return isaacsim_root / "_build" / target / "release"


def _repoint_source_build_prebundles() -> None:
"""Keep Isaac Sim's prebundled packages from shadowing the active environment."""
# ``install`` imports ``command_vscode_settings`` from this module, so defer this import until
# both command modules are initialized. Reuse the same protection as the legacy installer.
from .install import _repoint_prebundle_packages

_repoint_prebundle_packages()


def command_run_docker(args: list[str]) -> None:
"""Run the docker container helper script (docker/container.py).

Expand Down
Loading
Loading