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
51 changes: 48 additions & 3 deletions scripts/tools/setup_isaacgym_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
# $UNISIM_ISAACGYM_HOME/isaacgym/python unpacked Preview 4
# $UNISIM_ISAACGYM_HOME/IsaacGym_Preview_4_Package.tar.gz downloaded tarball
#
# The script is idempotent: completed steps are skipped on re-run.
# The script is idempotent: completed steps are skipped on re-run. A conda env
# is not relocatable, so if the whole ISAACGYM_HOME tree was moved since the
# env was created, the script repairs the stale absolute paths (entry-point
# shebangs, .pth files, egg-links, conda-meta) in place instead of re-creating
# the env.

set -euo pipefail

Expand Down Expand Up @@ -99,6 +103,43 @@ else
python=3.8 -c conda-forge --override-channels
fi

# Conda envs hard-code their install prefix in entry-point shebangs, .pth
# files, egg-links and conda-meta. If the tree was relocated (e.g. from the
# legacy $HOME/.unilab/isaacgym to the current default), those references go
# stale: `bin/pip` fails with "cannot execute: required file not found" and
# the editable install disappears from sys.path, while every skip-check above
# still passes. Detect the stale prefix from the pip shebang and rewrite it
# in place; this is far cheaper than re-creating the env (torch is ~GBs).
repair_env_prefix_if_needed() {
local pip_script="$ENV_ROOT/bin/pip"
[ -f "$pip_script" ] || return 0
local shebang interp old_prefix
shebang="$(head -n 1 "$pip_script")"
case "$shebang" in '#!'*) ;; *) return 0 ;; esac
interp="${shebang#'#!'}"
interp="${interp%% *}"
case "$interp" in */bin/python*) ;; *) return 0 ;; esac
old_prefix="${interp%/bin/python*}"
if [ -z "$old_prefix" ] || [ "$old_prefix" = "$ENV_ROOT" ]; then
return 0
fi
log "env '$ENV_NAME' was relocated from $old_prefix; repairing stale paths in place"
find "$ENV_ROOT/bin" -maxdepth 1 -type f -print0 | while IFS= read -r -d '' f; do
if [ "$(head -c 2 "$f")" = '#!' ]; then
sed -i "1s|^#!$old_prefix/|#!$ENV_ROOT/|" "$f"
fi
done
local sp="$ENV_ROOT/lib/python3.8/site-packages"
if [ -d "$sp" ]; then
find "$sp" -maxdepth 1 -type f \( -name '*.pth' -o -name '*.egg-link' \) \
-exec sed -i "s|$old_prefix|$ENV_ROOT|g" {} +
fi
if [ -d "$ENV_ROOT/conda-meta" ]; then
sed -i "s|$old_prefix|$ENV_ROOT|g" "$ENV_ROOT"/conda-meta/*.json
fi
}
repair_env_prefix_if_needed

# Fix `version GLIBCXX_3.4.32 not found` on Ubuntu 24.04 by shipping a newer
# libstdc++ inside the env.
if [ -f "$LIBSTDCXX_SENTINEL" ]; then
Expand Down Expand Up @@ -135,11 +176,15 @@ else
tar -xzf "$TARBALL_PATH" -C "$ISAACGYM_HOME"
fi

if "$ENV_ROOT/bin/pip" show isaacgym >/dev/null 2>&1; then
# Use `python -m pip` rather than the bin/pip entry point so this still works
# even if that script's shebang is broken. pip show alone is not a reliable
# skip-check: it trusts a possibly stale egg-link, so also verify the import.
if "$HSGYM_PYTHON" -m pip show isaacgym >/dev/null 2>&1 && \
LD_LIBRARY_PATH="$ENV_ROOT/lib" "$HSGYM_PYTHON" -c "import isaacgym" >/dev/null 2>&1; then
log "isaacgym already installed in '$ENV_NAME', skipping pip install"
else
log "installing isaacgym (pip install -e) into '$ENV_NAME'"
"$ENV_ROOT/bin/pip" install -e "$ISAACGYM_DIR/python"
"$HSGYM_PYTHON" -m pip install -e "$ISAACGYM_DIR/python"
fi

# Step 5: self-check the import with the env's lib/ on LD_LIBRARY_PATH. The
Expand Down
59 changes: 53 additions & 6 deletions scripts/tools/setup_isaacsim_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
# * Resumable — large downloads use curl -C - so an interrupted transfer
# continues where it stopped; pip's HTTP cache covers pip downloads.
# * Isolated — UniLab code, configs, and the UniLab venv are never touched.
# * Relocation-aware — a venv is not relocatable; if ISAACSIM_HOME was moved
# since the install, stale shebang/activate/editable-finder paths are
# repaired in place instead of reinstalling multi-GB wheels.
#
# Usage:
# bash scripts/tools/setup_isaacsim_env.sh [--verify-sim]
Expand Down Expand Up @@ -78,6 +81,48 @@ exec > >(tee -a "$LOG_FILE") 2>&1
log "UNISIM_ISAACSIM_HOME=$ISAACSIM_HOME"
log "isaacsim=$ISAACSIM_VERSION isaaclab=$ISAACLAB_VERSION torch=$TORCH_VERSION+cu128"

# A venv is not relocatable: entry-point shebangs, activate scripts and the
# PEP 660 __editable__ finder modules all hard-code the install prefix. If the
# whole ISAACSIM_HOME tree was moved since the install (e.g. from the legacy
# $HOME/.unilab/isaacsim to the current default), every step marker is still
# present but pip cannot execute and isaaclab disappears from sys.path. Detect
# the stale prefix from the pip shebang and rewrite it in place; this is far
# cheaper than reinstalling multi-GB wheels.
repair_env_prefix_if_needed() {
local pip_script=$VENV_DIR/bin/pip
[[ -f $pip_script ]] || return 0
local shebang interp old_venv old_home
shebang=$(head -n 1 "$pip_script")
[[ $shebang == '#!'* ]] || return 0
interp=${shebang#'#!'}
interp=${interp%% *}
[[ $interp == */bin/python* ]] || return 0
old_venv=${interp%/bin/python*}
old_home=${old_venv%/venv}
[[ -n $old_home && $old_venv != "$VENV_DIR" ]] || return 0
log "venv was relocated from $old_home; repairing stale paths in place"
# Entry-point scripts: rewrite only the shebang line (never touch binaries).
local f
while IFS= read -r -d '' f; do
if [[ $(head -c 2 "$f") == '#!' ]]; then
sed -i "1s|^#!$old_venv/|#!$VENV_DIR/|" "$f"
fi
done < <(find "$VENV_DIR/bin" -maxdepth 1 -type f -print0)
# activate scripts carry VIRTUAL_ENV in the body, not in a shebang.
sed -i "s|$old_venv|$VENV_DIR|g" "$VENV_DIR"/bin/activate* 2>/dev/null || true
# Editable finders / stray .pth reference the IsaacLab source tree.
local sp=$VENV_DIR/lib/python$PYTHON_VERSION/site-packages
if [[ -d $sp ]]; then
find "$sp" -maxdepth 1 -type f \( -name '__editable__*_finder.py' -o -name '*.pth' \) \
-exec grep -lF "$old_home" {} + | while read -r f; do
sed -i "s|$old_home|$ISAACSIM_HOME|g" "$f"
done
fi
# Re-verify imports against the repaired env.
rm -f "$MARKER_DIR/06_verify"
}
repair_env_prefix_if_needed

