diff mbox series

[11/20] devtool: ide-sdk: add Cargo build task

Message ID 20261026-devtool-ide-sdk-cargo-v1-11-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
Generate a Cargo build task that uses the exported recipe config and build
flags. Run it in the recipe source tree with only the SDK PATH so Cargo
uses the cross environment captured for the recipe.

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

Patch

diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index 990a3060aa..bd0bfb06ec 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -4390,6 +4390,43 @@  class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests):
         self.assertIn('rust-lang.rust-analyzer', extensions['recommendations'])
         self.assertIn('ms-vscode.cpptools', extensions['recommendations'])
 
+    def test_code_cargo_build_task(self):
+        recipe_name = "cargo-example"
+        self._check_workspace()
+        self._write_bb_config()
+        tempdir = self._devtool_ide_sdk_recipe(recipe_name, "Cargo.toml", None)
+        runCmd('devtool ide-sdk %s oe-selftest-image --ide=code '
+               '--target root@localhost --no-host-check' % recipe_name,
+               output_log=self._cmd_logger)
+
+        with open(os.path.join(tempdir, '.vscode', 'tasks.json')) as tasks_file:
+            tasks = json.load(tasks_file)['tasks']
+        build_task = next(task for task in tasks
+                          if task['label'].startswith('cargo build '))
+        cargo_config = os.path.join(
+            self.workspacedir, 'ide-sdk', recipe_name, 'cargo-config.toml')
+        self.assertEqual(build_task['command'], get_bb_var('CARGO', recipe_name))
+        self.assertEqual(
+            build_task['args'][:3], ['--config', cargo_config, 'build'])
+        self.assertIn('--features', build_task['args'])
+        self.assertIn('ide-sdk-selftest', build_task['args'])
+        self.assertEqual(set(build_task['options']['env']), {'PATH'})
+
+        build_env = os.environ.copy()
+        build_env.update(build_task['options']['env'])
+        result = subprocess.run(
+            [build_task['command']] + build_task['args'],
+            cwd=build_task['options']['cwd'], env=build_env,
+            stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+            universal_newlines=True)
+        self.assertEqual(result.returncode, 0, result.stdout)
+
+        install_task = next(
+            task for task in tasks
+            if task['label'].startswith('install && deploy-target '))
+        self.assertEqual(install_task['dependsOn'], [build_task['label']])
+
+
 class DevtoolIdeSdkKernelTests(DevtoolIdeSdkTests):
 
     @OETestTag("runqemu")
diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py
index 80314bfb89..089016c639 100644
--- a/scripts/lib/devtool/ide_plugins/ide_code.py
+++ b/scripts/lib/devtool/ide_plugins/ide_code.py
@@ -8,6 +8,7 @@ 
 import json
 import logging
 import os
+import shlex
 import shutil
 import shlex
 from devtool.ide_plugins import BuildTool, IdeBase, GdbCrossConfig, DebuggerServerModes, LldbServerConfig, get_devtool_deploy_opts, resolve_deploy_target
@@ -852,6 +853,28 @@  class IdeVSCode(IdeBase):
         IdeBase.update_json_file(
             self.dot_code_dir(modified_recipe), tasks_file, tasks_dict)
 
+    def vscode_tasks_cargo(self, args, image_recipe, modified_recipe):
+        build_task_name = "cargo build %s" % modified_recipe.recipe_id_pretty
+        cargo_config = modified_recipe.cargo_config_path
+        build_task = {
+            "label": build_task_name,
+            "type": "shell",
+            "command": modified_recipe.cargo,
+            "args": ["--config", cargo_config, "build"] +
+                     shlex.split(modified_recipe.cargo_build_flags) +
+                     shlex.split(modified_recipe.cargo_packageconfig_confargs),
+            "options": {
+                "cwd": modified_recipe.real_srctree,
+                "env": {"PATH": modified_recipe.path},
+            },
+            "group": {
+                "kind": "build",
+                "isDefault": True
+            },
+            "problemMatcher": []
+        }
+        self.vscode_tasks_binary(args, image_recipe, modified_recipe, build_task)
+
     def vscode_tasks_fallback(self, args, image_recipe, modified_recipe):
         oe_init_dir = modified_recipe.oe_init_dir
         oe_init = ". %s %s > /dev/null && " % (modified_recipe.oe_init_build_env, modified_recipe.topdir)
@@ -990,6 +1013,8 @@  class IdeVSCode(IdeBase):
             self.vscode_tasks_binary(args, image_recipe, modified_recipe)
         elif modified_recipe.build_tool == BuildTool.KERNEL_MODULE:
             self.vscode_tasks_kernel_module(args, image_recipe, modified_recipe)
+        elif modified_recipe.build_tool == BuildTool.CARGO:
+            self.vscode_tasks_cargo(args, image_recipe, modified_recipe)
         else:
             self.vscode_tasks_fallback(args, image_recipe, modified_recipe)