| .. _module-pw_ide-bazel-usage: |
| |
| ================= |
| Code intelligence |
| ================= |
| .. pigweed-module-subpage:: |
| :name: pw_ide |
| |
| The Pigweed Visual Studio Code extension bridges the build system and ``clangd`` |
| to provide the smoothest possible C++ embedded development system. For |
| background on the tools and approaches Pigweed uses, check out the |
| :ref:`design docs<module-pw_ide-contributing-design-cpp>`. For Rust code |
| intelligence, see :ref:`module-pw_ide-bazel-rust`. This doc is a |
| user guide to the way those concepts are applied in Visual Studio Code. |
| |
| ---------------- |
| Target discovery |
| ---------------- |
| Pigweed IDE will discover build targets for Bazel, GN and CMake builds |
| automatically, as well as any other targets described by compilation databases |
| produced by other means. |
| |
| In general, the process of discovering and processing build targets is triggered |
| by running the :ref:`Refresh Compile Commands<module-pw_ide-bazel-commands-refresh-compile-commands>` |
| command. See below for build system-specific details. |
| |
| .. tab-set:: |
| |
| .. tab-item:: Bazel |
| |
| Pigweed IDE generates ``clangd``-compatible compilation databases for |
| your project's build targets defined by ``pw_compile_commands_generator`` |
| targets in your ``BUILD.bazel`` file. |
| |
| .. tip:: |
| |
| For instructions on configuring and using Rust code intelligence with |
| ``rust-analyzer``, see :ref:`module-pw_ide-bazel-rust`. |
| |
| **Fixed Compile Command Generation** |
| |
| To ensure a consistent set of compilation databases, you can use the |
| ``pw_compile_commands_generator`` rule in your top-level ``BUILD.bazel`` |
| file. This provides a declarative way to define and group build targets |
| for which to generate compile commands. ``pw_compile_commands_generator`` |
| targets must be run via ``bazel run`` to generate updated compile commands |
| databases. |
| |
| .. note:: |
| |
| Each instance of ``pw_compile_commands_generator`` is intended to |
| represent a unique target platform or build configuration. |
| |
| This method provides wide code intelligence coverage by analyzing all |
| targets specified in the generator target. It ensures that code |
| intelligence is available for all configured platforms without needing to |
| build them first. |
| |
| Example configuration: |
| |
| .. code-block:: bazel |
| |
| load( |
| "@pigweed//pw_ide/bazel/compile_commands:pw_compile_commands_generator.bzl", |
| "pw_compile_commands_generator", |
| ) |
| |
| # Creates a set of compile command databases that merges |
| # all of the databases produced by its deps. |
| pw_compile_commands_generator( |
| name = "update_compile_commands", |
| deps = [ |
| ":update_host_compile_commands", |
| ":update_rp2040_compile_commands", |
| ], |
| ) |
| |
| pw_compile_commands_generator( |
| name = "update_host_compile_commands", |
| display_name = "Host C++", |
| platform = "@bazel_tools//tools:host_platform", |
| target_patterns = [ |
| "//...", |
| ], |
| ) |
| |
| pw_compile_commands_generator( |
| name = "update_rp2040_compile_commands", |
| display_name = "RP2040", |
| platform = "//targets/rp2040", |
| target_patterns = [ |
| "//...", |
| ], |
| ) |
| |
| **Generator Rule Arguments** |
| |
| The ``pw_compile_commands_generator`` rule supports the following main |
| arguments: |
| |
| * ``target_patterns``: List of Bazel target patterns for C/C++ compilation |
| database generation (used by ``clangd``). |
| |
| * ``platform``: The Bazel target platform to evaluate when collecting |
| C/C++ target patterns. |
| |
| * ``config``: Optional Bazel build configuration name to use for |
| compilation and platform inference. |
| |
| * ``bazel_args``: Optional list of extra Bazel command-line arguments |
| (such as custom flags or build configs) used when building platforms or |
| evaluating target patterns. |
| |
| * ``display_name``: Optional human-readable label shown in the Pigweed |
| Visual Studio Code target selection panel. |
| |
| * ``symlink_prefix``: Custom symlink prefix if your Bazel workspace uses |
| the ``--symlink_prefix`` flag. |
| |
| **Custom Symlink Prefixes** |
| |
| By default, Bazel creates symlinks like ``bazel-out`` and ``external`` in |
| your workspace root to point to the build output and external |
| dependencies. ``pw_ide`` utilizes these symlinks to generate **relative |
| paths** (e.g., ``bazel-out/...``) in the resulting compilation databases. |
| Relative paths ensure that the compilation database remains portable and |
| correct across different machines and build environments. |
| |
| If you use Bazel's ``--symlink_prefix`` flag (e.g., to support multiple |
| concurrent builds in the same workspace), Bazel will create these |
| symlinks with a custom name (e.g. ``out/out`` instead of ``bazel-out``). |
| If ``pw_ide`` is unaware of this prefix, it may fail to find the |
| necessary symlinks and fall back to using absolute paths, which are |
| not portable and can cause issues with code intelligence tools. |
| |
| You can inform ``pw_ide`` of your custom prefix using the |
| ``symlink_prefix`` attribute: |
| |
| .. code-block:: bazel |
| |
| pw_compile_commands_generator( |
| name = "update_custom_prefix_commands", |
| symlink_prefix = "out/", # Match your Bazel --symlink_prefix |
| target_patterns = [ |
| "//...", |
| ], |
| ) |
| |
| Example usage: |
| |
| .. code-block:: console |
| |
| $ bazel run //:update_compile_commands |
| |
| .. tab-item:: GN |
| |
| GN :ref:`can be configured<module-pw_ide-contributing-design-cpp-gn>` to generate a |
| compilation database whenever ``gn gen`` is run. Pigweed IDE will find |
| that file when :ref:`Refresh Compile Commands<module-pw_ide-bazel-commands-refresh-compile-commands>` |
| is run and make those targets available for code analysis. |
| |
| Right now, this is a manual process; if the compilation databases need to |
| be updated, you have to run ``gn gen`` and then |
| :ref:`Refresh Compile Commands<module-pw_ide-bazel-commands-refresh-compile-commands>`. |
| |
| .. tab-item:: CMake |
| |
| CMake :ref:`can be configured<module-pw_ide-contributing-design-cpp-cmake>` to generate |
| compilation databases during its build. Pigweed IDE will find those files |
| when :ref:`Refresh Compile Commands<module-pw_ide-bazel-commands-refresh-compile-commands>` |
| is run and make those targets available for code analysis. |
| |
| If you have a CMake build watcher running, then the compilation databases |
| will update automatically in response to your code changes without the |
| need to run :ref:`Refresh Compile Commands<module-pw_ide-bazel-commands-refresh-compile-commands>`. |
| The only time you would need to manually run that command is if build |
| targets were added or removed from the build. |
| |
| ------------------------------------------------- |
| Selecting a target platform for code intelligence |
| ------------------------------------------------- |
| Pigweed IDE allows you to inspect, generate, and switch C/C++ code |
| intelligence targets (used by ``clangd``) directly from the Visual Studio |
| Code interface. For Rust targets, see |
| :ref:`module-pw_ide-bazel-rust`. |
| |
| Target selection panel |
| ====================== |
| The recommended way to manage compile commands is through the **Pigweed** |
| extension panel in Visual Studio Code (accessible from the Activity Bar icon). |
| |
| Under **Select or generate compile commands**, locate the **C++ Targets** |
| table (for Rust targets, see |
| :ref:`module-pw_ide-bazel-rust`). Each target row |
| displays: |
| |
| * **Target**: The display name of the target platform (configured via |
| ``display_name`` in your generator target). |
| * **Last generated at**: The timestamp when compile commands were last generated |
| for this target (e.g., ``1 month ago`` or ``Never``). |
| * **Action**: A button to **Generate** (if never generated) or **Regenerate** |
| the compile commands for that target. |
| |
| Clicking **Generate** or **Regenerate** triggers generation of the compilation |
| database for that target and automatically selects it as the active target for |
| code intelligence. |
| |
| Selecting a C++ target configures ``clangd`` with the generated |
| ``compile_commands.json`` for that platform. Note that C++ and Rust target |
| platforms are selected and managed independently. See |
| :ref:`module-pw_ide-bazel-rust` for Rust |
| target selection details. |
| |
| Once compile commands are generated and selected, step **2. Enjoy code |
| intelligence** updates to confirm that code intelligence is active. |
| |
| Status bar and command palette |
| ============================== |
| The currently-selected target platform is also displayed in the Visual |
| Studio Code status bar: |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-status-bar-target.png |
| :alt: Visual Studio Code screenshot showing the target status bar item |
| |
| You can click the status bar item to select a new target platform from a dropdown |
| list at the top of the screen. |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-dropdown-select-target.png |
| :alt: Visual Studio Code screenshot showing the target selector |
| |
| |
| |
| No automatic process is perfect, and if an error occurs during the refresh |
| process, that will be indicated with this icon in the status bar: |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-status-bar-fault.png |
| :alt: Visual Studio Code screenshot showing the target status bar item in an |
| error state |
| |
| You can click the status bar item to trigger a retry, or you can |
| :ref:`open the output panel<module-pw_ide-bazel-commands-open-output-panel>` |
| to get more details about the error. |
| |
| .. note:: |
| |
| * You can always trigger a manual compilation database refresh by running |
| :ref:`Pigweed: Refresh Compile Commands<module-pw_ide-bazel-commands-refresh-compile-commands>`. |
| |
| * If you don't want to use the automatic refresh process, you can |
| :ref:`disable it<module-pw_ide-bazel-configuration-disable-compile-commands-file-watcher>`. |
| |
| ---------------------------------- |
| Inactive and orphaned source files |
| ---------------------------------- |
| As discussed in the :ref:`design docs<module-pw_ide-contributing-design-cpp>`, some source |
| files will be compiled in several different targets, possibly with different |
| compiler and linker options. Likewise, some files may not be compiled as part |
| of a particular selected target, perhaps because the file is not relevant to |
| the target (for example, hardware support implementations for a host simulator |
| target). Finally, some source files may not be compiled by *any* defined target |
| group, either because those files have not yet been brought into the build |
| graph, or because none of the defined target platforms contain a target that builds |
| that source file. |
| |
| We need to care about this because ``clangd`` tries to be helpful in a way that |
| is very counterproductive in Pigweed projects: If it encounters a file but |
| cannot find a corresponding compile command in the compilation database, it |
| will *infer* a compile command for that file from other similar files that *are* |
| in the compilation database. |
| |
| Since the compilation databases that Pigweed generates are specifically |
| engineered to only include compile commands pertinent to the selected target |
| group, the *inferred* code intelligence ``clangd`` provides for other files |
| is invalid. So the Pigweed extension provides mechanisms to exclude those files |
| from ``clangd`` and prevent misleading code intelligence information. |
| |
| .. glossary:: |
| |
| Active source file |
| A source file that is built in the currently-selected target platform |
| |
| Inactive source file |
| A source file that is *not* built in the currently-selected target platform |
| |
| Orphaned source file |
| A source file that is not built by *any* defined target platforms |
| |
| Disabling ``clangd`` for inactive and orphaned files |
| ==================================================== |
| By default, Pigweed will disable ``clangd`` for inactive and orphaned files to |
| prevent inaccurate and distracting information from appearing in the editor. |
| You can see that ``clangd`` is disabled for those files when you see this icon |
| in the status bar: |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-inactive-clangd-disabled.png |
| :alt: Visual Studio Code screenshot showing code intelligence disabled for |
| inactive files |
| |
| You can click the icon to *enable* ``clangd`` for all files, regardless of |
| whether they are in the current target's build graph or not. That state will be |
| indicated with this icon: |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-inactive-clangd-enabled.png |
| :alt: Visual Studio Code screenshot showing code intelligence enabled for |
| inactive files |
| |
| You can click it again to toggle it back to the default state. |
| |
| File status indicators |
| ====================== |
| The Visual Studio Code explorer (file tree) displays an indicator next to |
| inactive and orphaned files to help you understand which files will not have |
| code intelligence. These indicators will change as you change targets and as |
| you change the build graph. |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-inactive-file-indicators.png |
| :alt: Visual Studio Code screenshot file indicators for inactive and |
| orphaned files |
| :figwidth: 250 |
| |
| Inactive files are indicated like this: |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-inactive-file-indicators-inactive.png |
| :alt: Visual Studio Code screenshot file indicators for inactive files |
| :figwidth: 250 |
| |
| Orphaned files are indicated like this: |
| |
| .. figure:: https://www.gstatic.com/pigweed/vsc-inactive-file-indicators-orphaned.png |
| :alt: Visual Studio Code screenshot file indicators for orphaned files |
| :figwidth: 250 |
| |
| Note that the colors may vary depending on your Visual Studio Code theme. |
| |
| .. tip:: |
| |
| By default, file status indicators will be shown even if ``clangd`` is |
| enabled for all files. You can change this behavior with |
| :ref:`this setting<module-pw_ide-bazel-configuration-hide-inactive-file-indicators>`. |