|
| 1 | +# Develop and Debugging Holoscan Application Natively |
| 2 | + |
| 3 | +This tutorial will guide you through the steps to set up your development environment for building and debugging your applications using Holoscan SDK natively with VS Code. |
| 4 | + |
| 5 | +Whether you are a C++ or Python developer, you can use the tutorial as a reference to set up your development environment and debug your Holoscan application. |
| 6 | + |
| 7 | +> 💡 Note: This guide is specific to the Linux development environment and is tested on Ubuntu 22.04 LTS. |
| 8 | +
|
| 9 | +## Prerequisites |
| 10 | + |
| 11 | +- [Holoscan SDK Prerequisites](https://docs.nvidia.com/holoscan/sdk-user-guide/sdk_installation.html#prerequisites) |
| 12 | +- [Visual Studio Code](https://code.visualstudio.com/) |
| 13 | +- [Holohub](https://github.com/nvidia-holoscan/holohub/) |
| 14 | + ```bash |
| 15 | + # clone the Holohub repository |
| 16 | + git clone https://github.com/nvidia-holoscan/holohub.git |
| 17 | + ``` |
| 18 | + |
| 19 | +### C++ Prerequisites |
| 20 | + |
| 21 | +To build and debug your C++ applications natively, we must first install the redistribution of the Holoscan SDK. To install Holoscan SDK using a Debian package, refer to the Debian package installation section in the [Holoscan SDK documentation](https://docs.nvidia.com/holoscan/sdk-user-guide/sdk_installation.html#instructions). |
| 22 | + |
| 23 | +- [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) extension for VS Code |
| 24 | +- [CMake](https://cmake.org/cmake/help/latest/command/install.html) 3.24.0 or higher |
| 25 | +- Ninja 1.10 or higher |
| 26 | + ```bash |
| 27 | + sudo apt update && sudo apt install ninja-build |
| 28 | + ``` |
| 29 | +- gcc 11.4 or higher |
| 30 | + ```bash |
| 31 | + sudo apt update && sudo apt install build-essential |
| 32 | + ``` |
| 33 | + |
| 34 | +### Python Prerequisites |
| 35 | + |
| 36 | +- [Python C++ Debugger](https://marketplace.visualstudio.com/items?itemName=benjamin-simmonds.pythoncpp-debug) extension for VS Code |
| 37 | +- [Python 3.10](https://www.python.org/) or higher |
| 38 | +- [Holoscan SDK PyPI Wheel](https://pypi.org/project/holoscan/) |
| 39 | + ```bash |
| 40 | + pip install holoscan |
| 41 | + ``` |
| 42 | +- (Optional) Python virtual environment of your choice |
| 43 | + |
| 44 | +## Environment Setup |
| 45 | + |
| 46 | +In this section, we walk through setting up a development environment using VS Code with some templates that we have included in this directory. A Hello World Holoscan application in C++ and Python is also included in the `cpp/` and the `python/`, respectively. |
| 47 | + |
| 48 | +### C++ |
| 49 | + |
| 50 | +The C++ example in this tutorial is pre-configured using the [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) extension in VS Code with a [CMake Preset](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) file ([CMakePresets.json](cpp/CMakePresets.json)). Once installed, VS Code should include all the CMake options in the status bar, as shown below. |
| 51 | + |
| 52 | +<figure> |
| 53 | + <img src="static/vscode-cmake-statusbar.png" alt="VS Code Status Bar" /> |
| 54 | + <figcaption>Figure 1: VS Code status bar with CMake options.</figcaption> |
| 55 | +</figure> |
| 56 | + |
| 57 | + |
| 58 | +Let's start a new instance of VS Code; run the following command from the root directory of the Holohub repository: |
| 59 | + |
| 60 | +```bash |
| 61 | +code tutorials/debugging/vscode-native/cpp |
| 62 | +``` |
| 63 | + |
| 64 | +A new instance of VS Code shall open and display the following files in the **Explorer** tab. |
| 65 | + |
| 66 | +<figure> |
| 67 | + <img src="static/vscode-cpp-files.png" alt="VS Code Hello World C++" /> |
| 68 | + <figcaption>Figure 2: VS Code Explorer showing files in the C++ Hello World sample application.</figcaption> |
| 69 | +</figure> |
| 70 | + |
| 71 | +#### Debugging |
| 72 | + |
| 73 | +The first time VS Code opens this directory, it may do one of the following actions depending on the version of VS Code and the CMake Tools extension installed: |
| 74 | + |
| 75 | +1. Prompt you to select a preset, **Debug** or **Release**. Select **Debug** to continue. This action configures CMake which creates a `build/` directory. Or, |
| 76 | +2. Automatically configures CMake with the **Debug** configure preset and creates a `build/` directory for you. |
| 77 | + |
| 78 | +If neither of these actions were performed, open the **Command Palette** from the **View** menu, or `Ctrl+Shift+P`. Select **CMake: Select Configure Preset** from the list of options and then select **Debug**. This configures CMake to build the Hello World sample application in debug mode using _g++_ as the compiler and _ninja_ as the build tool. |
| 79 | + |
| 80 | +Next, open the **Command Palette** again, and select **CMake: Build** and then select **build** from **Select a build task** dropdown. |
| 81 | +This action builds the Hello World binary and stores the artifact in `build/debug/src/hello_world`. |
| 82 | + |
| 83 | +Let's debug the Hello World application, open the [hello_world.cpp](cpp/src/hello_world.cpp#L55) file in VS Code, and set a breakpoint in the `main()` function. Switch to the **Run and Debug** tab in VS Code. Select **(gdb) Launch Hello World** from the dropdown and click **Start Debugging** icon (play button ▶️) to start debugging. VS Code should stop at the breakpoint: |
| 84 | + |
| 85 | +<figure> |
| 86 | + <img src="static/vscode-cpp-breakpoint.png" alt="VS Code Hello World C++ Breakpoint" /> |
| 87 | + <figcaption>Figure 3: VS Code hitting the breakpoint set in the C++ Hello World sample application.</figcaption> |
| 88 | +</figure> |
| 89 | + |
| 90 | +##### Step into Holoscan Source Code |
| 91 | + |
| 92 | +To step into Holoscan SDK source code, we need to clone the Holoscan SDK and create a debug build of the Holoscan SDK. First, complete the steps described in the [Building Holoscan SDK](#building-holoscan-sdk) section and then follow these steps to configure your debugging environment: |
| 93 | + |
| 94 | +1. The Holoscan SDK build process creates an `install-[arch]/` directory upon completion. Open the [CMakePresets.json](cpp/CMakePresets.json#L19) and update the `HOLOSCAN_INSTALL_DIR` variable with the `install-[arch]` path. For example: |
| 95 | + |
| 96 | + ```json |
| 97 | + "cacheVariables": { |
| 98 | + ... |
| 99 | + "HOLOSCAN_INSTALL_DIR": "/home/user/holoscan-sdk/install-x86_64" |
| 100 | + } |
| 101 | + ``` |
| 102 | + |
| 103 | + > 💡 Tip: Step 3 of the [Building Holoscan SDK](#building-holoscan-sdk) section describes how to find the Holoscan SDK installation path. |
| 104 | +
|
| 105 | +2. Open [launch.json](cpp/.vscode/launch.json#L22) and update the source map path **value** with the path to the `src/` directory of Holoscan SDK. For example: |
| 106 | + |
| 107 | + ```json |
| 108 | + "sourceFileMap": { |
| 109 | + "/workspace/holoscan-sdk/src/": "/home/user/holoscan-sdk/src" |
| 110 | + }, |
| 111 | + ``` |
| 112 | + |
| 113 | + > 💡 Tip: Change `/home/user/holoscan-sdk` to the path where you cloned the Holoscan SDK repository. |
| 114 | +
|
| 115 | +3. Clean up the existing build directory by opening the **Command Palette** and select **CMake: Clean Rebuild** and select **build**. |
| 116 | + |
| 117 | +4. Add Holoscan SDK source code to the workspace: Select **Add Folder to Workspace...** from the **File** menu. Find and select the directory where Holoscan SDK repository resides. |
| 118 | + The **Explorer** should now look like this: |
| 119 | + <figure> |
| 120 | + <img src="static/vscode-cpp-holoscan-sdk.png" alt="VS Code C++ Workspace with Holoscan SDK" /> |
| 121 | + <figcaption>Figure 4: VS Code workspace with Holoscan SDK.</figcaption> |
| 122 | + </figure> |
| 123 | + |
| 124 | +5. Open `src/core/application.cpp` from the `holoscan-sdk` folder. Find `void Application::run()` and set a breakpoint inside the function. |
| 125 | + |
| 126 | +6. Switch to the **Run and Debug** tab in VS Code. Select **(gdb) Launch Hello World** from the dropdown and click **Start Debugging** icon (play button ▶️) to start debugging. This time, VS Code should stop in the `main()` of Hello World and inside `void Application::run()`. |
| 127 | + |
| 128 | +#### Testing |
| 129 | + |
| 130 | +The C++ Hello World sample application includes a test case in the [CMakeLists.txt](./cpp/src/CMakeLists.txt#L31) file. To run this test case, ensure the **Test Preset** is set to `[Test All]` and then click the **Run CTest** button on the status bar. This action should run the test case and output the following: |
| 131 | + |
| 132 | +```bash |
| 133 | +[main] Building folder: /.../holohub/tutorials/debugging/vscode-native/cpp/build/debug |
| 134 | +[build] Starting build |
| 135 | +[proc] Executing command: /usr/local/bin/cmake --build /.../holohub/tutorials/debugging/vscode-native/cpp/build/debug --config Debug --target hello_world -- |
| 136 | +[build] ninja: no work to do. |
| 137 | +[driver] Build completed: 00:00:00.027 |
| 138 | +[build] Build finished with exit code 0 |
| 139 | +[proc] Executing command: /usr/local/bin/ctest -T test --output-on-failure --output-on-failure --stop-on-failure -R ^EXAMPLE_CPP_HELLO_WORLD_TEST$ |
| 140 | +[ctest] Site: holoscan-dev |
| 141 | +[ctest] Build name: Linux-g++ |
| 142 | +[ctest] Test project /.../holohub/tutorials/debugging/vscode-native/cpp/build/debug |
| 143 | +[ctest] Start 1: EXAMPLE_CPP_HELLO_WORLD_TEST |
| 144 | +[ctest] 1/1 Test #1: EXAMPLE_CPP_HELLO_WORLD_TEST ..... Passed 0.03 sec |
| 145 | +[ctest] |
| 146 | +[ctest] 100% tests passed, 0 tests failed out of 1 |
| 147 | +[ctest] |
| 148 | +[ctest] Total Test time (real) = 0.03 sec |
| 149 | +[ctest] CTest finished with return code 0 |
| 150 | +``` |
| 151 | + |
| 152 | +### Python |
| 153 | + |
| 154 | +The Python example resides in `tutorials/debugging/vscode-native/python`. Open it with VS Code with the following command: |
| 155 | + |
| 156 | +```bash |
| 157 | +code tutorials/debugging/vscode-native/python |
| 158 | +``` |
| 159 | + |
| 160 | +Inside VS Code, open the integrated terminal (select **Terminal** from the **View** menu) to set up a virtual environment and install the dependencies: |
| 161 | + |
| 162 | +```bash |
| 163 | +# Configure a Python virtual environment if desired, e.g., |
| 164 | +python3 -m venv .venv |
| 165 | + |
| 166 | +# Install dependencies |
| 167 | +pip install -r ./requirements.txt |
| 168 | +``` |
| 169 | + |
| 170 | +> 💡Tip: Install the Holoscan SDK PyPI package in your favorite Python virtual environment or select the **Python: Create Environment** command from the **Command Palette** to create a new virtual environment. |
| 171 | +
|
| 172 | +#### Debugging |
| 173 | + |
| 174 | +Open the [hello_world.py](python/src/hello_world.py#L54) file and set a breakpoint in the `main()` function. |
| 175 | + |
| 176 | +A launch profile, **Python Debugger**, is configured in the [launch.json](python/.vscode/launch.json). Switch to the **Run and Debug** tab to select the launch profile from the list, then click the **Start Debugging** icon (play button ▶️) to run the application. VS Code should stop at your breakpoint: |
| 177 | + |
| 178 | +<figure> |
| 179 | + <img src="static/vscode-python-breakpoint.png" alt="VS Code Hello World Python Breakpoint" /> |
| 180 | + <figcaption>Figure 5: VS Code hitting the breakpoint set in the Python Hello World sample application.</figcaption> |
| 181 | +</figure> |
| 182 | + |
| 183 | +##### Step into Holoscan Source Code |
| 184 | + |
| 185 | +To step into Holoscan SDK source code with a Python application, we need to clone the Holoscan SDK and create a debug build of the Holoscan SDK. Complete the steps described in the [Building Holoscan SDK](#building-holoscan-sdk) section and then follow these steps to configure your debugging environment: |
| 186 | + |
| 187 | +1. Open [launch.json](python/.vscode/launch.json#L22) and update `PYTHONPATH` and `LD_LIBRARY_PATH` environment variables with the path to the Holoscan SDK that we built in the previous step. For example: |
| 188 | + |
| 189 | + ```json |
| 190 | + "env": { |
| 191 | + "PYTHONPATH": "/home/user/holoscan-sdk/install-x86-64/python/lib", |
| 192 | + "LD_LIBRARY_PATH": "/home/user/holoscan-sdk/install-x86_64/lib" |
| 193 | + }, |
| 194 | + ``` |
| 195 | + > 💡 Tip: Step 3 of the [Building Holoscan SDK](#building-holoscan-sdk) section describes how to find the Holoscan SDK installation path. |
| 196 | +
|
| 197 | +2. Unlike the C++ debugger, VS Code does not support setting a `sourcemap`; therefore, we have to make a symbolic link to the `holoscan-sdk` directory that we just cloned: |
| 198 | + ```bash |
| 199 | + sudo mkdir /workspace |
| 200 | + sudo ln -s /home/user/holoscan-sdk /workspace/holoscan-sdk |
| 201 | + ``` |
| 202 | + > 💡 Tip: Change `/home/user/holoscan-sdk` to the path where you cloned the Holoscan SDK repository. |
| 203 | +
|
| 204 | +3. Add Holoscan SDK source code to the workspace: Select **Add Folder to Workspace...** from the **File** menu. Find and select the directory where Holoscan SDK repository resides. |
| 205 | + The **Explorer** should now look like this: |
| 206 | + <figure> |
| 207 | + <img src="static/vscode-python-holoscan-sdk.png" alt="VS Code C++ Workspace with Holoscan SDK" /> |
| 208 | + <figcaption>Figure 6: VS Code workspace with Holoscan SDK.</figcaption> |
| 209 | + </figure> |
| 210 | + |
| 211 | +4. Open `src/core/application.cpp` from the `holoscan-sdk` folder. Find `void Application::run()` and set a breakpoint inside the function. |
| 212 | + |
| 213 | +5. Switch to the **Run and Debug** tab in VS Code. Select **Python C++ Debugger** from the dropdown and click the **Start Debugging** icon (play button ▶️) to start debugging. This time, VS Code should stop in the `main()` function of the Hello World application and the `void Application::run()` function from Holoscan SDK. |
| 214 | + |
| 215 | + > 💡 Tip: When the debug session starts, it stops at the top of the main application file and brings up a prompt in the terminal asking for superuser access. |
| 216 | + > ```bash |
| 217 | + > Superuser access is required to attach to a process. Attaching as superuser can potentially harm your computer. Do you want to continue? [y/N] |
| 218 | + > ``` |
| 219 | + > You may answer `Y` or `y` to continue the debug session. The debugger shall now stop at the breakpoint you've set in the `application.cpp` file. |
| 220 | +
|
| 221 | +#### Testing |
| 222 | +
|
| 223 | +The Python Hello World sample application includes a test case in the [tests/](python/tests/) directory. To run the test case, ensure you have all the requirements installed from the previous [step](#python), and then run the following command: |
| 224 | +
|
| 225 | +```bash |
| 226 | +$ pytest -v |
| 227 | +
|
| 228 | +========================================================================================== test session starts ========================================================================================== |
| 229 | +platform linux -- Python 3.10.12, pytest-8.3.2, pluggy-1.5.0 -- /home/user/holohub/tutorials/debugging/vscode-native/python/.venv/bin/python |
| 230 | +cachedir: .pytest_cache |
| 231 | +rootdir: /home/user/holohub/tutorials/debugging/vscode-native/python |
| 232 | +configfile: pytest.ini |
| 233 | +collected 1 item |
| 234 | +
|
| 235 | +test_hello_world.py::test_hello_world PASSED [100%] |
| 236 | +
|
| 237 | +=========================================================================================== 1 passed in 0.03s =========================================================================================== |
| 238 | +
|
| 239 | +``` |
| 240 | +
|
| 241 | +## Building Holoscan SDK |
| 242 | +
|
| 243 | +If you plan to step into the Holoscan SDK source code when debugging your application, you must build the Holoscan SDK from the source. To do this, follow these steps: |
| 244 | +
|
| 245 | +1. Clone Holoscan SDK: |
| 246 | +
|
| 247 | + ```bash |
| 248 | + git clone --depth 1 --branch <tag> https://github.com/nvidia-holoscan/holoscan-sdk.git |
| 249 | +
|
| 250 | + # For eaxmple, to clone and checkout Holoscan version 2.2.0 |
| 251 | + git clone --depth 1 --branch v2.2.0 https://github.com/nvidia-holoscan/holoscan-sdk.git |
| 252 | + ``` |
| 253 | +
|
| 254 | + > 🔗 Link: [Holoscan SDK tags](https://github.com/nvidia-holoscan/holoscan-sdk/tags) |
| 255 | +
|
| 256 | +2. Build the Holoscan SDK in Debug mode: |
| 257 | +
|
| 258 | + ```bash |
| 259 | + cd holoscan-sdk |
| 260 | + ./run build --type debug |
| 261 | + ``` |
| 262 | +
|
| 263 | + > 💡 Tip: A comprehensive guide on how to build the Holoscan SDK is also available from the [Holoscan SDK](https://github.com/nvidia-holoscan/holoscan-sdk/blob/v2.2.0/DEVELOP.md#building-the-sdk-from-source) repository. |
| 264 | +
|
| 265 | + > 💡 Tip: To build Holoscan SDK v2.2.0 or earlier, check this [Github issue](https://github.com/nvidia-holoscan/holoscan-sdk/issues/30) for additional steps. |
| 266 | +
|
| 267 | +3. Run the following command to find the Holoscan SDK installation path, we will use it later: |
| 268 | + ```bash |
| 269 | + find $PWD -name "install-*" -type d |
| 270 | + # example output |
| 271 | + /home/user/holoscan-sdk/install-x86_64 |
| 272 | + ``` |
0 commit comments