# Accept the Omniverse Kit EULA non-interactively (install + any Kit launch)
export OMNI_KIT_ACCEPT_EULA=${OMNI_KIT_ACCEPT_EULA:-1}

Expand Down Expand Up @@ -116,8 +161,10 @@ step_create_venv() {
}
run_step 01_venv step_create_venv

PIP="$VENV_DIR/bin/pip"
PYTHON="$VENV_DIR/bin/python"
# Go through `python -m pip` rather than the bin/pip entry point so pip still
# works even if that script's shebang is broken (e.g. mid-relocation).
pip_cmd() { "$PYTHON" -m pip "$@"; }

# ---------------------------------------------------------------------------
# Step 1b: real cmake binary (avoids sudo; used by egl_probe's native build).
Expand All @@ -138,7 +185,7 @@ step_cmake() {
mkdir -p "$ISAACSIM_HOME/tools/bin"
ln -sfn "$dest/bin/cmake" "$ISAACSIM_HOME/tools/bin/cmake"
# drop the fragile pip-cmake entry point so it cannot shadow the real binary
"$PIP" uninstall -y cmake >/dev/null 2>&1 || true
pip_cmd uninstall -y cmake >/dev/null 2>&1 || true
}
run_step 01b_cmake step_cmake

Expand All @@ -150,15 +197,15 @@ export PATH="$ISAACSIM_HOME/tools/bin:$VENV_DIR/bin:$PATH"
# re-runs cheap if the wheel was fetched before.
# ---------------------------------------------------------------------------
run_step 02_torch \
"$PIP" install -U "torch==$TORCH_VERSION" "torchvision==$TORCHVISION_VERSION" \
pip_cmd install -U "torch==$TORCH_VERSION" "torchvision==$TORCHVISION_VERSION" \
--index-url https://download.pytorch.org/whl/cu128

# ---------------------------------------------------------------------------
# Step 3: IsaacSim from the NVIDIA PyPI index (multi-GB; cached by pip on re-run)
# ---------------------------------------------------------------------------
step_isaacsim() {
"$PIP" install pyperclip
"$PIP" install "isaacsim[all,extscache]==$ISAACSIM_VERSION" \
pip_cmd install pyperclip
pip_cmd install "isaacsim[all,extscache]==$ISAACSIM_VERSION" \
--extra-index-url https://pypi.nvidia.com
}
run_step 03_isaacsim step_isaacsim
Expand Down Expand Up @@ -192,7 +239,7 @@ run_step 04_isaaclab_src step_fetch_isaaclab
# ---------------------------------------------------------------------------
step_install_isaaclab() {
cd "$ISAACLAB_DIR"
"$PIP" install 'setuptools<81'
pip_cmd install 'setuptools<81'
echo 'setuptools<81' > build-constraints.txt
export PIP_BUILD_CONSTRAINT="$ISAACLAB_DIR/build-constraints.txt"
# Pin torch stack: pip would otherwise upgrade to a newer torch/CUDA build
Expand Down