From patchwork Sun Sep 27 17:44:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 99379 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7483FC9832F for ; Sun, 27 Sep 2026 17:45:18 +0000 (UTC) Received: from mta-64-228.siemens.flowmailer.net (mta-64-228.siemens.flowmailer.net [185.136.64.228]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.40682.1790531113091861050 for ; Sun, 27 Sep 2026 10:45:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm1 header.b=gamGrtVq; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.228, mailfrom: fm-1329275-20260927174509846b971676000207b1-jbow_y@rts-flowmailer.siemens.com) Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 20260927174509846b971676000207b1 for ; Sun, 27 Sep 2026 19:45:10 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=YpQB1fxyy5exLq1yzilaxDQeFie3Mhh53svccIz5/0E=; b=gamGrtVqN8u6whpXgA6/Ks2mvSj1cxX0UAU0sxMzoP5MsCk8yJR3NpU43GLKwMltLpyOW+ d2xDEDPqh7FHVHiAfPcsz/ZaGsSVL8f6FaC00IKYOuhgB5u8GulwnLRSkcwgzf5/uIxP46YD GI32W8zOD4PQ0yCp9cv0XKh8094z73M6Pi/Ot5ZPfwb+Bt6/KiAwjvfdX+MFUr8o0xRCsktJ TbQbNhO0bnWllXQbEsj+VVifDdO6EibOJgS8Nuehp7VpO2uGPE67TEBymYWeK2j3jgka5yVF pwmgjrzz3fD2uHgPOW9vcMJwFzhU/pveVtL+1klFitq15BAvY4F3QdQg==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH 1/5] devtool: ide-sdk: support shared recipe IDE hooks Date: Sun, 27 Sep 2026 19:44:49 +0200 Message-ID: <20260927174506.652690-2-adrian.freihofer@siemens.com> In-Reply-To: <20260927174506.652690-1-adrian.freihofer@siemens.com> References: <20260927174506.652690-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sun, 27 Sep 2026 17:45:18 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/246702 From: Adrian Freihofer In shared mode, unmodified recipes are built into the sysroots, but IDE plugins cannot prepare recipe-specific dependencies or generate configurations for an explicitly named recipe. Add initialization and setup hooks for each shared recipe. Plugins can request build tasks and image debug packages during setup; finalize the image bbappend before its build and generate recipe projects after the shared sysroots are ready. For example, a plugin can use a virtual/kernel recipe and an image to create a kernel debugging project without devtool modify. Signed-off-by: Adrian Freihofer --- scripts/lib/devtool/ide_plugins/__init__.py | 6 ++++++ scripts/lib/devtool/ide_sdk.py | 23 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/scripts/lib/devtool/ide_plugins/__init__.py b/scripts/lib/devtool/ide_plugins/__init__.py index 2cdb2e504a..87e5db6b68 100644 --- a/scripts/lib/devtool/ide_plugins/__init__.py +++ b/scripts/lib/devtool/ide_plugins/__init__.py @@ -367,6 +367,12 @@ class IdeBase: logger.warn("Shared sysroot mode is not supported for IDE %s" % self.ide_name) + def initialize_shared_recipe(self, config, tinfoil, images, recipe_name): + return [] + + def setup_shared_recipe(self, args, shared_env, image, workspace_path, recipe_name): + pass + def initialize_modified_recipe(self, config, tinfoil, recipe_modified): """Hook called once per modified recipe, inside the shared tinfoil session""" pass diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 1eb4d94fc6..2f23741371 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -1870,6 +1870,10 @@ def ide_setup(args, config, basepath, workspace): bootstrap_tasks_late += build_sysroots.bootstrap_tasks shared_env = SharedSysrootsEnv() shared_env.initialize(ide_support, build_sysroots) + for recipe_name in recipes_other_names: + for ide in ides: + bootstrap_tasks += ide.initialize_shared_recipe( + config, tinfoil, recipes_images, recipe_name) recipes_modified = [] if args.mode == DevtoolIdeMode.modified: @@ -1916,9 +1920,18 @@ def ide_setup(args, config, basepath, workspace): for recipe_modified in recipes_modified: if recipe_modified.update_bbappend(): recipe_bbappend_changed = True + shared_bbappend_changed = False + if args.mode == DevtoolIdeMode.shared: + for image in recipes_images: + if image.extra_image_install_debugfs: + bootstrap_tasks = [task for task in bootstrap_tasks + if task not in image.bootstrap_tasks] + image_bootstrap_tasks += image.bootstrap_tasks + if image.update_image_bbappend([], None): + shared_bbappend_changed = True if not args.skip_bitbake: - if recipe_bbappend_changed: + if recipe_bbappend_changed or shared_bbappend_changed: # The bbappend content just written differs from the one bitbake # parsed during the tinfoil session above. See update_image_bbappend()'s # matching reset for phase 2 for why this is needed. @@ -1940,10 +1953,18 @@ def ide_setup(args, config, basepath, workspace): exec_build_env_command( config.init_path, basepath, bb_cmd + ' '.join(bootstrap_tasks_late), watch=True) + if args.mode == DevtoolIdeMode.shared and image_bootstrap_tasks: + exec_build_env_command( + config.init_path, basepath, + bb_cmd + ' '.join(image_bootstrap_tasks), watch=True) if args.mode == DevtoolIdeMode.shared: for ide in ides: ide.setup_shared_sysroots(shared_env) + for recipe_name in recipes_other_names: + ide.setup_shared_recipe( + args, shared_env, recipes_images[0] if recipes_images else None, + config.workspace_path, recipe_name) elif args.mode == DevtoolIdeMode.modified: for recipe_modified in recipes_modified: if recipe_modified.build_tool is BuildTool.CMAKE: From patchwork Sun Sep 27 17:44:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 99382 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CEB0C9833F for ; Sun, 27 Sep 2026 17:45:19 +0000 (UTC) Received: from mta-64-228.siemens.flowmailer.net (mta-64-228.siemens.flowmailer.net [185.136.64.228]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.40681.1790531113091811559 for ; Sun, 27 Sep 2026 10:45:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm1 header.b=lcQcTcXP; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.228, mailfrom: fm-1329275-202609271745097564ca292d000207da-psgtln@rts-flowmailer.siemens.com) Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 202609271745097564ca292d000207da for ; Sun, 27 Sep 2026 19:45:10 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=v7XI7ZqKK/ojtr9qTcDWU+j1P190kCcVYldJRcSFvUA=; b=lcQcTcXP8QpgAN4mo6KF1szlWnKmra6U49PiYm9jv8vT5uzHrcb2tQzlWPb0LdYA4Z9kwK GZHYc0P05Dk73OcqeYaDcGXWFloE/5zsNXfSBLp3lf4XQipwCPHBKGU80rJt9OxP46dUQjYq Bdh1UltvWHBmm302T580gxex58+VamFomO1+k3PTvr1j5k7owvC63OJ8C2w80PHHMzFrc6wm s73E7AM+wQmr0CSbnzh0Wwbc8/aUVt04D5xwrV8QjJWrPzHC8Wjbei4/Z/XT9KvnUyU19Te3 lzdb4uD87aqmxPMa6iTjr/cTl+eJcBMXzlp/O6bwIX0KpxJ0wFVW5Xfg==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH 2/5] devtool: ide-sdk: initialize shared images for IDE plugins Date: Sun, 27 Sep 2026 19:44:50 +0200 Message-ID: <20260927174506.652690-3-adrian.freihofer@siemens.com> In-Reply-To: <20260927174506.652690-1-adrian.freihofer@siemens.com> References: <20260927174506.652690-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sun, 27 Sep 2026 17:45:19 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/246704 From: Adrian Freihofer Shared mode treated images as build dependencies only. IDE plugins could not request image debug packages or create configurations using the built rootfs. Add initialization and setup hooks for each supplied image. Build shared images after writing plugin-requested debug settings and before populating shared sysroots. Image-aware plugins can now generate debugger projects without naming a recipe to debug or changing the image task hash during the build. --- scripts/lib/devtool/ide_plugins/__init__.py | 6 +++++ scripts/lib/devtool/ide_sdk.py | 26 ++++++++++----------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/scripts/lib/devtool/ide_plugins/__init__.py b/scripts/lib/devtool/ide_plugins/__init__.py index 87e5db6b68..7841bc37b9 100644 --- a/scripts/lib/devtool/ide_plugins/__init__.py +++ b/scripts/lib/devtool/ide_plugins/__init__.py @@ -367,6 +367,12 @@ class IdeBase: logger.warn("Shared sysroot mode is not supported for IDE %s" % self.ide_name) + def initialize_shared_image(self, config, tinfoil, image): + return [] + + def setup_shared_image(self, args, shared_env, image, workspace_path): + pass + def initialize_shared_recipe(self, config, tinfoil, images, recipe_name): return [] diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 2f23741371..68005170c4 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -1842,13 +1842,9 @@ def ide_setup(args, config, basepath, workspace): raise DevtoolError( "%s does not exist. Run devtool ide-sdk --nfs=%s without " "--skip-bitbake first." % (recipe_image.nfs_deploy_dir, args.nfs)) - if args.mode == DevtoolIdeMode.modified: - # Keep the image build separate so that the complete bbappend - # (IMAGE_ vars + QB_SLIRP_OPT) can be written in one step - # before the image is built, avoiding sstate hash mismatches. - image_bootstrap_tasks += recipe_image.bootstrap_tasks - else: - bootstrap_tasks += recipe_image.bootstrap_tasks + # Build images only after the complete bbappend has been written, + # so the build never sees changing image task hashes. + image_bootstrap_tasks += recipe_image.bootstrap_tasks recipes_images.append(recipe_image) # Provide a Direct SDK with shared sysroots @@ -1870,6 +1866,9 @@ def ide_setup(args, config, basepath, workspace): bootstrap_tasks_late += build_sysroots.bootstrap_tasks shared_env = SharedSysrootsEnv() shared_env.initialize(ide_support, build_sysroots) + for image in recipes_images: + for ide in ides: + bootstrap_tasks += ide.initialize_shared_image(config, tinfoil, image) for recipe_name in recipes_other_names: for ide in ides: bootstrap_tasks += ide.initialize_shared_recipe( @@ -1924,9 +1923,6 @@ def ide_setup(args, config, basepath, workspace): if args.mode == DevtoolIdeMode.shared: for image in recipes_images: if image.extra_image_install_debugfs: - bootstrap_tasks = [task for task in bootstrap_tasks - if task not in image.bootstrap_tasks] - image_bootstrap_tasks += image.bootstrap_tasks if image.update_image_bbappend([], None): shared_bbappend_changed = True @@ -1949,18 +1945,20 @@ def ide_setup(args, config, basepath, workspace): exec_build_env_command( config.init_path, basepath, bb_cmd + ' '.join(bootstrap_tasks), watch=True) - if bootstrap_tasks_late: - exec_build_env_command( - config.init_path, basepath, - bb_cmd + ' '.join(bootstrap_tasks_late), watch=True) if args.mode == DevtoolIdeMode.shared and image_bootstrap_tasks: exec_build_env_command( config.init_path, basepath, bb_cmd + ' '.join(image_bootstrap_tasks), watch=True) + if bootstrap_tasks_late: + exec_build_env_command( + config.init_path, basepath, + bb_cmd + ' '.join(bootstrap_tasks_late), watch=True) if args.mode == DevtoolIdeMode.shared: for ide in ides: ide.setup_shared_sysroots(shared_env) + for image in recipes_images: + ide.setup_shared_image(args, shared_env, image, config.workspace_path) for recipe_name in recipes_other_names: ide.setup_shared_recipe( args, shared_env, recipes_images[0] if recipes_images else None, From patchwork Sun Sep 27 17:44:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 99378 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53BA5C98338 for ; Sun, 27 Sep 2026 17:45:18 +0000 (UTC) Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.41618.1790531113091750625 for ; Sun, 27 Sep 2026 10:45:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm1 header.b=RjE60RH0; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.225, mailfrom: fm-1329275-2026092717450942668c271e00020792-ybmpo7@rts-flowmailer.siemens.com) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 2026092717450942668c271e00020792 for ; Sun, 27 Sep 2026 19:45:10 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=YrcYOuqqMcYXO1gi+V7cGq5ZDzZaKpNdhBq9tmHOZdk=; b=RjE60RH0dLKg68+ChhEUBmcU80Klh0OJVbNwhImJiK1hnknvSCJQkY5jbkD7l6UoVpZijD 4x0K+gCatp4s7FWYnbbZS1eSwf8cftanQSNTxDTIbdPnIDhzFUoottU37/Q3ZvmOwWFenrBz u4eECWLgYyS3yISvan7SKuJhHOXVJVhiU7a4wpHI5IqFlzMPRoqOSMUIm8OVPlX7lIK4xGEM 1E92slNBHFhqey1Mx+EMZG0scmV1B47yVFfGekPSu5iPMPv5DwLf37WkD47JW0Hy/WrohMeE gfuXAJf79kTlvwC59QZH51ztT/U1AcM4xXZ78JhlC8TLjiJLRRPxdC6w==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH 3/5] devtool: ide-sdk: support NFS exports in shared mode Date: Sun, 27 Sep 2026 19:44:51 +0200 Message-ID: <20260927174506.652690-4-adrian.freihofer@siemens.com> In-Reply-To: <20260927174506.652690-1-adrian.freihofer@siemens.com> References: <20260927174506.652690-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sun, 27 Sep 2026 17:45:18 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/246706 From: Adrian Freihofer Shared mode rejected --nfs even when an image was supplied, so an image-backed debug session could not use an exported target rootfs. Write the required image tar and debugfs settings before building, then extract the selected rootfs before image-specific IDE setup. Reject --nfs when no image recipe was supplied. For example, build and export a debug rootfs with: devtool ide-sdk -m shared core-image-minimal --nfs=rootfs-dbg --- scripts/lib/devtool/ide_sdk.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 68005170c4..ac07dae656 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -391,7 +391,7 @@ class RecipeImage: return helper def update_image_bbappend(self, recipes_modified, nfs=None): - """Write debug settings for modified-mode recipes into the image bbappend. + """Write debug and NFS settings for the selected image into its bbappend. Writes IMAGE_GEN_DEBUGFS, IMAGE_FSTYPES_DEBUGFS, IMAGE_CLASSES for image-combined-dbg, the appropriate debug server (gdbserver or @@ -1785,8 +1785,8 @@ def ide_setup(args, config, basepath, workspace): logger.error("In shared sysroots mode modified recipes %s cannot be handled." % str( recipes_modified_names)) invalid_params = True - if args.nfs: - logger.error("--nfs is only supported in modified mode.") + if args.nfs and not recipes_image_names: + logger.error("--nfs requires an image recipe.") invalid_params = True if args.nfs_extract_dir and not args.nfs: logger.error("--nfs-extract-dir requires --nfs.") @@ -1922,8 +1922,8 @@ def ide_setup(args, config, basepath, workspace): shared_bbappend_changed = False if args.mode == DevtoolIdeMode.shared: for image in recipes_images: - if image.extra_image_install_debugfs: - if image.update_image_bbappend([], None): + if image.extra_image_install_debugfs or args.nfs: + if image.update_image_bbappend([], args.nfs): shared_bbappend_changed = True if not args.skip_bitbake: @@ -1955,6 +1955,9 @@ def ide_setup(args, config, basepath, workspace): bb_cmd + ' '.join(bootstrap_tasks_late), watch=True) if args.mode == DevtoolIdeMode.shared: + if args.nfs and not args.skip_bitbake: + for image in recipes_images: + image.extract_nfs_rootfs(nfs_export_base_dir, args.nfs, args.target) for ide in ides: ide.setup_shared_sysroots(shared_env) for image in recipes_images: @@ -2074,6 +2077,8 @@ def register_commands(subparsers, context): ' Usage example:\n' ' devtool ide-sdk -m ' + DevtoolIdeMode.shared.name + ' recipe(s)\n' ' This command generates a cross-toolchain as well as the corresponding shared sysroot directories.\n' + ' An image recipe may also be supplied to build a target image and generate image-based IDE configurations.\n' + ' With an image recipe, --nfs exports its rootfs for NFS booting.\n' ' To use this tool-chain the environment-* file found in the deploy..image folder needs to be sourced into a shell.\n' ' In case of VSCode and cmake the tool-chain is also exposed as a cmake-kit') default_ide = list(ide_plugins.keys())[0] From patchwork Sun Sep 27 17:44:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 99380 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 969CFCA5FA2 for ; Sun, 27 Sep 2026 17:45:19 +0000 (UTC) Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.40680.1790531113091596644 for ; Sun, 27 Sep 2026 10:45:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm1 header.b=Ll4akzZE; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.225, mailfrom: fm-1329275-2026092717451099ad3ff8a7000207a0-ymyhf2@rts-flowmailer.siemens.com) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 2026092717451099ad3ff8a7000207a0 for ; Sun, 27 Sep 2026 19:45:10 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=LEinUEP9iLO2rOo3v/EFuhYFeFNxAgtzCxZuVwFsWGA=; b=Ll4akzZET2ulJVugR1VEOfOYPec7nV19/EQXpULinN7aPiySOmhg85CWrhywjmy3bGpMjT EBnRKqzCYWeGO/uaPTQiJsa1y6KLnlllBHFFlst8yHmO4FveknPcbJlBjRCpyrqvArBJiv13 3YvBUW2c/fn9Wyz72kZfhMKKO597igtghH8f/+O6cB93HvqD2mefjA21RmtNVz/iOByM1Mpf IoeoxiLsZFkQp2++Qrn3fFc6kTaT0XviV8ZwOQBaXSTr0LlrEK7fb5PO/35iXT5U/9fyuOc3 V25NKqr2DN+XhSAzmer6UBan27nmCN3G9fKNctuOzubgHiawtXEsdiOQ==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH 4/5] devtool: ide-sdk: allow combining shared and modified modes Date: Sun, 27 Sep 2026 19:44:52 +0200 Message-ID: <20260927174506.652690-5-adrian.freihofer@siemens.com> In-Reply-To: <20260927174506.652690-1-adrian.freihofer@siemens.com> References: <20260927174506.652690-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sun, 27 Sep 2026 17:45:19 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/246705 From: Adrian Freihofer Modified mode sets up the IDE for devtool-modified recipes, while shared mode provides a standalone cross-toolchain and sysroots for work outside those recipe workspaces. Previously these workflows needed separate ide-sdk invocations, potentially building the same image twice. Accept repeated --mode flags to run both workflows together. Modified recipes still get their recipe-specific IDE configurations; the shared environment can also be sourced to build other source code with the cross-toolchain. When an image is supplied, its rootfs-dbg provides debug symbols and sources for image-backed debugging, and --nfs can export that rootfs for a running target. Collect image settings from both workflows, build the image once, then populate shared sysroots and generate both sets of IDE configurations. Either mode can still be selected alone, and modified remains the default when --mode is omitted. For example, after devtool modify cmake-example: devtool ide-sdk -m modified -m shared \ cmake-example core-image-minimal --ide=code --nfs=rootfs-dbg From the build directory, open the modified recipe's generated IDE configuration: code workspace/sources/cmake-example In another shell in the build directory, source the shared SDK environment to build other source code with its cross-toolchain: . tmp/deploy/images/*/environment-setup-* cd /path/to/other/source make --- scripts/lib/devtool/ide_sdk.py | 55 +++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index ac07dae656..9faf041957 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -1732,6 +1732,8 @@ class RecipeModified: def ide_setup(args, config, basepath, workspace): """Generate the IDE configuration for the workspace""" + modes = set(args.mode or [DevtoolIdeMode.modified]) + # Explicitely passing some special recipes does not make sense for recipe in args.recipenames: if recipe in ['meta-ide-support', 'build-sysroots']: @@ -1780,8 +1782,8 @@ def ide_setup(args, config, basepath, workspace): recipes_other_names.append(recipe) invalid_params = False - if args.mode == DevtoolIdeMode.shared: - if len(recipes_modified_names): + if DevtoolIdeMode.shared in modes: + if recipes_modified_names and DevtoolIdeMode.modified not in modes: logger.error("In shared sysroots mode modified recipes %s cannot be handled." % str( recipes_modified_names)) invalid_params = True @@ -1791,7 +1793,7 @@ def ide_setup(args, config, basepath, workspace): if args.nfs_extract_dir and not args.nfs: logger.error("--nfs-extract-dir requires --nfs.") invalid_params = True - if args.mode == DevtoolIdeMode.modified: + if DevtoolIdeMode.modified in modes: if not recipes_modified_names: appends_dir = os.path.join(config.workspace_path, 'appends') recipes_modified_names = sorted( @@ -1802,7 +1804,7 @@ def ide_setup(args, config, basepath, workspace): logger.info( "No modified recipes specified, using workspace bbappends from %s: %s", appends_dir, ', '.join(recipes_modified_names)) - if len(recipes_other_names): + if recipes_other_names and DevtoolIdeMode.shared not in modes: logger.error("Only in shared sysroots mode not modified recipes %s can be handled." % str( recipes_other_names)) invalid_params = True @@ -1849,7 +1851,7 @@ def ide_setup(args, config, basepath, workspace): # Provide a Direct SDK with shared sysroots recipes_not_modified = [] - if args.mode == DevtoolIdeMode.shared: + if DevtoolIdeMode.shared in modes: ide_support = RecipeMetaIdeSupport() ide_support.initialize(config, tinfoil) bootstrap_tasks += ide_support.bootstrap_tasks @@ -1875,7 +1877,7 @@ def ide_setup(args, config, basepath, workspace): config, tinfoil, recipes_images, recipe_name) recipes_modified = [] - if args.mode == DevtoolIdeMode.modified: + if DevtoolIdeMode.modified in modes: logger.info("Setting up workspaces for modified recipe: %s" % str(recipes_modified_names)) DebuggerCrossConfig._port_next = int(args.gdbserver_port_start) @@ -1920,7 +1922,7 @@ def ide_setup(args, config, basepath, workspace): if recipe_modified.update_bbappend(): recipe_bbappend_changed = True shared_bbappend_changed = False - if args.mode == DevtoolIdeMode.shared: + if modes == {DevtoolIdeMode.shared}: for image in recipes_images: if image.extra_image_install_debugfs or args.nfs: if image.update_image_bbappend([], args.nfs): @@ -1945,28 +1947,20 @@ def ide_setup(args, config, basepath, workspace): exec_build_env_command( config.init_path, basepath, bb_cmd + ' '.join(bootstrap_tasks), watch=True) - if args.mode == DevtoolIdeMode.shared and image_bootstrap_tasks: + if modes == {DevtoolIdeMode.shared} and image_bootstrap_tasks: exec_build_env_command( config.init_path, basepath, bb_cmd + ' '.join(image_bootstrap_tasks), watch=True) - if bootstrap_tasks_late: + if modes == {DevtoolIdeMode.shared} and bootstrap_tasks_late: exec_build_env_command( config.init_path, basepath, bb_cmd + ' '.join(bootstrap_tasks_late), watch=True) - if args.mode == DevtoolIdeMode.shared: + if modes == {DevtoolIdeMode.shared}: if args.nfs and not args.skip_bitbake: for image in recipes_images: image.extract_nfs_rootfs(nfs_export_base_dir, args.nfs, args.target) - for ide in ides: - ide.setup_shared_sysroots(shared_env) - for image in recipes_images: - ide.setup_shared_image(args, shared_env, image, config.workspace_path) - for recipe_name in recipes_other_names: - ide.setup_shared_recipe( - args, shared_env, recipes_images[0] if recipes_images else None, - config.workspace_path, recipe_name) - elif args.mode == DevtoolIdeMode.modified: + if DevtoolIdeMode.modified in modes: for recipe_modified in recipes_modified: if recipe_modified.build_tool is BuildTool.CMAKE: recipe_modified.cmake_preset() @@ -2022,8 +2016,20 @@ def ide_setup(args, config, basepath, workspace): if args.nfs and not args.skip_bitbake: for ri in recipes_images: ri.extract_nfs_rootfs(nfs_export_base_dir, args.nfs, args.target) - else: - raise DevtoolError("Must not end up here.") + + if DevtoolIdeMode.shared in modes: + if DevtoolIdeMode.modified in modes and bootstrap_tasks_late and not args.skip_bitbake: + exec_build_env_command( + config.init_path, basepath, + bb_cmd + ' '.join(bootstrap_tasks_late), watch=True) + for ide in ides: + ide.setup_shared_sysroots(shared_env) + for image in recipes_images: + ide.setup_shared_image(args, shared_env, image, config.workspace_path) + for recipe_name in recipes_other_names: + ide.setup_shared_recipe( + args, shared_env, recipes_images[0] if recipes_images else None, + config.workspace_path, recipe_name) def register_commands(subparsers, context): @@ -2062,8 +2068,8 @@ def register_commands(subparsers, context): 'In modified mode at least the image recipe is required; if no modified recipe is passed, ' 'all modified recipes are taken from /appends/*.bbappend.') parser_ide_sdk.add_argument( - '-m', '--mode', type=DevtoolIdeMode, default=DevtoolIdeMode.modified, - help='Different SDK types are supported:\n' + '-m', '--mode', type=DevtoolIdeMode, action='append', + help='Different SDK types are supported. Repeat --mode to generate both:\n' '- "' + DevtoolIdeMode.modified.name + '" (default):\n' ' devtool modify creates a workspace to work on the source code of a recipe.\n' ' devtool ide-sdk builds the SDK and generates the IDE configuration(s) in the workspace directorie(s)\n' @@ -2080,7 +2086,8 @@ def register_commands(subparsers, context): ' An image recipe may also be supplied to build a target image and generate image-based IDE configurations.\n' ' With an image recipe, --nfs exports its rootfs for NFS booting.\n' ' To use this tool-chain the environment-* file found in the deploy..image folder needs to be sourced into a shell.\n' - ' In case of VSCode and cmake the tool-chain is also exposed as a cmake-kit') + ' In case of VSCode and cmake the tool-chain is also exposed as a cmake-kit.\n' + ' Combine with --mode modified to generate recipe IDE configurations and shared sysroots from one image build.') default_ide = list(ide_plugins.keys())[0] ide_choices = list(ide_plugins.keys()) + ['all'] parser_ide_sdk.add_argument( From patchwork Sun Sep 27 17:44:53 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 99381 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 090D3CA5FA3 for ; Sun, 27 Sep 2026 17:45:20 +0000 (UTC) Received: from mta-65-226.siemens.flowmailer.net (mta-65-226.siemens.flowmailer.net [185.136.65.226]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.41619.1790531113091884337 for ; Sun, 27 Sep 2026 10:45:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm1 header.b=g5RezzTk; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.226, mailfrom: fm-1329275-20260927174510732536f0c7000207cb-xc8koy@rts-flowmailer.siemens.com) Received: by mta-65-226.siemens.flowmailer.net with ESMTPSA id 20260927174510732536f0c7000207cb for ; Sun, 27 Sep 2026 19:45:10 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=/t1mdB3CLDkV7zroMXl0zkiYgDS6AAslpIReOpUTDxM=; b=g5RezzTkKIcG21h0HWbsQH+UYDZEG0yVlxUjbe1tyTz7oVr+tzxOxXibkRvUdefzQDuOvo S2PSlFk4VVfgzD6YPn5TtH/ebrFa8G8zRVgICu+CRdUR0i81hHZR/VId+l7QFSjP6aOzmDuF DVQDbKEuaQPobWWUT7Oi87vn2T6Uev3ahLdBu2wU32UbDiMXkfhgh3mJu4oaZlz3e/uNiNH5 jTwA3qKVV6pexjfalF9c1aY1KqRCN/ab9hZ8hMKjuiuFf3Ye4/sFrnGdNHU7GzZWmixXV0/Z YM0RfTXsF4QECbzMHqSYDEimXIPuzY4bKL/C/wwJ/3nOcAtyDcsOWZ/g==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH 5/5] oe-selftest: devtool ide-sdk: cover modified + shared + NFS Date: Sun, 27 Sep 2026 19:44:53 +0200 Message-ID: <20260927174506.652690-6-adrian.freihofer@siemens.com> In-Reply-To: <20260927174506.652690-1-adrian.freihofer@siemens.com> References: <20260927174506.652690-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sun, 27 Sep 2026 17:45:20 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/246703 From: Adrian Freihofer Run the existing VS Code NFS debug-rootfs test with both modified and shared modes enabled. Keep its image, recipe and debugger checks while also asserting that the shared environment script and standalone sysroot were generated. Reuse the existing test instead of adding a separate combined-mode test. --- meta/lib/oeqa/selftest/cases/devtool.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index a6002ec2b6..265f2147a4 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3612,7 +3612,7 @@ class DevtoolIdeSdkTests(DevtoolBase): """Verify a recipe's binary was extracted into the NFS debug rootfs.""" self.assertExists(os.path.join(nfs_rootfs, 'usr', 'bin', example_exe)) - def _test_code_nfs_debug_rootfs(self): + def _test_code_nfs_debug_rootfs(self, shared=False): """Verify ide-sdk extracts an NFS debug rootfs for VS Code debugging.""" recipe_name = self._cmake_recipe_name build_file = "CMakeLists.txt" @@ -3622,12 +3622,20 @@ class DevtoolIdeSdkTests(DevtoolBase): self._write_bb_config() tempdir = self._devtool_ide_sdk_recipe( recipe_name, build_file, testimage) - runCmd('devtool ide-sdk %s %s -c --ide=code --nfs=rootfs-dbg' % - (recipe_name, testimage), output_log=self._cmd_logger) + mode_opts = '-m modified -m shared ' if shared else '' + runCmd('devtool ide-sdk %s%s %s -c --ide=code --nfs=rootfs-dbg' % + (mode_opts, recipe_name, testimage), output_log=self._cmd_logger) nfs_rootfs, _ = self._verify_nfs_debug_rootfs(testimage, 'rootfs-dbg') self._verify_nfs_binary_deployed(nfs_rootfs, recipe_name) self._verify_nfs_launch_json(tempdir, nfs_rootfs) + if shared: + bb_vars = get_bb_vars( + ['REAL_MULTIMACH_TARGET_SYS', 'DEPLOY_DIR_IMAGE'], 'meta-ide-support') + self.assertExists(os.path.join( + bb_vars['DEPLOY_DIR_IMAGE'], + 'environment-setup-%s' % bb_vars['REAL_MULTIMACH_TARGET_SYS'])) + self.assertExists(get_bb_var('STANDALONE_SYSROOT', 'build-sysroots')) def _test_code_and_none_qemu(self, nfs=False, slirp=False): """Verify devtool ide-sdk --ide=code --ide=none for cmake, meson and the target toolchain. @@ -4300,7 +4308,7 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): def test_code_nfs_debug_rootfs(self): """Verify ide-sdk extracts an NFS debug rootfs for VS Code debugging.""" - self._test_code_nfs_debug_rootfs() + self._test_code_nfs_debug_rootfs(shared=True) @OETestTag("runqemu") def test_code_and_none_qemu(self):