Skip to content
Open
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
34 changes: 34 additions & 0 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"features": {
"ghcr.io/devcontainers-extra/features/apt-packages:1": {
"version": "1.0.6",
"resolved": "ghcr.io/devcontainers-extra/features/apt-packages@sha256:55c54412112da81b9381e470cdbbe55278564950d1ff536ce925b1e8e096babd",
"integrity": "sha256:55c54412112da81b9381e470cdbbe55278564950d1ff536ce925b1e8e096babd"
},
"ghcr.io/devcontainers-extra/features/cmake:1": {
"version": "1.0.0",
"resolved": "ghcr.io/devcontainers-extra/features/cmake@sha256:86e25502f6b1213a68d88e4e55c969eba0b5016b9666d216ab65f5047808bc90",
"integrity": "sha256:86e25502f6b1213a68d88e4e55c969eba0b5016b9666d216ab65f5047808bc90"
},
"ghcr.io/devcontainers-extra/features/uv:1": {
"version": "1.0.2",
"resolved": "ghcr.io/devcontainers-extra/features/uv@sha256:1ac5b9f17a9e9e745933d0ac2ecf758e06ed3da4423cd22c94cce4d482fd2dd8",
"integrity": "sha256:1ac5b9f17a9e9e745933d0ac2ecf758e06ed3da4423cd22c94cce4d482fd2dd8"
},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
"version": "1.10.0",
"resolved": "ghcr.io/devcontainers/features/docker-outside-of-docker@sha256:c2c2cf829505ead8e4892c88c31b6594ae94a2bbb209e16e1fac456c1a3a624e",
"integrity": "sha256:c2c2cf829505ead8e4892c88c31b6594ae94a2bbb209e16e1fac456c1a3a624e"
},
"ghcr.io/devcontainers/features/git-lfs:1": {
"version": "1.2.5",
"resolved": "ghcr.io/devcontainers/features/git-lfs@sha256:71c2b371cf12ab7fcec47cf17369c6f59156100dad9abf9e4c593049d789de72",
"integrity": "sha256:71c2b371cf12ab7fcec47cf17369c6f59156100dad9abf9e4c593049d789de72"
},
"ghcr.io/devcontainers/features/git:1": {
"version": "1.3.8",
"resolved": "ghcr.io/devcontainers/features/git@sha256:fd75977de13a9979000e0e78baf949adb0ca71d2398995fa22e0a36d7e7e7fe2",
"integrity": "sha256:fd75977de13a9979000e0e78baf949adb0ca71d2398995fa22e0a36d7e7e7fe2"
}
}
}
5 changes: 4 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
"ghcr.io/devcontainers/features/git-lfs:1": {},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
"ghcr.io/devcontainers-extra/features/apt-packages:1": {
"packages": "clang-format-14,libx11-dev,libxrandr-dev,libxxf86vm-dev,libgl1-mesa-dev"
"packages": "clang-format-14,libx11-dev,libxrandr-dev,libxxf86vm-dev,libgl1-mesa-dev,patchelf"
},
"ghcr.io/devcontainers-extra/features/cmake:1": {},
"ghcr.io/devcontainers-extra/features/uv:1": {}
},
"postCreateCommand": "uv tool install pre-commit && pre-commit install",
"customizations": {
"vscode": {
"settings": {
"cmake.buildDirectory": "${workspaceFolder}/build-devcontainer"
},
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cmake-tools",
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package-lock.json

# Build directories
build/
build-devcontainer/
_build/
**/build/
install/
Expand Down
47 changes: 38 additions & 9 deletions cmake/SetupPython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,46 @@ if(BUILD_PYTHON_BINDINGS)
else()
set(_venv_python "${_build_venv}/bin/python")
endif()
# Reuse an existing venv when possible. If the directory exists but the
# interpreter is missing, fail fast and require explicit cleanup.
if(EXISTS "${_build_venv}" AND NOT EXISTS "${_venv_python}")
message(FATAL_ERROR
"Found stale build venv directory at ${_build_venv}, but no interpreter at ${_venv_python}. "
"Please remove ${_build_venv} and reconfigure."
# Reuse the venv when its interpreter still runs. bin/python is an absolute
# symlink into a uv-managed Python, so it is only valid in the environment
# that created the venv.
set(_venv_usable FALSE)
if(EXISTS "${_venv_python}")
execute_process(
COMMAND "${_venv_python}" --version
RESULT_VARIABLE _venv_python_ok
OUTPUT_QUIET
ERROR_QUIET
)
if(_venv_python_ok EQUAL 0)
set(_venv_usable TRUE)
endif()
endif()
if(NOT EXISTS "${_venv_python}")

if(_venv_usable)
message(STATUS "Reusing existing build venv at ${_build_venv}")
elseif(EXISTS "${_build_venv}")
# Directory is present but its interpreter is not usable. Describe the
# actual failure: a dangling bin/python symlink (the common case when the
# venv was created in a different environment, e.g. a dev container vs the
# host, whose uv-managed Python lives elsewhere) versus an interpreter that
# is present but does not run. Only the former means the target is missing.
if(IS_SYMLINK "${_venv_python}" AND NOT EXISTS "${_venv_python}")
file(READ_SYMLINK "${_venv_python}" _venv_link_target)
string(CONCAT _venv_detail
"Its interpreter symlink is broken: ${_venv_python} -> "
"${_venv_link_target} (target does not exist). This build venv was "
"created in a different environment whose uv-managed Python lives "
"elsewhere.")
else()
set(_venv_detail "Its interpreter ${_venv_python} is missing or does not run.")
endif()
message(FATAL_ERROR
"Build venv at ${_build_venv} has no working Python interpreter. "
"${_venv_detail}\n"
"Remove the build directory ${CMAKE_BINARY_DIR} (or run 'cmake --fresh') "
"and reconfigure to recreate the venv for this environment.")
else()
execute_process(
COMMAND "${UV_EXECUTABLE}" venv --python "${Python3_EXECUTABLE}" "${_build_venv}"
RESULT_VARIABLE _venv_ok
Expand All @@ -167,8 +198,6 @@ if(BUILD_PYTHON_BINDINGS)
if(NOT _venv_ok EQUAL 0)
message(FATAL_ERROR "Failed to create build venv: ${_venv_err}")
endif()
else()
message(STATUS "Reusing existing build venv at ${_build_venv}")
endif()
execute_process(
COMMAND "${UV_EXECUTABLE}" pip install --python "${_venv_python}" "numpy>=2.0"
Expand Down
49 changes: 49 additions & 0 deletions docs/source/getting_started/build_from_source/devcontainer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.. SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
.. SPDX-License-Identifier: Apache-2.0

Dev Container (VS Code)
=======================

.. admonition:: Scope

The dev container is intended for **development and unit testing only** — not for running a
production teleop session.

The repository ships a :code-file:`.devcontainer/devcontainer.json` that pre-installs all build
dependencies and VS Code extensions, so you can configure and build without installing anything on
your host machine. See the
`VS Code Dev Containers documentation <https://code.visualstudio.com/docs/devcontainers/containers>`_
for a full overview of the workflow.

Prerequisites
-------------

- `Docker <https://docs.docker.com/get-docker/>`_ running on the host
- `VS Code <https://code.visualstudio.com/>`_ with the
`Dev Containers extension <https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers>`_
(``ms-vscode-remote.remote-containers``) installed

Usage
-----

1. Open the repository folder in VS Code.
2. When prompted *"Reopen in Container"*, click it — or open the Command Palette
(:kbd:`Ctrl+Shift+P`) and run **Dev Containers: Reopen in Container**.
3. VS Code rebuilds the container (first time only) and reopens the workspace inside it.
4. Use the CMake Tools sidebar to configure and build. The build directory is set to
``build-devcontainer`` to keep it separate from any host build.

What's included
---------------

The container provides:

- Ubuntu 22.04 base image with ``build-essential``, ``cmake``, ``uv``,
``clang-format-14``, and the X11/GL headers required by Isaac Teleop
- ``git`` and ``git-lfs``
- ``docker-outside-of-docker`` so Docker commands reach the host daemon
- VS Code extensions: C/C++ IntelliSense, CMake Tools, Python, CMake syntax highlighting
- ``pre-commit`` hooks installed automatically on container creation

After the container starts, follow the normal :ref:`configure and build steps <one-time-setup>`
— all required tools are already present.
2 changes: 2 additions & 0 deletions docs/source/getting_started/build_from_source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ examples. The instructions align with the project's CMake configuration and the
.. admonition:: Next Steps

- To build and serve the **WebXR client** locally, see :doc:`webxr`.
- To build inside VS Code without installing dependencies on the host, see :doc:`devcontainer`.

Prerequisites
-------------
Expand Down Expand Up @@ -332,6 +333,7 @@ based on the Python version. Note that ``pip`` and ``uv pip`` has slightly diff
:hidden:

webxr
devcontainer

..
References
Expand Down
Loading