From patchwork Mon Oct 26 08:55:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101947 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38522.1793004972511885507 for ; Mon, 26 Oct 2026 01:56:13 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=R2JKZEU8; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 465953D8187E; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id 87ZqttwwqyfR; Mon, 26 Oct 2026 04:56:10 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 0B77D3D81844; Mon, 26 Oct 2026 04:56:10 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 0B77D3D81844 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004970; bh=1rpQc12OOWrD8JOmJ630Coke86oLKyouFl1NFNc+qBY=; h=From:Date:MIME-Version:Message-Id:To; b=R2JKZEU8QASwDSueBk0JGDvQylJJ0IsEjxasGiOH1D2zD8jfUpBf7Vn8cDzsD+zr0 NsGOjrv6cHOklMliz4V/99BlL1njNEZSMP0iU08k+THauj7u6Ctj78k/KO9XeqC2pN G+iJsb6lhyXojdDMRFZyOTvzGy2lhyHwqfI4mPsIfYMCtEjBa+Kfzc9UrAjbTrGyF4 Yb+Sz0yELJdzKB+j6Z5IpW/5cDTpVuT90rPVkp/X2tR7xXmzF2v+K2DPFSTL+hLDG/ Izqat6DcFwijUrgL6BK1hWZS5tDb+9bPyVHbAQks9geKPeNj0QD/ZI7QnYXE6bkbpy bgbQ3GGrkGU2Q== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id 69gS3SdRq1fH; Mon, 26 Oct 2026 04:56:09 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 77FEC3D81863; Mon, 26 Oct 2026 04:56:09 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:39 +0100 Subject: [PATCH 01/20] cargo-example: add minimal selftest fixture MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-1-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:14 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248639 Add a minimal cargo recipe to demonstrate the ide-sdk configuration for Rust in the selftests. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta-selftest/recipes-test/rust/cargo-example.bb | 15 +++++++++++++++ .../recipes-test/rust/cargo-example/Cargo.lock | 5 +++++ .../recipes-test/rust/cargo-example/Cargo.toml | 8 ++++++++ .../recipes-test/rust/cargo-example/build.rs | 20 ++++++++++++++++++++ .../recipes-test/rust/cargo-example/src/main.rs | 11 +++++++++++ 5 files changed, 59 insertions(+) diff --git a/meta-selftest/recipes-test/rust/cargo-example.bb b/meta-selftest/recipes-test/rust/cargo-example.bb new file mode 100644 index 0000000000..cca56d8d81 --- /dev/null +++ b/meta-selftest/recipes-test/rust/cargo-example.bb @@ -0,0 +1,15 @@ +SUMMARY = "Minimal Cargo application for devtool ide-sdk selftests" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +SRC_URI = "file://Cargo.toml \ + file://Cargo.lock \ + file://build.rs \ + file://src/main.rs \ + " + +S = "${UNPACKDIR}" + +inherit cargo + +CARGO_BUILD_FLAGS:append = " --features ide-sdk-selftest" diff --git a/meta-selftest/recipes-test/rust/cargo-example/Cargo.lock b/meta-selftest/recipes-test/rust/cargo-example/Cargo.lock new file mode 100644 index 0000000000..27cb8ffd40 --- /dev/null +++ b/meta-selftest/recipes-test/rust/cargo-example/Cargo.lock @@ -0,0 +1,5 @@ +version = 3 + +[[package]] +name = "cargo-example" +version = "0.1.0" diff --git a/meta-selftest/recipes-test/rust/cargo-example/Cargo.toml b/meta-selftest/recipes-test/rust/cargo-example/Cargo.toml new file mode 100644 index 0000000000..e8a2e1dde4 --- /dev/null +++ b/meta-selftest/recipes-test/rust/cargo-example/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "cargo-example" +version = "0.1.0" +edition = "2021" + +[features] +# Used only to verify that ide-sdk forwards recipe Cargo features to its task. +ide-sdk-selftest = [] diff --git a/meta-selftest/recipes-test/rust/cargo-example/build.rs b/meta-selftest/recipes-test/rust/cargo-example/build.rs new file mode 100644 index 0000000000..f0733b3d38 --- /dev/null +++ b/meta-selftest/recipes-test/rust/cargo-example/build.rs @@ -0,0 +1,20 @@ +use std::env; + +// Fail the selftest build if Cargo does not receive BitBake's cross environment. +fn main() { + let target_cc = env::var("CC").expect("Cargo config should set target CC"); + assert!(target_cc.ends_with("/target-rust-cc"), "unexpected CC: {target_cc}"); + + let host_cc = env::var("HOST_CC").expect("Cargo config should set host CC"); + assert!(host_cc.ends_with("/build-rust-cc"), "unexpected HOST_CC: {host_cc}"); + + assert!( + env::var_os("RUST_TARGET_PATH").is_some(), + "Cargo config should set the OE Rust target path", + ); + assert_eq!( + env::var("PKG_CONFIG_ALLOW_CROSS").as_deref(), + Ok("1"), + "Cargo config should allow cross pkg-config", + ); +} diff --git a/meta-selftest/recipes-test/rust/cargo-example/src/main.rs b/meta-selftest/recipes-test/rust/cargo-example/src/main.rs new file mode 100644 index 0000000000..7066010f51 --- /dev/null +++ b/meta-selftest/recipes-test/rust/cargo-example/src/main.rs @@ -0,0 +1,11 @@ +fn fibonacci(n: u32) -> u32 { + match n { + 0 => 0, + 1 => 1, + _ => fibonacci(n - 1) + fibonacci(n - 2), + } +} + +fn main() { + println!("fibonacci={}", fibonacci(4)); +} From patchwork Mon Oct 26 08:55:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101948 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38880.1793004973001292519 for ; Mon, 26 Oct 2026 01:56:13 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=xBe+4q4s; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 0C8003D81844; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id 3DScaZgXatwP; Mon, 26 Oct 2026 04:56:10 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id A48CA3D81863; Mon, 26 Oct 2026 04:56:10 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com A48CA3D81863 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004970; bh=bZO4lFWWoB6SCEXJqzw0uMjNK2xxOjkmqZECd7seGDE=; h=From:Date:MIME-Version:Message-Id:To; b=xBe+4q4sWGpx7GIrp0wQjtCx3BRtbSg3U/zNX7jBtNJIjFsN4/nDQtv8j5HsLuIPE p+tNLbglo11LGBDe/V3pABx7uwGAqE0mWkswMsNOk1bYl/TBDXLdY0uhGZhn0PG85P Oy0sTYa/SWFjGW1dX43o1dcSLl9gSOT82cu6AO3mJaLMycqjgKRB4uyBygQIiSKZf4 Kiq/sla9VG3OST1TSdtOYq2/dZF7gtGiRdHl6EVGB4jmtgV25VjZkyAHCwNdavmwsM HQNZOQKEUpoxbQoTc8zR0iyw0nXRslqfBeVeC+6YIyVn2r1SNGp8m87qvhemRakdMY f95g3F9VHSgIw== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id zmbLpjLkpE1B; Mon, 26 Oct 2026 04:56:10 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 1B76A3D81886; Mon, 26 Oct 2026 04:56:10 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:40 +0100 Subject: [PATCH 02/20] devtool: ide-sdk: capture Cargo cross environment MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-2-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:23 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248640 Capture Cargo target and host compiler settings, recipe Cargo state, and package configuration to generate IDE settings. Rust source paths use Cargo RUSTFLAGS and TARGET_DBGSRC_DIR because Rust does not use compiler DEBUG_PREFIX_MAP. Mirror the -sys and pkg-config exports from cargo_common.bbclass so generated Cargo config matches OE's system-library behavior. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_plugins/__init__.py | 1 + scripts/lib/devtool/ide_sdk.py | 57 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/scripts/lib/devtool/ide_plugins/__init__.py b/scripts/lib/devtool/ide_plugins/__init__.py index 7841bc37b9..10fcde471f 100644 --- a/scripts/lib/devtool/ide_plugins/__init__.py +++ b/scripts/lib/devtool/ide_plugins/__init__.py @@ -33,6 +33,7 @@ class BuildTool(Enum): UNDEFINED = auto() CMAKE = auto() MESON = auto() + CARGO = auto() KERNEL_MODULE = auto() @property diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 9faf041957..e686dbcff8 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -877,6 +877,15 @@ class RecipeModified: self.extra_oemake = None self.kernel_cc = None self.staging_kernel_dir = None + # Cargo application + self.cargo = None + self.cargo_target = None + self.cargo_linker = None + self.cargo_home = None + self.cargo_build_flags = None + self.cargo_packageconfig_confargs = None + self.cargo_rustflags = None + self.cargo_env = None # Populated after bitbake built all the recipes self._installed_binaries = None @@ -1032,6 +1041,54 @@ class RecipeModified: self.extra_oemeson = recipe_d.getVar('EXTRA_OEMESON') self.meson_cross_file = recipe_d.getVar('MESON_CROSS_FILE') self.build_tool = BuildTool.MESON + elif bb.data.inherits_class('cargo', recipe_d): + self.cargo = recipe_d.getVar('CARGO') or 'cargo' + self.cargo_target = recipe_d.getVar('RUST_HOST_SYS') + self.cargo_linker = recipe_d.getVar('CARGO_RUST_TARGET_CCLD') + self.cargo_home = recipe_d.getVar('CARGO_HOME') + self.cargo_build_flags = recipe_d.getVar('CARGO_BUILD_FLAGS') or '' + self.cargo_packageconfig_confargs = recipe_d.getVar( + 'PACKAGECONFIG_CONFARGS') or '' + self.cargo_rustflags = recipe_d.getVar('RUSTFLAGS') or '' + # Rust DWARF paths need remapping to the target debug-source path + # so LLDB can resolve files after the source tree is relocated. + target_dbgsrc_dir = recipe_d.getVar('TARGET_DBGSRC_DIR') + if target_dbgsrc_dir: + source_map = '--remap-path-prefix=%s=%s' % ( + self.real_srctree, target_dbgsrc_dir) + self.cargo_rustflags = '%s %s' % ( + self.cargo_rustflags, shlex.quote(source_map)) + # This environment feeds the generated Cargo config and the C/C++ + # IntelliSense settings; build tasks themselves only need PATH. + self.cargo_env = self.exported_vars.copy() + self.cargo_env.update({ + 'CC': recipe_d.getVar('RUST_TARGET_CC'), + 'CXX': recipe_d.getVar('RUST_TARGET_CXX'), + 'CFLAGS': recipe_d.getVar('CFLAGS'), + 'CXXFLAGS': recipe_d.getVar('CXXFLAGS'), + 'AR': recipe_d.getVar('AR'), + 'TARGET_CC': recipe_d.getVar('RUST_TARGET_CC'), + 'TARGET_CXX': recipe_d.getVar('RUST_TARGET_CXX'), + 'TARGET_CFLAGS': recipe_d.getVar('CFLAGS'), + 'TARGET_CXXFLAGS': recipe_d.getVar('CXXFLAGS'), + 'TARGET_AR': recipe_d.getVar('AR'), + 'HOST_CC': recipe_d.getVar('RUST_BUILD_CC'), + 'HOST_CXX': recipe_d.getVar('RUST_BUILD_CXX'), + 'HOST_CFLAGS': recipe_d.getVar('BUILD_CFLAGS'), + 'HOST_CXXFLAGS': recipe_d.getVar('BUILD_CXXFLAGS'), + 'HOST_AR': recipe_d.getVar('BUILD_AR'), + # Match cargo_common.bbclass so Cargo -sys crates use OE's + # staged libraries through pkg-config instead of vendoring. + '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', + }) + self.build_tool = BuildTool.CARGO elif bb.data.inherits_class('module', recipe_d): self.build_tool = BuildTool.KERNEL_MODULE self.wants_gdbserver = False From patchwork Mon Oct 26 08:55:41 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101957 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38523.1793004973620930012 for ; Mon, 26 Oct 2026 01:56:13 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=Iks9K5J7; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 9F76A3D818BD; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id PpGGN_SvsoVm; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 490283D81886; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 490283D81886 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004971; bh=u78LAm3kCalwn/I6m7UYFSB57F27UMB0d29XkBWW4eg=; h=From:Date:MIME-Version:Message-Id:To; b=Iks9K5J7uGbAonFxGAhAScYgq/39lKb4CuEaUMW/lHH87dXnlKveCdrU8PkHmMSOA DnEKi5Bch6vHD+4kTpQLQBDZyfIB17SWRrSqL9Htww7pq/jy66J8NznVD6y+g230lP ZqCh2XI4KKdUGRmPW+fhpN0z7gO5FEWPsQmLUdv5wQM3tpn3YqAuFu5YTZZGzFdxB0 gpMjasQSX1nnshK14QpqUpPkszCVRi3d9s156SjeMhkffbxTScd5zbKpUMKTT4V3Z4 u/IRXHdbq8iNtzoXMvJfIi5q6LfIRSMZqyjFYb31kM0c+0IQX46+ZCNgnoo+i5DiUT zPj6+BwwvR2ww== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id BzaVtBpgYiOm; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id B19A63D81896; Mon, 26 Oct 2026 04:56:10 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:41 +0100 Subject: [PATCH 03/20] devtool: ide-sdk: export recipe Cargo configuration MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-3-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248641 Export recipe Cargo config to the devtool workspace so Cargo and rust-analyzer reuse target, linker, rustflags, and dependency settings instead of duplicating them in settings.json and tasks.json. Other IDE integrations can reuse the generated config too. Update managed TOML table entries in place to preserve unrelated content. tomllib and tomli only parse TOML; using a writer would add a dependency. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_sdk.py | 84 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index e686dbcff8..21229f5970 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -36,6 +36,34 @@ logger = logging.getLogger('devtool') ide_plugins = {} +def set_toml_table_values(content, table, values): + """Update one TOML table while preserving unrelated configuration text.""" + lines = content.splitlines() + header = '[%s]' % table + try: + start = next(i for i, line in enumerate(lines) + if line.strip() == header) + except StopIteration: + if lines and lines[-1].strip(): + lines.append('') + lines.append(header) + start = len(lines) - 1 + + end = next((i for i in range(start + 1, len(lines)) + if lines[i].lstrip().startswith('[') + and lines[i].rstrip().endswith(']')), len(lines)) + for key, value in values.items(): + entry = '%s = %s' % (key, value) + for i in range(start + 1, end): + if '=' in lines[i] and lines[i].split('=', 1)[0].strip() == key: + lines[i] = entry + break + else: + lines.insert(end, entry) + end += 1 + return '\n'.join(lines).rstrip() + '\n' + + class DevtoolIdeMode(Enum): """Different modes are supported by the ide-sdk plugin. @@ -1122,6 +1150,62 @@ class RecipeModified: self.recipe_id = self.bpn + "-" + self.package_arch self.recipe_id_pretty = self.bpn + ": " + self.package_arch + @property + def cargo_config_path(self): + return os.path.join(self.ide_sdk_dir, 'cargo-config.toml') + + def update_cargo_config(self): + """Export the recipe Cargo config to the devtool workspace.""" + source_config = os.path.join(self.cargo_home, 'config.toml') + try: + with open(source_config, 'r') as config_file: + original = config_file.read() + except FileNotFoundError as exc: + raise DevtoolError( + 'Cargo config not found at %s; build the recipe first' % source_config) from exc + + content = ( + '# Generated by devtool ide-sdk for the active build environment.\n' + '\n' + + original) + content = set_toml_table_values(content, 'build', { + 'target': json.dumps(self.cargo_target), + }) + content = set_toml_table_values(content, 'target.%s' % self.cargo_target, { + 'linker': json.dumps(self.cargo_linker), + 'rustflags': json.dumps(shlex.split(self.cargo_rustflags)), + }) + env_names = ( + 'CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'AR', + 'TARGET_CC', 'TARGET_CXX', 'TARGET_CFLAGS', 'TARGET_CXXFLAGS', 'TARGET_AR', + 'HOST_CC', 'HOST_CXX', 'HOST_CFLAGS', 'HOST_CXXFLAGS', 'HOST_AR', + 'RUST_TARGET_PATH', 'RUST_BACKTRACE', 'SOURCE_DATE_EPOCH', + 'PKG_CONFIG', 'PKG_CONFIG_FOR_BUILD', 'PKG_CONFIG_FOR_TARGET', + 'PKG_CONFIG_SYSROOT_DIR', 'PKG_CONFIG_PATH', 'PKG_CONFIG_LIBDIR', + 'LIBGIT2_NO_VENDOR', 'LIBSSH2_SYS_USE_PKG_CONFIG', + 'LIBSQLITE3_SYS_USE_PKG_CONFIG', 'OPENSSL_NO_VENDOR', + 'PKG_CONFIG_ALLOW_CROSS', 'PKG_CONFIG_ALL_DYNAMIC', + 'SYSTEM_DEPS_BUILD_INTERNAL', 'ZSTD_SYS_USE_PKG_CONFIG', + ) + env_values = {} + for name in env_names: + value = self.cargo_env.get(name) + if value is not None: + env_values[name] = '{ value = %s, force = true }' % json.dumps(str(value)) + content = set_toml_table_values(content, 'env', env_values) + + config_path = self.cargo_config_path + os.makedirs(os.path.dirname(config_path), exist_ok=True) + try: + with open(config_path, 'r') as config_file: + current = config_file.read() + except FileNotFoundError: + current = None + if current != content: + with open(config_path, 'w') as config_file: + config_file.write(content) + return config_path + @staticmethod def is_valid_shell_variable(var): """Skip strange shell variables like systemd From patchwork Mon Oct 26 08:55:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101959 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38524.1793004973870975863 for ; Mon, 26 Oct 2026 01:56:14 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=HGvhrnMt; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id E04CE3D81886; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id 1DbCJP5o0Y9D; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id DDE803D81896; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com DDE803D81896 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004971; bh=QuBNPmiC+CmLPjndRVy+du3hchxNnRcsJCOUm+3IHxY=; h=From:Date:MIME-Version:Message-Id:To; b=HGvhrnMtKM7F0EoJmZLnVyHyEmdHrD7UZ7LsODpNYekGf4Ik7TaPMcwxkMXXeurAg v85sW6E1ViW1EH7eTLsm0cN6BkWxcM8QR9WbxAKowEXBaaojzR2tM7hGp/jx8oGBfz 78ft9DAiptKZiVIlAf12G9/ExLgxzIwcwM2gROjkxfHLu5r03BHUzYIBPJxIU8RCQg 63e05UJDWHawx+4EGSfAt0ie6sFy5EWjXyzzJWo0Eg3vR+lS6Xx7Of7gEyQy2bbmFW D0wz+1Y7gXgipvSHXyUXKlkD41kbELWedzNeLq10cHM3YDGfeyqLaXogkBe97XyZ3f 3w7Z/Vm7QvPzQ== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id W1si99SANAWv; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 547FB3D81844; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:42 +0100 Subject: [PATCH 04/20] devtool: ide-sdk: recommend Rust Analyzer for Cargo MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-4-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248642 Recommend rust-analyzer for Cargo recipes and verify the extension appears in the generated VS Code recommendations file. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 14 ++++++++++++++ scripts/lib/devtool/ide_plugins/ide_code.py | 2 ++ 2 files changed, 16 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 265f2147a4..941f54e36b 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -4339,6 +4339,20 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): self._test_code_and_none_qemu(slirp=True) +class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests): + + def test_code_cargo_rust_analyzer_recommendation(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' % recipe_name, + output_log=self._cmd_logger) + + with open(os.path.join(tempdir, '.vscode', 'extensions.json')) as extensions_file: + extensions = json.load(extensions_file) + self.assertIn('rust-lang.rust-analyzer', extensions['recommendations']) + 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 081dc08657..cf7f81293c 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -303,6 +303,8 @@ class IdeVSCode(IdeBase): def vscode_extensions(self, modified_recipe): recommendations = [] + if modified_recipe.build_tool is BuildTool.CARGO: + recommendations.append("rust-lang.rust-analyzer") # 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 From patchwork Mon Oct 26 08:55:43 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101963 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38881.1793004974669504489 for ; Mon, 26 Oct 2026 01:56:14 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=KIrkwoN1; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id C05273D818BC; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id Ksa6OU-xk-PL; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 826BE3D81863; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 826BE3D81863 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004972; bh=TgIZAsf68xq5NDzRMbJV0PlHF2RHw2dfudgfA0nd+Sc=; h=From:Date:MIME-Version:Message-Id:To; b=KIrkwoN1bKTIXRiTiH3Zu5zXHqU+hPEesLAnmVC3VDhxzVIdfSEpIk5c5Ke9DNePF WS+l/zd2ddcrOUkhwRZefWjmZQ6wE1s9OEWpI5orIT7MHHttd2Xif1PzPLJyZffK9T 7PK2geytOqifrUUCB/xhX7k9VT3TiEueiEzQ1rtp5zvmPZNfN9ppcque2TGicKc15L N0vZgykH0q5bHPa/Ss5mEViLwSw4UXicH1L1aHMgiA7nQEdw0C+m60mgCMnRA4rVXm q4s3STNGAb3IDtarmwt26Q9twFoMtWKGrkpDKMyCYcjRUGA0sT3Em1Kxe3ZhJXbu6N 4BNDvHHJkqcyg== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id W28th-MR3iqB; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id EAF623D818BA; Mon, 26 Oct 2026 04:56:11 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:43 +0100 Subject: [PATCH 05/20] devtool: ide-sdk: configure Rust Analyzer for Cargo MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-5-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248643 Point Rust Analyzer at the generated Cargo config and target, while keeping its process environment limited to the recipe PATH. Verify the workspace config path and target in the Cargo selftest. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 12 +++++++++++- scripts/lib/devtool/ide_plugins/ide_code.py | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 941f54e36b..d1e15d0180 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -4341,7 +4341,7 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests): - def test_code_cargo_rust_analyzer_recommendation(self): + def test_code_cargo_rust_analyzer_configuration(self): recipe_name = "cargo-example" self._check_workspace() self._write_bb_config() @@ -4349,8 +4349,18 @@ class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests): runCmd('devtool ide-sdk %s oe-selftest-image --ide=code' % recipe_name, output_log=self._cmd_logger) + with open(os.path.join(tempdir, '.vscode', 'settings.json')) as settings_file: + settings = json.load(settings_file) with open(os.path.join(tempdir, '.vscode', 'extensions.json')) as extensions_file: extensions = json.load(extensions_file) + cargo_config = os.path.join( + self.workspacedir, 'ide-sdk', recipe_name, 'cargo-config.toml') + self.assertExists(cargo_config, 'Cargo config was not generated') + 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.assertIn('rust-lang.rust-analyzer', 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 cf7f81293c..85f286335f 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -228,6 +228,16 @@ class IdeVSCode(IdeBase): } ] + def __vscode_settings_cargo(self, settings_dict, modified_recipe): + if modified_recipe.build_tool is not BuildTool.CARGO: + return + cargo_config = modified_recipe.update_cargo_config() + settings_dict["rust-analyzer.server.extraEnv"] = { + "PATH": modified_recipe.path + } + settings_dict["rust-analyzer.cargo.target"] = modified_recipe.cargo_target + settings_dict["rust-analyzer.cargo.configPath"] = cargo_config + def __vscode_settings_clangd(self, settings_dict, modified_recipe): if not (modified_recipe.ide_sdk_intellisense == 'clangd' and modified_recipe.build_tool.is_c_cpp): return @@ -294,6 +304,7 @@ class IdeVSCode(IdeBase): self.__vscode_settings_cmake(settings_dict, modified_recipe) self.__vscode_settings_meson(settings_dict, modified_recipe) self.__vscode_settings_kernel_module(settings_dict, modified_recipe) + self.__vscode_settings_cargo(settings_dict, modified_recipe) self.__vscode_settings_clangd(settings_dict, modified_recipe) self.__vscode_settings_format(settings_dict, modified_recipe) From patchwork Mon Oct 26 08:55:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101964 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38525.1793004975015738863 for ; Mon, 26 Oct 2026 01:56:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=Mp12dZ4Y; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 226123D81844; Mon, 26 Oct 2026 04:56:14 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id gL1-4LGr0uVE; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 368693D818BA; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 368693D818BA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004973; bh=qIDYJjJ09oCXWLLZg+cU+4J0bwnr7WYvhUM/m3YSX1Y=; h=From:Date:MIME-Version:Message-Id:To; b=Mp12dZ4YeJnGOwqT2AS7EsROQQPKld5NOaX6uvg5wYejbwsaHi4mbaMCjiGHpBFHK X8OoHaIwWhLeO85g9Poz11v3IdAt2ModAN0iD2nN3bEqMYMDxE++EAP/3UwNMqcJsM nU9ADDwq9jkkyVmFzp33OcxEsyBMNe/4V689UI2d4D8UeQA7zJlw7BC+8rECi/RX9V mHgKtW7Dt0WDRKRFf0UVnz5wlJkWeC/98L4WKqh/LoJsIskbVzd5GmDKAg0Pw8ye9l s3Y0J7dEjqU/Q/ygpgfgJDR/rkru6Jd/xS+JJ2XXDU3LV6EnHY22ZUU+UegSlsPpWc +73IQhiul3A4w== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id HP0lp3ahAywA; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 8FBC03D818BC; Mon, 26 Oct 2026 04:56:12 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:44 +0100 Subject: [PATCH 06/20] devtool: ide-sdk: share IntelliSense architecture mapping MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-6-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:26 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248644 Move the target architecture map out of the Meson branch so Cargo C/C++ IntelliSense for FFI and build-script code can reuse the same mapping instead of duplicating it. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_plugins/ide_code.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index 85f286335f..95ef472ed4 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -352,16 +352,16 @@ class IdeVSCode(IdeBase): properties_dict = { "name": modified_recipe.recipe_id_pretty, } + arch_map = { + 'aarch64': 'arm64', 'x86_64': 'x64', 'arm': 'arm', + 'i686': 'x86', 'i586': 'x86', 'riscv64': 'x64', 'riscv32': 'x86', + } 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. compiler_type = 'clang' if modified_recipe.toolchain == 'clang' else 'gcc' - arch_map = { - 'aarch64': 'arm64', 'x86_64': 'x64', 'arm': 'arm', - 'i686': 'x86', 'i586': 'x86', 'riscv64': 'x64', 'riscv32': 'x86', - } intelli_arch = arch_map.get(modified_recipe.target_arch, 'x64') properties_dict["compilerPath"] = os.path.join( modified_recipe.staging_bindir_toolchain, From patchwork Mon Oct 26 08:55:45 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101953 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38527.1793004976351016933 for ; Mon, 26 Oct 2026 01:56:16 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=tVZQ09yF; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 74CA63D81665; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id fcjzcL0Zf7ew; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id CFA8D3D818C4; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com CFA8D3D818C4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004973; bh=U54+2qcueXERKEgB6htcazjaXCWQvWBP2foyGleKW/A=; h=From:Date:MIME-Version:Message-Id:To; b=tVZQ09yF8Dtbds0SF5mDj8ADksssPnaM8whoSTOwjEQGBNGQdUwT+GgzEfrR/mprT er/2pTBZInXsIc+z3GxiZaRMT71Y4tI+mKQl11NRTMeXbTxeOcn/DvvCK8Mst/orbZ i+KoTKE+TOetQfIQEAs9CvpCOIYNevsaWTNk5RCY1EkEPreZ8RvuvAxL0OrM4+SP9x nXfU1khG3NRICl9TOPNIWP2cFdt90k5WCl1Nz1FhqcFoIKbJIOJdoGaCF5IeJf8F/1 /GNvoxwuQvav8ju+Sol5+b+5RoHa1EsjmR2eiN/PKRb71TYQhAYM0UtJsIcwi2FZL/ Ux8Lkz+sqIy9w== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id NajTPFkiVdPg; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 31F6A3D81896; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:45 +0100 Subject: [PATCH 07/20] devtool: ide-sdk: configure Cargo C++ IntelliSense MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-7-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:24 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248646 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 --- 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 --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 From patchwork Mon Oct 26 08:55:46 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101960 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38882.1793004976132852958 for ; Mon, 26 Oct 2026 01:56:16 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=osgDdpjf; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 40A213D81829; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id S35FiSj-SjTh; Mon, 26 Oct 2026 04:56:14 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 6D7CD3D81665; Mon, 26 Oct 2026 04:56:14 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 6D7CD3D81665 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004974; bh=3y1o/WKyuWmpg/1EDAAY/KSoY2hRrsLR02St6cSh92Q=; h=From:Date:MIME-Version:Message-Id:To; b=osgDdpjfVi0KcjXkRr5LQ9khUFT5VzTtLOYoXcFJxHbSArQKBCo9Z8Gngi9priwNf M21r0S+0c+6SzXy7OJVwVSvpM5qcnujSctJ8+ZOI8HFKExDBKMo2UOKtkUbQlCrtY7 qLw1DyUHgMhgHdV/DfVoFOk+6HlL1iNYjI5X2M7P1nl6IyT2Ng28M5w916Xhh/3ofW IHXdd8cu6Vc2HR0jhEvaN5JKAl9lydIHEdRDu8qnTpEpGIMre2bwGvtfxnVkgdF9aM PzihvVqrXno+ru46XdFaITDIdOnQ7he/QLKtrmU/C+VzDCnq8Laf9zdTlF8sdexMnK CgOVM5m+J3gXA== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id OZtNKuOyf4wJ; Mon, 26 Oct 2026 04:56:14 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id C89723D81863; Mon, 26 Oct 2026 04:56:13 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:46 +0100 Subject: [PATCH 08/20] devtool: ide-sdk: generalize binary install task name MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-8-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248645 Rename the C++-specific generator to describe its install/deploy behavior. The upcoming Cargo task builds outside BitBake and will reuse this helper to install and deploy the resulting recipe artifacts. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_plugins/ide_code.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index fcd2e5b5fe..53cebe71a8 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -674,7 +674,7 @@ class IdeVSCode(IdeBase): IdeBase.update_json_file( self.dot_code_dir(modified_recipe), launch_file, launch_dict) - def vscode_tasks_cpp(self, args, image_recipe, modified_recipe): + def vscode_tasks_binary(self, args, image_recipe, modified_recipe): run_install_deploy = modified_recipe.gen_install_deploy_script(args, image_recipe.nfs_deploy_dir) install_task_name = "install && deploy-target %s" % modified_recipe.recipe_id_pretty deploy_args = ["--target", resolve_deploy_target(args, image_recipe.nfs_deploy_dir)] @@ -976,7 +976,7 @@ class IdeVSCode(IdeBase): def vscode_tasks(self, args, image_recipe, modified_recipe): if modified_recipe.build_tool.is_c_cpp: - self.vscode_tasks_cpp(args, image_recipe, modified_recipe) + 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) else: From patchwork Mon Oct 26 08:55:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101955 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38528.1793004976717084786 for ; Mon, 26 Oct 2026 01:56:16 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=KFHrSTDT; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id CCA963D818BA; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id nwpDPCLDg9nz; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 0BF693D81833; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 0BF693D81833 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004975; bh=JXShXhkRKPWWFRgkHDwUAbTUOqGEt4vPm3yq1BONqLU=; h=From:Date:MIME-Version:Message-Id:To; b=KFHrSTDT2gj+Y/vALe+W7uQH9gBoU28o7c7N1x2cRHGD1emS7JWhOt5VNGl8IWuy2 ThKlQ+kDqx4QcZgYJQojNFQ8gH4zHyHrX3a6lxFcSok5V2IdZIPDA5y7g24uhCl2ds 6vs5nd6H7/q+uFRCK+lPDSNd5XQU6OI5o8su7kdrQ/iO1ZxwUmXQTkb9TnY8gZw9Oo jmVAjnIJHi6ybqE96QNSDe5euyRCvApNfIAPRpcseaJgQ9lfHLYJUfiEGbhn0h/xTk EkOwpo8qOn6RFF7JMjN9NtY/UP5eBPNmP3wGFrWY9k4ArhIPUEb7tGURxeNM06JAHH JotcCLREc2+9Q== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id n3-D5k9Vneqp; Mon, 26 Oct 2026 04:56:14 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 68E853D81829; Mon, 26 Oct 2026 04:56:14 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:47 +0100 Subject: [PATCH 09/20] devtool: ide-sdk: extract install task definition MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-9-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248647 Extract the install/deploy task object before adding optional dependencies. This preserves existing task output and provides a shared insertion point for Cargo build/deploy ordering. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_plugins/ide_code.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index 53cebe71a8..b5ff344e8a 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -682,17 +682,16 @@ class IdeVSCode(IdeBase): deploy_args += ["--port", args.port] for package in args.package or []: deploy_args += ["--package", package] + install_task = { + "label": install_task_name, + "type": "shell", + "command": run_install_deploy, + "args": deploy_args, + "problemMatcher": [] + } tasks_dict = { "version": "2.0.0", - "tasks": [ - { - "label": install_task_name, - "type": "shell", - "command": run_install_deploy, - "args": deploy_args, - "problemMatcher": [] - } - ] + "tasks": [install_task] } for cross_debug_config in self.cross_debug_configs: if cross_debug_config.modified_recipe is not modified_recipe: From patchwork Mon Oct 26 08:55:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101958 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38529.1793004977600449847 for ; Mon, 26 Oct 2026 01:56:17 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=NxLDYTtj; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id B206D3D81886; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id i7wFoIf5Co6f; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id A85813D81896; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com A85813D81896 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004975; bh=0x47750gnldgQigHO0SFXxgHiO5NanX28aV3lhDPWVw=; h=From:Date:MIME-Version:Message-Id:To; b=NxLDYTtji9IBjIwHW3s0eiXTSzEMp16G5n81JxzQPFH2bkKwb1koRoaoLYHBhazoT cgORBF0FrZqf/9hN2J/kXrEO/dlgTO8iUpE8TjpsJWWYoMhPnOPPvP/SFpBkr3E16M LdZpSP1YRPXKN8VIjyJFn1mqH4TWJrgvNmONtVCv9Z71/J2Y3SHPee4wr6Z4W8uTbw Cd84gFUVyMYpNPd8+X7SCxX5AOjIlhqKDV7F02mIhX5pWACQI6efhHVsy1O6pUFXF3 nOKYkBbR85h2959ZKxUWOF5hGdUvDMOsPjWXCPDDAenUsOz5ngKcl1JqC7jUqLiAtR wU9fHJI2Ij7vA== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id mwUP95d7ghib; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 0D1BE3D81863; Mon, 26 Oct 2026 04:56:14 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:48 +0100 Subject: [PATCH 10/20] devtool: ide-sdk: order install after optional build task MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-10-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248648 Let binary task generation optionally insert a build task and make install/deploy depend on it. Cargo builds outside BitBake, so this ordering ensures its artifacts exist before do_install and deploy-target run. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_plugins/ide_code.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index b5ff344e8a..80314bfb89 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -674,7 +674,7 @@ class IdeVSCode(IdeBase): IdeBase.update_json_file( self.dot_code_dir(modified_recipe), launch_file, launch_dict) - def vscode_tasks_binary(self, args, image_recipe, modified_recipe): + def vscode_tasks_binary(self, args, image_recipe, modified_recipe, build_task=None): run_install_deploy = modified_recipe.gen_install_deploy_script(args, image_recipe.nfs_deploy_dir) install_task_name = "install && deploy-target %s" % modified_recipe.recipe_id_pretty deploy_args = ["--target", resolve_deploy_target(args, image_recipe.nfs_deploy_dir)] @@ -689,9 +689,21 @@ class IdeVSCode(IdeBase): "args": deploy_args, "problemMatcher": [] } + tasks = [build_task] if build_task else [] + install_task = { + "label": install_task_name, + "type": "shell", + "command": run_install_deploy, + "args": deploy_args, + "problemMatcher": [] + } + if build_task: + install_task["dependsOn"] = [build_task["label"]] + install_task["dependsOrder"] = "sequence" + tasks.append(install_task) tasks_dict = { "version": "2.0.0", - "tasks": [install_task] + "tasks": tasks } for cross_debug_config in self.cross_debug_configs: if cross_debug_config.modified_recipe is not modified_recipe: From patchwork Mon Oct 26 08:55:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101956 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38883.1793004978568706182 for ; Mon, 26 Oct 2026 01:56:18 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=o4A1lKGz; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id A84D43D81665; Mon, 26 Oct 2026 04:56:17 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id yWGw1k-HwnMh; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 32A123D81844; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 32A123D81844 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004976; bh=2wXA9kvuVFwrZ+iyx3dvkrTNM+TJ0RZOfDP0gnM/e/8=; h=From:Date:MIME-Version:Message-Id:To; b=o4A1lKGzkN7CUvy2Orx8MNBmAAk1jvF7mr1rrlxR8jZ9LkEnRUc6YhJ3Y9fNwslXQ Roc9p2pgyNl8zchLO3h8ZoAp5hycOB3VeVbsPUOsRuwNeXLPPUg/pF4xvJ+E3P8Ce/ orgwx0t85BUDrhtaJp2Q1niORvt6rFDg8ZC7cC00NF7NFNPY6rj9ckBZNdRS4KGqNe 0tGMpRc28jtUkSel7z43mCj1SdGXSTf3AMs/0R3/YMM5fyETivlpGDeuEYbGhyNODy elKK/B++KT3s9E5+uxPPxyo6z/SN885bcFsOQ/NkJ2inu0t9sEviLAkwB64W3ga3k/ SFD0waxtHXghQ== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id L2ZmMPUunFab; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id A3FD63D818A9; Mon, 26 Oct 2026 04:56:15 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:49 +0100 Subject: [PATCH 11/20] devtool: ide-sdk: add Cargo build task MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-11-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248649 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 --- meta/lib/oeqa/selftest/cases/devtool.py | 37 +++++++++++++++++++++++++++++ scripts/lib/devtool/ide_plugins/ide_code.py | 25 +++++++++++++++++++ 2 files changed, 62 insertions(+) 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) From patchwork Mon Oct 26 08:55:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101962 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38884.1793004979382349804 for ; Mon, 26 Oct 2026 01:56:19 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=aLkNcsru; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 79D6A3D818A9; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id zem5wYZu1DSD; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id CDE213D81896; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com CDE213D81896 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004976; bh=dU/+2ZEfQcF4Q8VIwQT5K45w/bHUMtvn2TB2uw6XMeA=; h=From:Date:MIME-Version:Message-Id:To; b=aLkNcsrunm/4DsZnJeKlHeKHhxf0TqI5WK/vcA8oc1exmWt/tD46sT7SpcDf6rACl N1utP8+hBSqyo5qtjqgl/nw/GCGu9ouHue4UevCZDt6QIBUZVoa+QBsssBbR4Tla2A bwV71zX0/7QfIg7AL91c8jzGWCe7nZVxgCfOGlT1Bl8JF6l8wjcP0u8SuU2EtFLvN8 nlFY84GlzwaFgHdbs/0wxbYdyQGnO8DINQWrVzHbxMbWqfcqW5Vk5SwxrIdD44zul0 1TxRHD+fRfW6S/jp/2Ty95btJYrZlazK6bM0PaXat6P9RXj6ZOdP+v0UsFiCtF3Gho hFfoop//WEgEA== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id jQmCT0jQY21J; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 444823D81863; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:50 +0100 Subject: [PATCH 12/20] devtool: ide-sdk: enforce LLDB for Cargo MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-12-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248651 Route Cargo debugging through CodeLLDB and lldb-server because GDB/cppdbg does not resolve Rust function breakpoints in the VS Code Rust workflow. Cargo debugging always uses LLDB, regardless of the recipe C/C++ toolchain. Key shared debugger instances by backend rather than TOOLCHAIN so Rust recipes use the correct server while ordinary GCC recipes retain GDB. Cargo C++ IntelliSense still uses the recipe compiler. This follows VS Code's recommended Rust workflow: https://code.visualstudio.com/docs/languages/rust#_debugging AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 22 ++++++++++++++++++ scripts/lib/devtool/ide_plugins/ide_code.py | 3 ++- scripts/lib/devtool/ide_sdk.py | 35 ++++++++++++++++++----------- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index bd0bfb06ec..38bd3301cf 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -4390,6 +4390,28 @@ class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests): self.assertIn('rust-lang.rust-analyzer', extensions['recommendations']) self.assertIn('ms-vscode.cpptools', extensions['recommendations']) + def test_code_cargo_lldb_configuration(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', 'extensions.json')) as extensions_file: + extensions = json.load(extensions_file) + with open(os.path.join(tempdir, '.vscode', 'launch.json')) as launch_file: + launch = json.load(launch_file)['configurations'][0] + with open(os.path.join(tempdir, '.vscode', 'tasks.json')) as tasks_file: + tasks = json.load(tasks_file)['tasks'] + + self.assertIn('vadimcn.vscode-lldb', extensions['recommendations']) + self.assertEqual(launch['type'], 'lldb') + server_task = next( + task for task in tasks if task['label'] == launch['preLaunchTask']) + self.assertIn('lldb-server platform --server', server_task['args'][-1]) + def test_code_cargo_build_task(self): recipe_name = "cargo-example" self._check_workspace() diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index 089016c639..e18c6a703d 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -320,6 +320,7 @@ class IdeVSCode(IdeBase): recommendations += [ "rust-lang.rust-analyzer", "ms-vscode.cpptools", + "vadimcn.vscode-lldb" ] # clangd (matched to the recipe's real cross compiler via # compile_commands.json) replaces cpptools as the IntelliSense provider @@ -1023,7 +1024,7 @@ class IdeVSCode(IdeBase): self.vscode_extensions(modified_recipe) self.vscode_c_cpp_properties(modified_recipe, image_recipe) if args.target: - if modified_recipe.toolchain == 'clang': + if modified_recipe.uses_lldb: self.initialize_cross_debug_configs( image_recipe, modified_recipe, LldbServerConfigVSCode) else: diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 21229f5970..44429e80b0 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -433,11 +433,11 @@ class RecipeImage: resulting bbappend content actually differs from what was on disk when initialize() ran, False if it is left exactly as it was. """ - wants_gdbserver = any( - r.wants_gdbserver and r.toolchain != 'clang' - for r in recipes_modified) wants_lldb_server = any( - r.wants_gdbserver and r.toolchain == 'clang' + r.wants_gdbserver and r.uses_lldb + for r in recipes_modified) + wants_gdbserver = any( + r.wants_gdbserver and not r.uses_lldb for r in recipes_modified) # Only add what the base configuration (e.g. local.conf) does not @@ -1150,6 +1150,14 @@ class RecipeModified: self.recipe_id = self.bpn + "-" + self.package_arch self.recipe_id_pretty = self.bpn + ": " + self.package_arch + @property + def uses_lldb(self): + # VS Code's Rust debugging guide recommends CodeLLDB: + # https://code.visualstudio.com/docs/languages/rust#_debugging + # ide-sdk supports Rust debugging only through CodeLLDB; cppdbg/GDB + # does not resolve Rust function breakpoints from the VS Code UI. + return self.toolchain == 'clang' or self.build_tool is BuildTool.CARGO + @property def cargo_config_path(self): return os.path.join(self.ide_sdk_dir, 'cargo-config.toml') @@ -2032,20 +2040,21 @@ def ide_setup(args, config, basepath, workspace): bootstrap_tasks += recipe_modified.bootstrap_tasks recipes_modified.append(recipe_modified) - # Key by (arch, toolchain) so recipes with different toolchains - # targeting the same arch each get the right debugger. + # Key by (arch, debugger) so recipes sharing an architecture + # but using different debugger backends each get the right one. + debugger = 'lldb' if recipe_modified.uses_lldb else 'gdb' debugger_key = (recipe_modified.target_arch, - recipe_modified.toolchain or '') + debugger) if debugger_key not in debuggers: target_device = TargetDevice(args) - if recipe_modified.toolchain == 'clang': - debugger = RecipeLldbNative(args, target_device) + if recipe_modified.uses_lldb: + debugger_config = RecipeLldbNative(args, target_device) else: - debugger = RecipeGdbCross( + debugger_config = RecipeGdbCross( args, recipe_modified.target_arch, target_device) - debugger.initialize(config, workspace, tinfoil) - bootstrap_tasks += debugger.bootstrap_tasks - debuggers[debugger_key] = debugger + debugger_config.initialize(config, workspace, tinfoil) + bootstrap_tasks += debugger_config.bootstrap_tasks + debuggers[debugger_key] = debugger_config recipe_modified.debugger_cross = debuggers[debugger_key] finally: From patchwork Mon Oct 26 08:55:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101954 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38885.1793004979402215349 for ; Mon, 26 Oct 2026 01:56:19 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=TjDFlYoe; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 782893D81863; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id o58oj3YgpKAY; Mon, 26 Oct 2026 04:56:17 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 6D13C3D81833; Mon, 26 Oct 2026 04:56:17 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 6D13C3D81833 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004977; bh=EKARW0KVqwqLfOu5u2y+ECXis1USBBQhcYj1kADBvQc=; h=From:Date:MIME-Version:Message-Id:To; b=TjDFlYoerVR7YZTBZFiz9ND7ElRUwf9GAShH1ggugCJTgqYykXx66SaAvAypdVmco EQaMWfw4avneiCNLDIuqjj7JD9Em+IqFyqdpAc0nu86duxceD9r3SKkFIouBlkRfuK OJH1rw5hl2weiq3GsstemTGEQ8AcZvB3zw1WHlf9szpORkZ9nXhUVuWWA0BziIimiw 61pOcDYljZTIhNmKBgW7ywWw244UBlJ/VKeCX0CXUiOBe5hEKTgZukmRdy5Zp4wopz pbGY/9m1knoxPlqG3I3BZbqLYmK6zriH8LfsM2hC+Vdhms0QbE8UpysxWo0kBypZMy HxzgWI7Pj5+ig== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id VgI_3mzybGgg; Mon, 26 Oct 2026 04:56:17 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id DCA1A3D8187E; Mon, 26 Oct 2026 04:56:16 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:51 +0100 Subject: [PATCH 13/20] devtool: ide-sdk: parse Rust debug path remaps MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-13-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:24 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248650 Use Cargo RUSTFLAGS to populate reverse debug mappings and recognize Rust --remap-path-prefix alongside the existing GCC prefix-map options. The following LLDB source-map change depends on these normalized mappings. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_sdk.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 44429e80b0..f22a98cedf 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -1140,6 +1140,9 @@ class RecipeModified: if self.build_tool is BuildTool.KERNEL_MODULE: self.reverse_debug_prefix_map = self._init_reverse_debug_prefix_map( self.kernel_cc) + elif self.build_tool is BuildTool.CARGO: + self.reverse_debug_prefix_map = self._init_reverse_debug_prefix_map( + self.cargo_rustflags) else: self.reverse_debug_prefix_map = self._init_reverse_debug_prefix_map( recipe_d.getVar('DEBUG_PREFIX_MAP')) @@ -1292,15 +1295,20 @@ class RecipeModified: return ':'.join(self.solib_search_path(image)) def _init_reverse_debug_prefix_map(self, debug_prefix_map): - """Parses GCC map options and returns a mapping of target to host paths. + """Parses compiler map options and returns a mapping of target to host paths. - This function scans a string containing GCC options such as -fdebug-prefix-map, + This function scans a string containing compiler options such as -fdebug-prefix-map, -fmacro-prefix-map, and -ffile-prefix-map (in both '--option value' and '--option=value' forms), extracting all mappings from target paths (used in debug info) to host source paths. If multiple mappings for the same target path are found, the most suitable host path is selected (preferring 'sources' over 'build' directories). """ - prefixes = ("-fdebug-prefix-map", "-fmacro-prefix-map", "-ffile-prefix-map") + prefixes = ( + "-fdebug-prefix-map", + "-fmacro-prefix-map", + "-ffile-prefix-map", + "--remap-path-prefix", + ) all_mappings = {} args = shlex.split(debug_prefix_map) i = 0 From patchwork Mon Oct 26 08:55:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101952 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38886.1793004980472050747 for ; Mon, 26 Oct 2026 01:56:20 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=wrXgnWqj; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 91E343D81896; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id bVcolLKkvPEg; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 338293D8187E; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 338293D8187E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004978; bh=rrnEewBsKAjXM2aK/FIRI4NA7lrcGb58Im2xwYnT0TA=; h=From:Date:MIME-Version:Message-Id:To; b=wrXgnWqjWNFlZHPNS3BB3+bTVDLoI/WgzLFjVTTEbe3eNFx2R3jm42EHn5O4npNSr PyJdkOI8AJMw5m/cexCtklYGaMGQWLCVGgRYHRLEqM4R+3xFVJSkavRhUPMzfEPIYI frNDLPeVMVx0qqiJLAw/gChnk74jR9otzadyChXt4fPJkvllYchUfvDZHoEr2HnN1C 39EagkJfBc4l1n9xj8UH/3KWKcTVXUYHI7JCp+QltJDcVBsYEwTCIaXb66H7ca5KNC cxMX7TLbeJAgKuMnXO0D44eOHpeAM0jVppSO+OuJGnH+iQF6VxpMBo7vUEBwFFAMuH +4VQfvpsRJKpw== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id pXolrxfZrivB; Mon, 26 Oct 2026 04:56:17 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 7CB123D81863; Mon, 26 Oct 2026 04:56:17 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:52 +0100 Subject: [PATCH 14/20] devtool: ide-sdk: remap Cargo sources for BitBake builds MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-14-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:24 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248652 With devtool modify, Cargo sources can live outside WORKDIR, so the standard Rust remaps leave the workspace path in DWARF and package QA rejects the debug package. Append a workspace-specific remap to RUST_DEBUG_REMAP in a managed bbappend section so repeated ide-sdk runs restore and reparse it. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_sdk.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index f22a98cedf..9fd95f0a63 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -823,6 +823,7 @@ class RecipeModified: VALID_BASH_ENV_NAME_CHARS = re.compile(r"^[a-zA-Z0-9_]*$") MARKER = '# devtool ide-sdk: clangd toolchain support' + CARGO_REMAP_MARKER = '# devtool ide-sdk: Cargo source debug remap' # PROVIDES of recipes that are deployed via do_deploy (e.g. to # DEPLOY_DIR_IMAGE) rather than installed into the rootfs, so adding them @@ -943,13 +944,14 @@ class RecipeModified: content = f.read() originals[name] = content stripped = cls._strip_marker_section(content, cls.MARKER) + stripped = cls._strip_marker_section(stripped, cls.CARGO_REMAP_MARKER) if stripped != content: with open(bbappend, 'w') as f: f.write(stripped) return originals def update_bbappend(self): - """Add DEPENDS on clang-native when clangd is used as only the IntelliSense engine""" + """Add workspace-only IDE dependencies and Cargo debug path remaps.""" wants_clang_native = ( self.build_tool.is_c_cpp and self.ide_sdk_intellisense == 'clangd' @@ -962,28 +964,44 @@ class RecipeModified: else: parsed_content = '' - if not wants_clang_native: + new_sections = [] + if wants_clang_native: + new_sections.append( + self.MARKER + '\nDEPENDS:append = " clang-native"\n') + if self.build_tool is BuildTool.CARGO: + new_sections.append( + self.CARGO_REMAP_MARKER + + '\nRUST_DEBUG_REMAP:append = " ' + '--remap-path-prefix=${S}=${TARGET_DBGSRC_DIR}"\n') + + if not new_sections: if self.MARKER in original_content: logger.info( "Removed clangd toolchain support from %s: no longer needed", self.bbappend) return False - new_section = self.MARKER + '\nDEPENDS:append = " clang-native"\n' new_content = parsed_content - if new_content and not new_content.endswith('\n'): - new_content += '\n' - new_content += new_section + for section in new_sections: + if new_content and not new_content.endswith('\n'): + new_content += '\n' + new_content += section - if new_content == original_content: + # Managed sections were stripped before parsing, so compare against + # what BitBake parsed rather than the saved pre-strip contents. + if new_content == parsed_content: return False appends_dir = os.path.dirname(self.bbappend) os.makedirs(appends_dir, exist_ok=True) with open(self.bbappend, 'w') as f: f.write(new_content) - logger.info( - "Updated %s: added DEPENDS on clang-native, needed to stage clangd " - "for IDE_SDK_INTELLISENSE=\"clangd\"", self.bbappend) + if wants_clang_native: + logger.info( + "Updated %s: added DEPENDS on clang-native, needed to stage clangd " + "for IDE_SDK_INTELLISENSE=\"clangd\"", self.bbappend) + if self.build_tool is BuildTool.CARGO: + logger.info( + "Updated %s: remapped Cargo external sources for debug info", self.bbappend) return True def initialize(self, config, workspace, tinfoil): From patchwork Mon Oct 26 08:55:53 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101961 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38530.1793004980561876048 for ; Mon, 26 Oct 2026 01:56:20 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=h1uieEr0; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id A15023D8187E; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id S9VcAReJFI1G; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id A67883D81833; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com A67883D81833 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004978; bh=lo+EJ4FjLmxljLHkeCjg/yWW+b9HqJmiHKXz6DinSPs=; h=From:Date:MIME-Version:Message-Id:To; b=h1uieEr0Kw1nHoS4KCItIBOfsvR5D0PkAZhCv38blV2EQefO01qC863pY905QOrJ3 llX5zRRx0OKGUyHOjQu//th6U4dSB5LZZvx31mMp1LmnxGXLJiHIeG077MdeQKjYLU xsKPRnchaBRTn23TFk/Q1gwLU45Xa2pjKT6RSZpl1gz4RYSpYutKMarFjNFGKG6+0M Lr0XWO3nQEiaPZuDp77TVFrskshYn3qoTeLwTJCrWlALM/Vw6FylnPVdUyxppiq5Ld eTinxgGE1IuPdhQZGjGgq96ZAQX7QISUJnKWrfmMeYWKuQMwZATKGFtZt52OJapsEU R+CVBHBUtoidw== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id rZSzB4fCJOGb; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 1D3C03D81829; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:53 +0100 Subject: [PATCH 15/20] devtool: ide-sdk: map Cargo workspace sources for LLDB MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-15-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248653 Cargo debug info remaps the modified source tree to TARGET_DBGSRC_DIR. Include this reverse map in CodeLLDB launch configs even when rootfs-dbg is disabled. Use the Cargo workspace as its source root while preserving the existing rootfs-debug mappings for other recipes. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 3 +++ scripts/lib/devtool/ide_plugins/ide_code.py | 13 ++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 38bd3301cf..ca76597bbe 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -4408,6 +4408,9 @@ class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests): self.assertIn('vadimcn.vscode-lldb', extensions['recommendations']) self.assertEqual(launch['type'], 'lldb') + target_dbgsrc_dir = get_bb_var('TARGET_DBGSRC_DIR', recipe_name) + self.assertEqual( + launch['sourceMap'][target_dbgsrc_dir], os.path.realpath(tempdir)) server_task = next( task for task in tasks if task['label'] == launch['preLaunchTask']) self.assertIn('lldb-server platform --server', server_task['args'][-1]) diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index e18c6a703d..596586ee9e 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -566,15 +566,22 @@ class IdeVSCode(IdeBase): source_map = { "/usr/include": os.path.join(modified_recipe.recipe_sysroot, "usr", "include") } - if lldb_config.image_recipe.rootfs_dbg: + rootfs_dbg = lldb_config.image_recipe.rootfs_dbg + is_cargo = modified_recipe.build_tool is BuildTool.CARGO + if is_cargo or rootfs_dbg: + source_root = ( + modified_recipe.real_srctree + if is_cargo else "${workspaceFolder}") # Map build-time paths back to the workspace source tree. for target_path, host_path in modified_recipe.reverse_debug_prefix_map.items(): if host_path.startswith(modified_recipe.real_srctree): source_map[target_path] = ( - "${workspaceFolder}" + source_root + host_path[len(modified_recipe.real_srctree):]) - else: + elif rootfs_dbg: source_map[target_path] = host_path + + if rootfs_dbg: if "/usr/src/debug" in source_map: logger.error( 'Key "/usr/src/debug" already exists in source_map. ' From patchwork Mon Oct 26 08:55:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101950 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38531.1793004981397862996 for ; Mon, 26 Oct 2026 01:56:21 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=lYTdC22e; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 7A8233D818BA; Mon, 26 Oct 2026 04:56:20 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id wAYrNtp_60f0; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 603753D81844; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 603753D81844 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004979; bh=AM4UfZsPn56bPCuiMgoyv2TEPIvnnERiTwMR1bycunY=; h=From:Date:MIME-Version:Message-Id:To; b=lYTdC22eYJsO3Dz6lrHDfJhbBsyniKAVt5BaGPS+mLHgzz27c+FKabWtrt6Cn8u7a fm+z5234sIEsMul0bUWaBxeY2kH3wHLmFReHO/U8+yx969xHaVxcPkYKJVXybFWbP5 86747QR6O7a+NO+UGPNeAJb2YkfNeyuLD81nUSLiHWw3BoPRC9DRQsj7hgFOouyN/J KlvDa8rtdocFiXgW3x7sQY3MCH1QrAyo5ByI95mkCK7ZaR/5+3Cl3JBO+xw0nRJLCD +3TSUi4tIIongZOyMyeme5EVB3MP2T6S7QxE+PCqP6sNbjojjGdxJMUfrSD6QVV+/r S1VBtGvS6sexQ== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id 7LgriVmN9S-P; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id B458F3D81896; Mon, 26 Oct 2026 04:56:18 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:54 +0100 Subject: [PATCH 16/20] devtool: ide-sdk: map libstd-rs sources to Rust SDK MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-16-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:23 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248654 libstd-rs DWARF paths use a source prefix under work-shared, while rust-native stages the standard-library sources in the recipe native sysroot. Derive the target prefix from BitBake metadata and map it to the SDK source tree so LLDB runtime frames resolve without host Rust sources. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- scripts/lib/devtool/ide_plugins/ide_code.py | 2 ++ scripts/lib/devtool/ide_sdk.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index 596586ee9e..623a54ddc6 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -568,6 +568,8 @@ class IdeVSCode(IdeBase): } rootfs_dbg = lldb_config.image_recipe.rootfs_dbg is_cargo = modified_recipe.build_tool is BuildTool.CARGO + if is_cargo: + source_map.update(modified_recipe.cargo_std_source_map) if is_cargo or rootfs_dbg: source_root = ( modified_recipe.real_srctree diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 9fd95f0a63..b6ac02e367 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -915,6 +915,7 @@ class RecipeModified: self.cargo_packageconfig_confargs = None self.cargo_rustflags = None self.cargo_env = None + self.cargo_std_source_map = {} # Populated after bitbake built all the recipes self._installed_binaries = None @@ -1134,6 +1135,24 @@ class RecipeModified: 'SYSTEM_DEPS_BUILD_INTERNAL': 'never', 'ZSTD_SYS_USE_PKG_CONFIG': '1', }) + # libstd-rs DWARF paths map to sources staged by rust-native. + libstd_recipe_d = parse_recipe( + config, tinfoil, 'libstd-rs', appends=True, + filter_workspace=False) + if libstd_recipe_d: + libstd_rustsrc = libstd_recipe_d.getVar('RUSTSRC') + target_dbgsrc_dir = libstd_recipe_d.getVar('TARGET_DBGSRC_DIR') + libstd_tmpdir = libstd_recipe_d.getVar('TMPDIR') + if libstd_rustsrc and target_dbgsrc_dir and libstd_tmpdir: + shared_source_dir = os.path.join(libstd_tmpdir, 'work-shared') + target_source_root = os.path.join( + target_dbgsrc_dir, + os.path.relpath(libstd_rustsrc, shared_source_dir), + 'library') + sdk_source_root = os.path.join( + self.recipe_sysroot_native, self.libdir.lstrip('/'), + 'rustlib', 'src', 'rust', 'library') + self.cargo_std_source_map[target_source_root] = sdk_source_root self.build_tool = BuildTool.CARGO elif bb.data.inherits_class('module', recipe_d): self.build_tool = BuildTool.KERNEL_MODULE From patchwork Mon Oct 26 08:55:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101949 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.38887.1793004981811665345 for ; Mon, 26 Oct 2026 01:56:21 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=NZ2JHgal; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id E3DB73D81833; Mon, 26 Oct 2026 04:56:20 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id JOzS0a6xe-0U; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id D566E3D81665; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com D566E3D81665 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004979; bh=M1LIKssFdcbe94nCJnZdmFMs47hU4b3W7TGxC5v287A=; h=From:Date:MIME-Version:Message-Id:To; b=NZ2JHgal6vN5cgio+ImTAtlYxkj9XdvgBGz/Fh32Qep5qgakBsuDlfNTYyl8VsfoI fh7ZrDTbLz+DEnxUb4x+GK4hry9bsCA+dK27T7yghLva4bZby8rPPLiiar9J5Xl/bd VzCfPajHsPEnEZCaT73MRA8o3QxFpFa+eNUtU54OcfwEaQ3MtMeKNLwEF9JHtE1MQJ cCbIfN2VogLDty3o3FqmOxzSlyoWjvw806yu5cSYVCUhS0urb+/ZWSKrQ7BPaFVzMP QdERrQbVVbEFVM4pb69vF1d/UCmJ8Dg7zsflx9LLep85C16638bAC7CLol3BNO0vGQ w9l5HvjkZhClw== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id N5OSjCGFLput; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 53B3A3D81886; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:55 +0100 Subject: [PATCH 17/20] oeqa/selftest: share source breakpoint lookup MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-17-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:23 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248655 Move the stable source-line helper to the common ide-sdk test base so the Rust CodeLLDB integration can reuse it. Preserve the rationale for using marker-based lines instead of brittle hard-coded numbers. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index ca76597bbe..99e6531877 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3133,6 +3133,20 @@ class DevtoolIdeSdkTests(DevtoolBase): def _sources_workdir_dir(self, src_dir): return os.path.realpath(os.path.join(src_dir, 'oe-workdir')) + def _find_source_break_line(self, tempdir, source_file, marker): + """Find the 1-based line number of `marker` in tempdir/source_file + + Used to set a source-level (file:line) breakpoint at a stable, + self-documenting location instead of hard-coding a line number that + would silently go stale whenever the example source changes. + """ + source_path = os.path.join(tempdir, source_file) + with open(source_path) as f: + for lineno, line in enumerate(f, start=1): + if marker in line: + return lineno + self.fail("Could not find marker %r in %s" % (marker, source_path)) + def _find_multi_script_port(self, recipe_name, script_prefix, example_exe): """Discover the port assigned to a generated 'multi' mode debug-server script (gdbserver_*/lldb_server_*), since each --ide plugin allocates @@ -4876,20 +4890,6 @@ class DevtoolIdeSdkClangTests(DevtoolIdeSdkTests): self.assertTrue(task, f"Configuration '{config_name}' preLaunchTask should not be empty") - def _find_source_break_line(self, tempdir, source_file, marker): - """Find the 1-based line number of `marker` in tempdir/source_file - - Used to set a source-level (file:line) breakpoint at a stable, - self-documenting location instead of hard-coding a line number that - would silently go stale whenever the example source changes. - """ - source_path = os.path.join(tempdir, source_file) - with open(source_path) as f: - for lineno, line in enumerate(f, start=1): - if marker in line: - return lineno - self.fail("Could not find marker %r in %s" % (marker, source_path)) - def _lldb_debug_cpp_example_batch_commands(self, tempdir): """Get a list of lldb --batch '-o' commands to debug the cpp-example-lib example From patchwork Mon Oct 26 08:55:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101951 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38532.1793004982251604166 for ; Mon, 26 Oct 2026 01:56:22 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=emyeuCEG; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 5C2673D81844; Mon, 26 Oct 2026 04:56:21 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id T1ePr6_rDGop; Mon, 26 Oct 2026 04:56:20 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 75C413D81829; Mon, 26 Oct 2026 04:56:20 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 75C413D81829 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004980; bh=UZbZKDjYHLKur1gUrDrH5mQtwzwH0j9faQ8bi+M0woE=; h=From:Date:MIME-Version:Message-Id:To; b=emyeuCEGOs1ql8CzlCueL12A5T53dbWmPom3dtfeU0NFvHnKDCr/dWIdyKWYybrVA ClqRyMyj1jLrPtA8Q6aLtpobqCmvpnbLugDleeD3LYPU6Tgt4s7jguK0rJBCt68VBH 9/7RCReTnro0DFRcysKl11gRDzNFU9VhhJ263YXKnrtwwRlZDcldkSkowtaTOIHSYB qALno4DAGBgNtxKM4PFD/N0IPNlZ0Xhyduuaota6aTa5rJm1VWbatMpWC1iqNdbXrM zYG4sPXqjCja+uLor+6tQQIvHw3eZLw6CZCn67/mv6pEDrvvxxEwGm89nWgvURERiI k5bXc8Zdy5O5A== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id 78SsAdZxunRM; Mon, 26 Oct 2026 04:56:20 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id E96DB3D81833; Mon, 26 Oct 2026 04:56:19 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:56 +0100 Subject: [PATCH 18/20] oeqa/selftest: run IDE tasks with configured environment MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-18-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:23 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248656 Apply each generated shell task's options.env and return its runCmd results. Cargo build tasks intentionally keep only the SDK PATH, and the following rebuild integration test needs both to execute and inspect that task. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 99e6531877..114536fc16 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3485,6 +3485,7 @@ class DevtoolIdeSdkTests(DevtoolBase): self.assertIn(task_label, task_by_label, "Task '%s' not found in tasks.json" % task_label) + task_results = [] ran = set() def run_task(label, execute_task): @@ -3509,14 +3510,20 @@ class DevtoolIdeSdkTests(DevtoolBase): args = [args] task_cmd = [command] + [str(arg) for arg in args] - task_cwd = task.get('options', {}).get('cwd', tempdir) + task_options = task.get('options', {}) + task_cwd = task_options.get('cwd', tempdir) if isinstance(task_cwd, str): task_cwd = task_cwd.replace('${workspaceFolder}', tempdir) - runCmd(task_cmd, cwd=task_cwd, output_log=self._cmd_logger) + task_env = os.environ.copy() + task_env.update(task_options.get('env', {})) + task_results.append(runCmd( + task_cmd, cwd=task_cwd, env=task_env, + output_log=self._cmd_logger)) ran.add(label) run_task(task_label, run_main_task) + return task_results def _ide_sdk_package_opts(self): """Extra `devtool ide-sdk --package` options. Override to scope packages.""" From patchwork Mon Oct 26 08:55:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101966 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38535.1793004983699186368 for ; Mon, 26 Oct 2026 01:56:23 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=O15D9VRr; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id C6FAF3D81896; Mon, 26 Oct 2026 04:56:22 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id A2pIK1NiTCtY; Mon, 26 Oct 2026 04:56:21 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 19BF83D81665; Mon, 26 Oct 2026 04:56:21 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 19BF83D81665 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004981; bh=gAwT//k7vaXLlexh39wXWYiuE+7JlwSuK+KYOVbs6BE=; h=From:Date:MIME-Version:Message-Id:To; b=O15D9VRrmXEZoi73YhXpop/2OYpRaMMxqr4YV5JH9hKzfVooKEt279Kl3Zs2XnBfY jQ7cG/240NBBn3mzpLOQktYX47Zybzqf/jxz8blvgmkAMP9uj4TFUAyemcloFXaeot S6M3b6UIkuXBLv0V8s6ti6NVz/zk1JDhojcb3ZbrRIJ0nvHBQ3Kyf7q+cqoSmj3idc iuzIpFfBX+y+zvW7BO5y+39F7kz7FiQMSLZx8tYW5zEzRqA8Qw1SNH23nV8sWGJYIb 7ZfbcjV3kPmQxnzvgip72nJzGK2UsJHMDbWiXBuaVpA8yXcrtIsLGpzDjYI26/hwpL iooDlrrUmNprA== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id CEo3Bu8viVpq; Mon, 26 Oct 2026 04:56:20 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 899BF3D81844; Mon, 26 Oct 2026 04:56:20 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:57 +0100 Subject: [PATCH 19/20] oeqa/selftest: debug Cargo example over QEMU slirp MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-19-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:26 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248658 Exercise Cargo deploy and CodeLLDB launch against oe-selftest-image over slirp. Verify source breakpoints, Rust and runtime backtrace frames, and that BitBake's RUST_DEBUG_REMAP includes the devtool external source tree so package QA does not reject host paths in DWARF. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 127 ++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 114536fc16..87dc8a1ee5 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -4472,6 +4472,133 @@ class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests): if task['label'].startswith('install && deploy-target ')) self.assertEqual(install_task['dependsOn'], [build_task['label']]) + @OETestTag("runqemu") + def test_code_cargo_qemu_slirp(self): + recipe_name = 'cargo-example' + testimage = 'oe-selftest-image' + self._check_workspace() + self._write_bb_config() + tempdir = self._devtool_ide_sdk_recipe( + recipe_name, 'Cargo.toml', testimage) + port_start = self._reserve_slirp_port_block() + port_opts = ' -G %d' % port_start + runCmd( + 'devtool ide-sdk %s %s --ide=code --target root@localhost ' + '--port 2222 --no-host-check%s' % ( + recipe_name, testimage, port_opts), + output_log=self._cmd_logger) + source_remap = '--remap-path-prefix=%s=%s' % ( + os.path.realpath(tempdir), + get_bb_var('TARGET_DBGSRC_DIR', recipe_name)) + rustflags = shlex.split(get_bb_var('RUSTFLAGS', recipe_name)) + self.assertIn( + source_remap, rustflags, + 'Cargo BitBake builds must remap the external source tree for DWARF') + self._verify_slirp_bbappend(testimage) + + with runqemu( + testimage, runqemuparams='nographic slirp snapshot') as qemu: + self.assertIsNotNone(qemu.port, 'No SSH port for the slirp target') + runCmd( + 'devtool ide-sdk %s %s %s --skip-bitbake --ide=code%s' % ( + recipe_name, testimage, + '-t root@%s -P %s --no-host-check' % (qemu.ip, qemu.port), + port_opts), + output_log=self._cmd_logger) + rustflags = shlex.split(get_bb_var('RUSTFLAGS', recipe_name)) + self.assertIn( + source_remap, rustflags, + 'Repeated ide-sdk runs must preserve the Cargo source remap') + self._verify_rust_lldb_debugging(tempdir, expected_input=4) + + def _verify_rust_lldb_debugging(self, tempdir, expected_input): + with open(os.path.join(tempdir, '.vscode', 'launch.json')) as launch_file: + launch = json.load(launch_file)['configurations'][0] + with open(os.path.join(tempdir, '.vscode', 'tasks.json')) as tasks_file: + tasks = json.load(tasks_file)['tasks'] + + self.assertEqual(launch['type'], 'lldb') + target_dbgsrc_dir = get_bb_var('TARGET_DBGSRC_DIR', 'cargo-example') + self.assertEqual( + launch['sourceMap'][target_dbgsrc_dir], os.path.realpath(tempdir)) + self._run_vscode_task_with_dependencies( + tempdir, launch['preLaunchTask'], run_main_task=False) + server_task = next( + task for task in tasks if task['label'] == launch['preLaunchTask']) + self.assertEqual(server_task['command'], 'ssh') + ssh_args = [server_task['command']] + server_task['args'] + if ssh_args[-1].startswith('"') and ssh_args[-1].endswith('"'): + ssh_args[-1] = ssh_args[-1][1:-1].replace('\\$', '$') + runCmd(ssh_args, output_log=self._cmd_logger) + + source_line = self._find_source_break_line( + tempdir, 'src/main.rs', ' match n {') + println_line = self._find_source_break_line( + tempdir, 'src/main.rs', 'println!') + lldb_batch = [ + os.path.join( + get_bb_var('RECIPE_SYSROOT_NATIVE', 'lldb-native'), + 'usr', 'bin', 'lldb'), + '--batch', + ] + for command in launch['initCommands'] + launch['targetCreateCommands']: + lldb_batch += ['-o', command] + source_map_args = [] + for source, destination in launch.get('sourceMap', {}).items(): + source_map_args += [source, destination] + if source_map_args: + lldb_batch += [ + '-o', 'settings set target.source-map %s' % + ' '.join(source_map_args)] + lldb_batch += [ + '-o', 'breakpoint set --file main.rs --line %d' % source_line, + '-o', 'breakpoint set --file main.rs --line %d' % println_line, + '-o', 'breakpoint disable 2', + '-o', 'breakpoint list', + '-o', 'run', + '-o', 'frame variable n', + '-o', 'thread backtrace', + '-o', 'breakpoint disable 1', + '-o', 'breakpoint enable 2', + '-o', 'continue', + '-o', 'frame info', + '-o', 'frame select 1', + '-o', 'frame info', + '-o', 'frame select 3', + '-o', "image lookup -v -r -n 'std::rt::lang_start.*'", + '-o', 'thread backtrace', + '-o', 'exit', + ] + result = runCmd(lldb_batch, timeout=60, output_log=self._cmd_logger) + self.assertNotIn('(pending)', result.output) + self.assertIn('cargo_example::fibonacci', result.output) + self.assertIn('cargo_example::main', result.output) + self.assertIn('std::rt::lang_start', result.output) + self.assertIn('__libc_start', result.output) + self.assertRegex(result.output, r'n\s*=\s*%d' % expected_input) + libstd_rustsrc = get_bb_var('RUSTSRC', 'libstd-rs') + libstd_work_shared = os.path.join( + get_bb_var('TMPDIR', 'libstd-rs'), 'work-shared') + rust_std_target_root = os.path.join( + get_bb_var('TARGET_DBGSRC_DIR', 'libstd-rs'), + os.path.relpath(libstd_rustsrc, libstd_work_shared), + 'library') + rust_std_sdk_root = os.path.join( + get_bb_var('RECIPE_SYSROOT_NATIVE', 'cargo-example'), + 'usr', 'lib', 'rustlib', 'src', 'rust', 'library') + rust_std_source = os.path.join( + rust_std_target_root, 'std', 'src', 'rt.rs') + self.assertEqual( + launch['sourceMap'][rust_std_target_root], rust_std_sdk_root) + self.assertIn( + rust_std_source, result.output, + 'Rust runtime backtrace did not resolve to the SDK debug path:\n%s' % + result.output) + self.assertNotIn(libstd_rustsrc, result.output) + self.assertTrue( + os.path.isfile(os.path.join(rust_std_sdk_root, 'std', 'src', 'rt.rs')), + 'Rust standard-library source is missing from the recipe SDK sysroot') + class DevtoolIdeSdkKernelTests(DevtoolIdeSdkTests): From patchwork Mon Oct 26 08:55:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enguerrand de Ribaucourt X-Patchwork-Id: 101965 Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.38534.1793004983597195104 for ; Mon, 26 Oct 2026 01:56:23 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=xm8+egdn; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: enguerrand.de-ribaucourt@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id AFDF03D8187E; Mon, 26 Oct 2026 04:56:22 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id bT7WqpChRkKy; Mon, 26 Oct 2026 04:56:21 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id ABDCB3D81829; Mon, 26 Oct 2026 04:56:21 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com ABDCB3D81829 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1793004981; bh=g8AC/yjwOAdLGWvDRpSJTF7jvjMboZLf614G+9o3LoU=; h=From:Date:MIME-Version:Message-Id:To; b=xm8+egdnzw1fiHQXaPm6cswPMIqhaqC2lXpGW3u3TAoWWjyQ3gVWtv77WwONT77JP O+wH2EsYtik32soulM+/YHohYkeCsQOGyoSfXIwUqh/MMo3iXLNxefhT0TB8nQrJIV kn7qr6kucGp8bo4CObDeBHK2sgMlalaSzkrnYjDJCO9zp7jcq5bGz9rRpDzfX8bODS 3ZpnwW8JR51rk3QZ9u1l8rxkokTWWG8zgF8v5WBOVEBHW6DfEW0I5p9eTXw5nxdIgo prn1hfwKNrIL5iV9qLY/TBw4WO6xzIjHS3VrLwI0g6IJuEknGDAaauv712gqEhXdAX NfX26giVxUHzQ== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id 7RagCmbTCzat; Mon, 26 Oct 2026 04:56:21 -0400 (EDT) Received: from isabelle.rennes.sfl (80-15-101-118.ftth.fr.orangecustomers.net [80.15.101.118]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 2BA233D81886; Mon, 26 Oct 2026 04:56:21 -0400 (EDT) From: Enguerrand de Ribaucourt Date: Mon, 26 Oct 2026 09:55:58 +0100 Subject: [PATCH 20/20] oeqa/selftest: verify Cargo rebuild and redeploy MIME-Version: 1.0 Message-Id: <20261026-devtool-ide-sdk-cargo-v1-20-d4504e124d07@savoirfairelinux.com> References: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> In-Reply-To: <20261026-devtool-ide-sdk-cargo-v1-0-d4504e124d07@savoirfairelinux.com> To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer , Enguerrand de Ribaucourt X-Mailer: b4 0.16.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Mon, 26 Oct 2026 08:56:26 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248657 After a source edit, run the ordered Cargo build/install/deploy tasks and verify the changed Fibonacci result. Use a helper to shift source lines so the breakpoint location can change without hard-coded line numbers; reuse the shared LLDB runner for both debug sessions. AI-Generated: Uses GitHub Copilot Signed-off-by: Enguerrand de Ribaucourt --- meta/lib/oeqa/selftest/cases/devtool.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 87dc8a1ee5..b9adb624c4 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3147,6 +3147,15 @@ class DevtoolIdeSdkTests(DevtoolBase): return lineno self.fail("Could not find marker %r in %s" % (marker, source_path)) + def _insert_source_line_shift(self, source_path, marker, line_count): + with open(source_path) as source_handle: + source = source_handle.read() + self.assertEqual(source.count(marker), 1) + inserted_lines = ''.join( + ' // line shift %d\n' % index for index in range(line_count)) + with open(source_path, 'w') as source_handle: + source_handle.write(source.replace(marker, inserted_lines + marker, 1)) + def _find_multi_script_port(self, recipe_name, script_prefix, example_exe): """Discover the port assigned to a generated 'multi' mode debug-server script (gdbserver_*/lldb_server_*), since each --ide plugin allocates @@ -4511,6 +4520,28 @@ class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests): 'Repeated ide-sdk runs must preserve the Cargo source remap') self._verify_rust_lldb_debugging(tempdir, expected_input=4) + main_rs = os.path.join(tempdir, 'src', 'main.rs') + self._insert_source_line_shift(main_rs, ' match n {', 4) + with open(main_rs) as source_file: + shifted_source = source_file.read() + self.assertEqual(shifted_source.count('fibonacci(4)'), 1) + with open(main_rs, 'w') as source_file: + source_file.write( + shifted_source.replace('fibonacci(4)', 'fibonacci(5)', 1)) + + with open(os.path.join(tempdir, '.vscode', 'tasks.json')) as tasks_file: + tasks = json.load(tasks_file)['tasks'] + install_task = next( + task for task in tasks + if task['label'].startswith('install && deploy-target ')) + task_results = self._run_vscode_task_with_dependencies( + tempdir, install_task['label']) + self.assertTrue( + any('Compiling cargo-example' in result.output + for result in task_results), + 'Cargo build task did not recompile the modified Rust source') + self._verify_rust_lldb_debugging(tempdir, expected_input=5) + def _verify_rust_lldb_debugging(self, tempdir, expected_input): with open(os.path.join(tempdir, '.vscode', 'launch.json')) as launch_file: launch = json.load(launch_file)['configurations'][0]