diff mbox series

[07/20] devtool: ide-sdk: configure Cargo C++ IntelliSense

Message ID 20261026-devtool-ide-sdk-cargo-v1-7-d4504e124d07@savoirfairelinux.com
State New
Headers show
Series devtool: ide-sdk: add support for Rust recipes | expand

Commit Message

Enguerrand de Ribaucourt Oct. 26, 2026, 8:55 a.m. UTC
Recommend cpptools for Cargo's native C/C++ code and configure its cross
compiler, sysroot, and include path. Reuse the shared architecture mapping
so IntelliSense matches the recipe environment. The selftest checks the
generated compiler and sysroot settings.

AI-Generated: Uses GitHub Copilot
Signed-off-by: Enguerrand de Ribaucourt <enguerrand.de-ribaucourt@savoirfairelinux.com>
---
 meta/lib/oeqa/selftest/cases/devtool.py     | 27 ++++++++++++++++++++++++++
 scripts/lib/devtool/ide_plugins/ide_code.py | 30 ++++++++++++++++++++---------
 2 files changed, 48 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index d1e15d0180..990a3060aa 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -4353,15 +4353,42 @@  class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests):
             settings = json.load(settings_file)
         with open(os.path.join(tempdir, '.vscode', 'extensions.json')) as extensions_file:
             extensions = json.load(extensions_file)
+        with open(os.path.join(tempdir, '.vscode', 'c_cpp_properties.json')) as properties_file:
+            properties = json.load(properties_file)['configurations'][0]
+        recipe_sysroot = os.path.realpath(get_bb_var('RECIPE_SYSROOT', recipe_name))
         cargo_config = os.path.join(
             self.workspacedir, 'ide-sdk', recipe_name, 'cargo-config.toml')
         self.assertExists(cargo_config, 'Cargo config was not generated')
+        with open(cargo_config) as cargo_config_file:
+            cargo_config_text = cargo_config_file.read()
+        cargo_class_env = {
+            'LIBGIT2_NO_VENDOR': '1',
+            'LIBSSH2_SYS_USE_PKG_CONFIG': '1',
+            'LIBSQLITE3_SYS_USE_PKG_CONFIG': '1',
+            'OPENSSL_NO_VENDOR': '1',
+            'PKG_CONFIG_ALLOW_CROSS': '1',
+            'PKG_CONFIG_ALL_DYNAMIC': '1',
+            'SYSTEM_DEPS_BUILD_INTERNAL': 'never',
+            'ZSTD_SYS_USE_PKG_CONFIG': '1',
+        }
+        for name, value in cargo_class_env.items():
+            self.assertIn(
+                '%s = { value = "%s", force = true }' % (name, value),
+                cargo_config_text)
         self.assertEqual(settings['rust-analyzer.cargo.configPath'], cargo_config)
         self.assertEqual(
             settings['rust-analyzer.cargo.target'],
             get_bb_var('RUST_HOST_SYS', recipe_name))
         self.assertNotIn('rust-analyzer.cargo.extraEnv', settings)
+        self.assertEqual(
+            properties['compilerPath'],
+            shlex.split(get_bb_var('RUST_TARGET_CXX', recipe_name))[0])
+        self.assertEqual(
+            properties['compilerArgs'], ['--sysroot=' + recipe_sysroot])
+        self.assertIn(os.path.join(recipe_sysroot, 'usr', 'include'),
+                      properties['includePath'])
         self.assertIn('rust-lang.rust-analyzer', extensions['recommendations'])
+        self.assertIn('ms-vscode.cpptools', extensions['recommendations'])
 
 class DevtoolIdeSdkKernelTests(DevtoolIdeSdkTests):
 
diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py
index 95ef472ed4..fcd2e5b5fe 100644
--- a/scripts/lib/devtool/ide_plugins/ide_code.py
+++ b/scripts/lib/devtool/ide_plugins/ide_code.py
@@ -9,6 +9,7 @@  import json
 import logging
 import os
 import shutil
+import shlex
 from devtool.ide_plugins import BuildTool, IdeBase, GdbCrossConfig, DebuggerServerModes, LldbServerConfig, get_devtool_deploy_opts, resolve_deploy_target
 
 logger = logging.getLogger('devtool')
@@ -315,7 +316,10 @@  class IdeVSCode(IdeBase):
     def vscode_extensions(self, modified_recipe):
         recommendations = []
         if modified_recipe.build_tool is BuildTool.CARGO:
-            recommendations.append("rust-lang.rust-analyzer")
+            recommendations += [
+                "rust-lang.rust-analyzer",
+                "ms-vscode.cpptools",
+            ]
         # clangd (matched to the recipe's real cross compiler via
         # compile_commands.json) replaces cpptools as the IntelliSense provider
         # when selected via IDE_SDK_INTELLISENSE (defaults to clangd for the
@@ -358,18 +362,26 @@  class IdeVSCode(IdeBase):
         }
         if modified_recipe.build_tool is BuildTool.CMAKE:
             properties_dict["configurationProvider"] = "ms-vscode.cmake-tools"
-        elif modified_recipe.build_tool is BuildTool.MESON:
-            # configurationProvider = "mesonbuild.mesonbuild" does not work because
-            # the cross-compiler is not in PATH and omits the sysroot by default.
+        elif modified_recipe.build_tool in (BuildTool.MESON, BuildTool.CARGO):
             compiler_type = 'clang' if modified_recipe.toolchain == 'clang' else 'gcc'
             intelli_arch = arch_map.get(modified_recipe.target_arch, 'x64')
-            properties_dict["compilerPath"] = os.path.join(
-                modified_recipe.staging_bindir_toolchain,
-                modified_recipe.cxx.split()[0])
+            if modified_recipe.build_tool is BuildTool.MESON:
+                # configurationProvider = "mesonbuild.mesonbuild" does not work
+                # because the cross-compiler is not in PATH and omits the sysroot.
+                properties_dict["compilerPath"] = os.path.join(
+                    modified_recipe.staging_bindir_toolchain,
+                    modified_recipe.cxx.split()[0])
+                properties_dict["compileCommands"] = os.path.join(
+                    modified_recipe.b, 'compile_commands.json')
+            else:
+                properties_dict["compilerPath"] = shlex.split(
+                    modified_recipe.cargo_env['CXX'])[0]
+                properties_dict["includePath"] = [
+                    "${workspaceFolder}/**",
+                    os.path.join(modified_recipe.recipe_sysroot, "usr", "include")
+                ]
             properties_dict["compilerArgs"] = [
                 "--sysroot=" + modified_recipe.recipe_sysroot]
-            properties_dict["compileCommands"] = os.path.join(
-                modified_recipe.b, 'compile_commands.json')
             properties_dict["intelliSenseMode"] = "linux-%s-%s" % (compiler_type, intelli_arch)
         elif modified_recipe.build_tool is BuildTool.KERNEL_MODULE:
             # Using e.g. configurationProvider = "ms-vscode.makefile-tools" was not successful