Complete Yocto mirror with license table for TQMa6UL (2038-compliance)

- 264 license table entries with exact download URLs (224/264 resolved)
- Complete sources/ directory with all BitBake recipes
- Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl)
- Full traceability for Softwarefreigabeantrag
- GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4
- License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
Siggi (OpenClaw Agent)
2026-03-01 20:58:18 +00:00
commit 16accb6b24
15086 changed files with 1292356 additions and 0 deletions

View File

@@ -0,0 +1,282 @@
#
# Copyright (C) 2023-2024 Siemens AG
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""Devtool ide-sdk IDE plugin interface definition and helper functions"""
import errno
import json
import logging
import os
import stat
from enum import Enum, auto
from devtool import DevtoolError
from bb.utils import mkdirhier
logger = logging.getLogger('devtool')
class BuildTool(Enum):
UNDEFINED = auto()
CMAKE = auto()
MESON = auto()
@property
def is_c_ccp(self):
if self is BuildTool.CMAKE:
return True
if self is BuildTool.MESON:
return True
return False
class GdbCrossConfig:
"""Base class defining the GDB configuration generator interface
Generate a GDB configuration for a binary on the target device.
Only one instance per binary is allowed. This allows to assign unique port
numbers for all gdbserver instances.
"""
_gdbserver_port_next = 1234
_binaries = []
def __init__(self, image_recipe, modified_recipe, binary, gdbserver_multi=True):
self.image_recipe = image_recipe
self.modified_recipe = modified_recipe
self.gdb_cross = modified_recipe.gdb_cross
self.binary = binary
if binary in GdbCrossConfig._binaries:
raise DevtoolError(
"gdbserver config for binary %s is already generated" % binary)
GdbCrossConfig._binaries.append(binary)
self.script_dir = modified_recipe.ide_sdk_scripts_dir
self.gdbinit_dir = os.path.join(self.script_dir, 'gdbinit')
self.gdbserver_multi = gdbserver_multi
self.binary_pretty = self.binary.replace(os.sep, '-').lstrip('-')
self.gdbserver_port = GdbCrossConfig._gdbserver_port_next
GdbCrossConfig._gdbserver_port_next += 1
self.id_pretty = "%d_%s" % (self.gdbserver_port, self.binary_pretty)
# gdbserver start script
gdbserver_script_file = 'gdbserver_' + self.id_pretty
if self.gdbserver_multi:
gdbserver_script_file += "_m"
self.gdbserver_script = os.path.join(
self.script_dir, gdbserver_script_file)
# gdbinit file
self.gdbinit = os.path.join(
self.gdbinit_dir, 'gdbinit_' + self.id_pretty)
# gdb start script
self.gdb_script = os.path.join(
self.script_dir, 'gdb_' + self.id_pretty)
def _gen_gdbserver_start_script(self):
"""Generate a shell command starting the gdbserver on the remote device via ssh
GDB supports two modes:
multi: gdbserver remains running over several debug sessions
once: gdbserver terminates after the debugged process terminates
"""
cmd_lines = ['#!/bin/sh']
if self.gdbserver_multi:
temp_dir = "TEMP_DIR=/tmp/gdbserver_%s; " % self.id_pretty
gdbserver_cmd_start = temp_dir
gdbserver_cmd_start += "test -f \\$TEMP_DIR/pid && exit 0; "
gdbserver_cmd_start += "mkdir -p \\$TEMP_DIR; "
gdbserver_cmd_start += "%s --multi :%s > \\$TEMP_DIR/log 2>&1 & " % (
self.gdb_cross.gdbserver_path, self.gdbserver_port)
gdbserver_cmd_start += "echo \\$! > \\$TEMP_DIR/pid;"
gdbserver_cmd_stop = temp_dir
gdbserver_cmd_stop += "test -f \\$TEMP_DIR/pid && kill \\$(cat \\$TEMP_DIR/pid); "
gdbserver_cmd_stop += "rm -rf \\$TEMP_DIR; "
gdbserver_cmd_l = []
gdbserver_cmd_l.append('if [ "$1" = "stop" ]; then')
gdbserver_cmd_l.append(' shift')
gdbserver_cmd_l.append(" %s %s %s %s 'sh -c \"%s\"'" % (
self.gdb_cross.target_device.ssh_sshexec, self.gdb_cross.target_device.ssh_port, self.gdb_cross.target_device.extraoptions, self.gdb_cross.target_device.target, gdbserver_cmd_stop))
gdbserver_cmd_l.append('else')
gdbserver_cmd_l.append(" %s %s %s %s 'sh -c \"%s\"'" % (
self.gdb_cross.target_device.ssh_sshexec, self.gdb_cross.target_device.ssh_port, self.gdb_cross.target_device.extraoptions, self.gdb_cross.target_device.target, gdbserver_cmd_start))
gdbserver_cmd_l.append('fi')
gdbserver_cmd = os.linesep.join(gdbserver_cmd_l)
else:
gdbserver_cmd_start = "%s --once :%s %s" % (
self.gdb_cross.gdbserver_path, self.gdbserver_port, self.binary)
gdbserver_cmd = "%s %s %s %s 'sh -c \"%s\"'" % (
self.gdb_cross.target_device.ssh_sshexec, self.gdb_cross.target_device.ssh_port, self.gdb_cross.target_device.extraoptions, self.gdb_cross.target_device.target, gdbserver_cmd_start)
cmd_lines.append(gdbserver_cmd)
GdbCrossConfig.write_file(self.gdbserver_script, cmd_lines, True)
def _gen_gdbinit_config(self):
"""Generate a gdbinit file for this binary and the corresponding gdbserver configuration"""
gdbinit_lines = ['# This file is generated by devtool ide-sdk']
if self.gdbserver_multi:
target_help = '# gdbserver --multi :%d' % self.gdbserver_port
remote_cmd = 'target extended-remote'
else:
target_help = '# gdbserver :%d %s' % (
self.gdbserver_port, self.binary)
remote_cmd = 'target remote'
gdbinit_lines.append('# On the remote target:')
gdbinit_lines.append(target_help)
gdbinit_lines.append('# On the build machine:')
gdbinit_lines.append('# cd ' + self.modified_recipe.real_srctree)
gdbinit_lines.append(
'# ' + self.gdb_cross.gdb + ' -ix ' + self.gdbinit)
gdbinit_lines.append('set sysroot ' + self.modified_recipe.d)
gdbinit_lines.append('set substitute-path "/usr/include" "' +
os.path.join(self.modified_recipe.recipe_sysroot, 'usr', 'include') + '"')
# Disable debuginfod for now, the IDE configuration uses rootfs-dbg from the image workdir.
gdbinit_lines.append('set debuginfod enabled off')
if self.image_recipe.rootfs_dbg:
gdbinit_lines.append(
'set solib-search-path "' + self.modified_recipe.solib_search_path_str(self.image_recipe) + '"')
# First: Search for sources of this recipe in the workspace folder
if self.modified_recipe.pn in self.modified_recipe.target_dbgsrc_dir:
gdbinit_lines.append('set substitute-path "%s" "%s"' %
(self.modified_recipe.target_dbgsrc_dir, self.modified_recipe.real_srctree))
else:
logger.error(
"TARGET_DBGSRC_DIR must contain the recipe name PN.")
# Second: Search for sources of other recipes in the rootfs-dbg
if self.modified_recipe.target_dbgsrc_dir.startswith("/usr/src/debug"):
gdbinit_lines.append('set substitute-path "/usr/src/debug" "%s"' % os.path.join(
self.image_recipe.rootfs_dbg, "usr", "src", "debug"))
else:
logger.error(
"TARGET_DBGSRC_DIR must start with /usr/src/debug.")
else:
logger.warning(
"Cannot setup debug symbols configuration for GDB. IMAGE_GEN_DEBUGFS is not enabled.")
gdbinit_lines.append(
'%s %s:%d' % (remote_cmd, self.gdb_cross.host, self.gdbserver_port))
gdbinit_lines.append('set remote exec-file ' + self.binary)
gdbinit_lines.append(
'run ' + os.path.join(self.modified_recipe.d, self.binary))
GdbCrossConfig.write_file(self.gdbinit, gdbinit_lines)
def _gen_gdb_start_script(self):
"""Generate a script starting GDB with the corresponding gdbinit configuration."""
cmd_lines = ['#!/bin/sh']
cmd_lines.append('cd ' + self.modified_recipe.real_srctree)
cmd_lines.append(self.gdb_cross.gdb + ' -ix ' +
self.gdbinit + ' "$@"')
GdbCrossConfig.write_file(self.gdb_script, cmd_lines, True)
def initialize(self):
self._gen_gdbserver_start_script()
self._gen_gdbinit_config()
self._gen_gdb_start_script()
@staticmethod
def write_file(script_file, cmd_lines, executable=False):
script_dir = os.path.dirname(script_file)
mkdirhier(script_dir)
with open(script_file, 'w') as script_f:
script_f.write(os.linesep.join(cmd_lines))
script_f.write(os.linesep)
if executable:
st = os.stat(script_file)
os.chmod(script_file, st.st_mode | stat.S_IEXEC)
logger.info("Created: %s" % script_file)
class IdeBase:
"""Base class defining the interface for IDE plugins"""
def __init__(self):
self.ide_name = 'undefined'
self.gdb_cross_configs = []
@classmethod
def ide_plugin_priority(cls):
"""Used to find the default ide handler if --ide is not passed"""
return 10
def setup_shared_sysroots(self, shared_env):
logger.warn("Shared sysroot mode is not supported for IDE %s" %
self.ide_name)
def setup_modified_recipe(self, args, image_recipe, modified_recipe):
logger.warn("Modified recipe mode is not supported for IDE %s" %
self.ide_name)
def initialize_gdb_cross_configs(self, image_recipe, modified_recipe, gdb_cross_config_class=GdbCrossConfig):
binaries = modified_recipe.find_installed_binaries()
for binary in binaries:
gdb_cross_config = gdb_cross_config_class(
image_recipe, modified_recipe, binary)
gdb_cross_config.initialize()
self.gdb_cross_configs.append(gdb_cross_config)
@staticmethod
def gen_oe_scrtips_sym_link(modified_recipe):
# create a sym-link from sources to the scripts directory
if os.path.isdir(modified_recipe.ide_sdk_scripts_dir):
IdeBase.symlink_force(modified_recipe.ide_sdk_scripts_dir,
os.path.join(modified_recipe.real_srctree, 'oe-scripts'))
@staticmethod
def update_json_file(json_dir, json_file, update_dict):
"""Update a json file
By default it uses the dict.update function. If this is not sutiable
the update function might be passed via update_func parameter.
"""
json_path = os.path.join(json_dir, json_file)
logger.info("Updating IDE config file: %s (%s)" %
(json_file, json_path))
if not os.path.exists(json_dir):
os.makedirs(json_dir)
try:
with open(json_path) as f:
orig_dict = json.load(f)
except json.decoder.JSONDecodeError:
logger.info(
"Decoding %s failed. Probably because of comments in the json file" % json_path)
orig_dict = {}
except FileNotFoundError:
orig_dict = {}
orig_dict.update(update_dict)
with open(json_path, 'w') as f:
json.dump(orig_dict, f, indent=4)
@staticmethod
def symlink_force(tgt, dst):
try:
os.symlink(tgt, dst)
except OSError as err:
if err.errno == errno.EEXIST:
if os.readlink(dst) != tgt:
os.remove(dst)
os.symlink(tgt, dst)
else:
raise err
def get_devtool_deploy_opts(args):
"""Filter args for devtool deploy-target args"""
if not args.target:
return None
devtool_deploy_opts = [args.target]
if args.no_host_check:
devtool_deploy_opts += ["-c"]
if args.show_status:
devtool_deploy_opts += ["-s"]
if args.no_preserve:
devtool_deploy_opts += ["-p"]
if args.no_check_space:
devtool_deploy_opts += ["--no-check-space"]
if args.ssh_exec:
devtool_deploy_opts += ["-e", args.ssh.exec]
if args.port:
devtool_deploy_opts += ["-P", args.port]
if args.key:
devtool_deploy_opts += ["-I", args.key]
if args.strip is False:
devtool_deploy_opts += ["--no-strip"]
return devtool_deploy_opts

View File

@@ -0,0 +1,463 @@
#
# Copyright (C) 2023-2024 Siemens AG
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""Devtool ide-sdk IDE plugin for VSCode and VSCodium"""
import json
import logging
import os
import shutil
from devtool.ide_plugins import BuildTool, IdeBase, GdbCrossConfig, get_devtool_deploy_opts
logger = logging.getLogger('devtool')
class GdbCrossConfigVSCode(GdbCrossConfig):
def __init__(self, image_recipe, modified_recipe, binary):
super().__init__(image_recipe, modified_recipe, binary, False)
def initialize(self):
self._gen_gdbserver_start_script()
class IdeVSCode(IdeBase):
"""Manage IDE configurations for VSCode
Modified recipe mode:
- cmake: use the cmake-preset generated by devtool ide-sdk
- meson: meson is called via a wrapper script generated by devtool ide-sdk
Shared sysroot mode:
In shared sysroot mode, the cross tool-chain is exported to the user's global configuration.
A workspace cannot be created because there is no recipe that defines how a workspace could
be set up.
- cmake: adds a cmake-kit to .local/share/CMakeTools/cmake-tools-kits.json
The cmake-kit uses the environment script and the tool-chain file
generated by meta-ide-support.
- meson: Meson needs manual workspace configuration.
"""
@classmethod
def ide_plugin_priority(cls):
"""If --ide is not passed this is the default plugin"""
if shutil.which('code'):
return 100
return 0
def setup_shared_sysroots(self, shared_env):
"""Expose the toolchain of the shared sysroots SDK"""
datadir = shared_env.ide_support.datadir
deploy_dir_image = shared_env.ide_support.deploy_dir_image
real_multimach_target_sys = shared_env.ide_support.real_multimach_target_sys
standalone_sysroot_native = shared_env.build_sysroots.standalone_sysroot_native
vscode_ws_path = os.path.join(
os.environ['HOME'], '.local', 'share', 'CMakeTools')
cmake_kits_path = os.path.join(vscode_ws_path, 'cmake-tools-kits.json')
oecmake_generator = "Ninja"
env_script = os.path.join(
deploy_dir_image, 'environment-setup-' + real_multimach_target_sys)
if not os.path.isdir(vscode_ws_path):
os.makedirs(vscode_ws_path)
cmake_kits_old = []
if os.path.exists(cmake_kits_path):
with open(cmake_kits_path, 'r', encoding='utf-8') as cmake_kits_file:
cmake_kits_old = json.load(cmake_kits_file)
cmake_kits = cmake_kits_old.copy()
cmake_kit_new = {
"name": "OE " + real_multimach_target_sys,
"environmentSetupScript": env_script,
"toolchainFile": standalone_sysroot_native + datadir + "/cmake/OEToolchainConfig.cmake",
"preferredGenerator": {
"name": oecmake_generator
}
}
def merge_kit(cmake_kits, cmake_kit_new):
i = 0
while i < len(cmake_kits):
if 'environmentSetupScript' in cmake_kits[i] and \
cmake_kits[i]['environmentSetupScript'] == cmake_kit_new['environmentSetupScript']:
cmake_kits[i] = cmake_kit_new
return
i += 1
cmake_kits.append(cmake_kit_new)
merge_kit(cmake_kits, cmake_kit_new)
if cmake_kits != cmake_kits_old:
logger.info("Updating: %s" % cmake_kits_path)
with open(cmake_kits_path, 'w', encoding='utf-8') as cmake_kits_file:
json.dump(cmake_kits, cmake_kits_file, indent=4)
else:
logger.info("Already up to date: %s" % cmake_kits_path)
cmake_native = os.path.join(
shared_env.build_sysroots.standalone_sysroot_native, 'usr', 'bin', 'cmake')
if os.path.isfile(cmake_native):
logger.info('cmake-kits call cmake by default. If the cmake provided by this SDK should be used, please add the following line to ".vscode/settings.json" file: "cmake.cmakePath": "%s"' % cmake_native)
else:
logger.error("Cannot find cmake native at: %s" % cmake_native)
def dot_code_dir(self, modified_recipe):
return os.path.join(modified_recipe.srctree, '.vscode')
def __vscode_settings_meson(self, settings_dict, modified_recipe):
if modified_recipe.build_tool is not BuildTool.MESON:
return
settings_dict["mesonbuild.mesonPath"] = modified_recipe.meson_wrapper
confopts = modified_recipe.mesonopts.split()
confopts += modified_recipe.meson_cross_file.split()
confopts += modified_recipe.extra_oemeson.split()
settings_dict["mesonbuild.configureOptions"] = confopts
settings_dict["mesonbuild.buildFolder"] = modified_recipe.b
def __vscode_settings_cmake(self, settings_dict, modified_recipe):
"""Add cmake specific settings to settings.json.
Note: most settings are passed to the cmake preset.
"""
if modified_recipe.build_tool is not BuildTool.CMAKE:
return
settings_dict["cmake.configureOnOpen"] = True
settings_dict["cmake.sourceDirectory"] = modified_recipe.real_srctree
def vscode_settings(self, modified_recipe, image_recipe):
files_excludes = {
"**/.git/**": True,
"**/oe-logs/**": True,
"**/oe-workdir/**": True,
"**/source-date-epoch/**": True
}
python_exclude = [
"**/.git/**",
"**/oe-logs/**",
"**/oe-workdir/**",
"**/source-date-epoch/**"
]
files_readonly = {
modified_recipe.recipe_sysroot + '/**': True,
modified_recipe.recipe_sysroot_native + '/**': True,
}
if image_recipe.rootfs_dbg is not None:
files_readonly[image_recipe.rootfs_dbg + '/**'] = True
settings_dict = {
"files.watcherExclude": files_excludes,
"files.exclude": files_excludes,
"files.readonlyInclude": files_readonly,
"python.analysis.exclude": python_exclude
}
self.__vscode_settings_cmake(settings_dict, modified_recipe)
self.__vscode_settings_meson(settings_dict, modified_recipe)
settings_file = 'settings.json'
IdeBase.update_json_file(
self.dot_code_dir(modified_recipe), settings_file, settings_dict)
def __vscode_extensions_cmake(self, modified_recipe, recommendations):
if modified_recipe.build_tool is not BuildTool.CMAKE:
return
recommendations += [
"twxs.cmake",
"ms-vscode.cmake-tools",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.cpptools-themes"
]
def __vscode_extensions_meson(self, modified_recipe, recommendations):
if modified_recipe.build_tool is not BuildTool.MESON:
return
recommendations += [
'mesonbuild.mesonbuild',
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.cpptools-themes"
]
def vscode_extensions(self, modified_recipe):
recommendations = []
self.__vscode_extensions_cmake(modified_recipe, recommendations)
self.__vscode_extensions_meson(modified_recipe, recommendations)
extensions_file = 'extensions.json'
IdeBase.update_json_file(
self.dot_code_dir(modified_recipe), extensions_file, {"recommendations": recommendations})
def vscode_c_cpp_properties(self, modified_recipe):
properties_dict = {
"name": modified_recipe.recipe_id_pretty,
}
if modified_recipe.build_tool is BuildTool.CMAKE:
properties_dict["configurationProvider"] = "ms-vscode.cmake-tools"
elif modified_recipe.build_tool is BuildTool.MESON:
properties_dict["configurationProvider"] = "mesonbuild.mesonbuild"
properties_dict["compilerPath"] = os.path.join(modified_recipe.staging_bindir_toolchain, modified_recipe.cxx.split()[0])
else: # no C/C++ build
return
properties_dicts = {
"configurations": [
properties_dict
],
"version": 4
}
prop_file = 'c_cpp_properties.json'
IdeBase.update_json_file(
self.dot_code_dir(modified_recipe), prop_file, properties_dicts)
def vscode_launch_bin_dbg(self, gdb_cross_config):
modified_recipe = gdb_cross_config.modified_recipe
launch_config = {
"name": gdb_cross_config.id_pretty,
"type": "cppdbg",
"request": "launch",
"program": os.path.join(modified_recipe.d, gdb_cross_config.binary.lstrip('/')),
"stopAtEntry": True,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": False,
"MIMode": "gdb",
"preLaunchTask": gdb_cross_config.id_pretty,
"miDebuggerPath": modified_recipe.gdb_cross.gdb,
"miDebuggerServerAddress": "%s:%d" % (modified_recipe.gdb_cross.host, gdb_cross_config.gdbserver_port)
}
# Search for header files in recipe-sysroot.
src_file_map = {
"/usr/include": os.path.join(modified_recipe.recipe_sysroot, "usr", "include")
}
# First of all search for not stripped binaries in the image folder.
# These binaries are copied (and optionally stripped) by deploy-target
setup_commands = [
{
"description": "sysroot",
"text": "set sysroot " + modified_recipe.d
}
]
if gdb_cross_config.image_recipe.rootfs_dbg:
launch_config['additionalSOLibSearchPath'] = modified_recipe.solib_search_path_str(
gdb_cross_config.image_recipe)
# First: Search for sources of this recipe in the workspace folder
if modified_recipe.pn in modified_recipe.target_dbgsrc_dir:
src_file_map[modified_recipe.target_dbgsrc_dir] = "${workspaceFolder}"
else:
logger.error(
"TARGET_DBGSRC_DIR must contain the recipe name PN.")
# Second: Search for sources of other recipes in the rootfs-dbg
if modified_recipe.target_dbgsrc_dir.startswith("/usr/src/debug"):
src_file_map["/usr/src/debug"] = os.path.join(
gdb_cross_config.image_recipe.rootfs_dbg, "usr", "src", "debug")
else:
logger.error(
"TARGET_DBGSRC_DIR must start with /usr/src/debug.")
else:
logger.warning(
"Cannot setup debug symbols configuration for GDB. IMAGE_GEN_DEBUGFS is not enabled.")
launch_config['sourceFileMap'] = src_file_map
launch_config['setupCommands'] = setup_commands
return launch_config
def vscode_launch(self, modified_recipe):
"""GDB Launch configuration for binaries (elf files)"""
configurations = []
for gdb_cross_config in self.gdb_cross_configs:
if gdb_cross_config.modified_recipe is modified_recipe:
configurations.append(self.vscode_launch_bin_dbg(gdb_cross_config))
launch_dict = {
"version": "0.2.0",
"configurations": configurations
}
launch_file = 'launch.json'
IdeBase.update_json_file(
self.dot_code_dir(modified_recipe), launch_file, launch_dict)
def vscode_tasks_cpp(self, args, modified_recipe):
run_install_deploy = modified_recipe.gen_install_deploy_script(args)
install_task_name = "install && deploy-target %s" % modified_recipe.recipe_id_pretty
tasks_dict = {
"version": "2.0.0",
"tasks": [
{
"label": install_task_name,
"type": "shell",
"command": run_install_deploy,
"problemMatcher": []
}
]
}
for gdb_cross_config in self.gdb_cross_configs:
if gdb_cross_config.modified_recipe is not modified_recipe:
continue
tasks_dict['tasks'].append(
{
"label": gdb_cross_config.id_pretty,
"type": "shell",
"isBackground": True,
"dependsOn": [
install_task_name
],
"command": gdb_cross_config.gdbserver_script,
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": True,
"beginsPattern": ".",
"endsPattern": ".",
}
}
]
})
tasks_file = 'tasks.json'
IdeBase.update_json_file(
self.dot_code_dir(modified_recipe), tasks_file, tasks_dict)
def vscode_tasks_fallback(self, args, 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)
dt_build = "devtool build "
dt_build_label = dt_build + modified_recipe.recipe_id_pretty
dt_build_cmd = dt_build + modified_recipe.bpn
clean_opt = " --clean"
dt_build_clean_label = dt_build + modified_recipe.recipe_id_pretty + clean_opt
dt_build_clean_cmd = dt_build + modified_recipe.bpn + clean_opt
dt_deploy = "devtool deploy-target "
dt_deploy_label = dt_deploy + modified_recipe.recipe_id_pretty
dt_deploy_cmd = dt_deploy + modified_recipe.bpn
dt_build_deploy_label = "devtool build & deploy-target %s" % modified_recipe.recipe_id_pretty
deploy_opts = ' '.join(get_devtool_deploy_opts(args))
tasks_dict = {
"version": "2.0.0",
"tasks": [
{
"label": dt_build_label,
"type": "shell",
"command": "bash",
"linux": {
"options": {
"cwd": oe_init_dir
}
},
"args": [
"--login",
"-c",
"%s%s" % (oe_init, dt_build_cmd)
],
"problemMatcher": []
},
{
"label": dt_deploy_label,
"type": "shell",
"command": "bash",
"linux": {
"options": {
"cwd": oe_init_dir
}
},
"args": [
"--login",
"-c",
"%s%s %s" % (
oe_init, dt_deploy_cmd, deploy_opts)
],
"problemMatcher": []
},
{
"label": dt_build_deploy_label,
"dependsOrder": "sequence",
"dependsOn": [
dt_build_label,
dt_deploy_label
],
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": True
}
},
{
"label": dt_build_clean_label,
"type": "shell",
"command": "bash",
"linux": {
"options": {
"cwd": oe_init_dir
}
},
"args": [
"--login",
"-c",
"%s%s" % (oe_init, dt_build_clean_cmd)
],
"problemMatcher": []
}
]
}
if modified_recipe.gdb_cross:
for gdb_cross_config in self.gdb_cross_configs:
if gdb_cross_config.modified_recipe is not modified_recipe:
continue
tasks_dict['tasks'].append(
{
"label": gdb_cross_config.id_pretty,
"type": "shell",
"isBackground": True,
"dependsOn": [
dt_build_deploy_label
],
"command": gdb_cross_config.gdbserver_script,
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": True,
"beginsPattern": ".",
"endsPattern": ".",
}
}
]
})
tasks_file = 'tasks.json'
IdeBase.update_json_file(
self.dot_code_dir(modified_recipe), tasks_file, tasks_dict)
def vscode_tasks(self, args, modified_recipe):
if modified_recipe.build_tool.is_c_ccp:
self.vscode_tasks_cpp(args, modified_recipe)
else:
self.vscode_tasks_fallback(args, modified_recipe)
def setup_modified_recipe(self, args, image_recipe, modified_recipe):
self.vscode_settings(modified_recipe, image_recipe)
self.vscode_extensions(modified_recipe)
self.vscode_c_cpp_properties(modified_recipe)
if args.target:
self.initialize_gdb_cross_configs(
image_recipe, modified_recipe, gdb_cross_config_class=GdbCrossConfigVSCode)
self.vscode_launch(modified_recipe)
self.vscode_tasks(args, modified_recipe)
def register_ide_plugin(ide_plugins):
ide_plugins['code'] = IdeVSCode

View File

@@ -0,0 +1,53 @@
#
# Copyright (C) 2023-2024 Siemens AG
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""Devtool ide-sdk generic IDE plugin"""
import os
import logging
from devtool.ide_plugins import IdeBase, GdbCrossConfig
logger = logging.getLogger('devtool')
class IdeNone(IdeBase):
"""Generate some generic helpers for other IDEs
Modified recipe mode:
Generate some helper scripts for remote debugging with GDB
Shared sysroot mode:
A wrapper for bitbake meta-ide-support and bitbake build-sysroots
"""
def __init__(self):
super().__init__()
def setup_shared_sysroots(self, shared_env):
real_multimach_target_sys = shared_env.ide_support.real_multimach_target_sys
deploy_dir_image = shared_env.ide_support.deploy_dir_image
env_script = os.path.join(
deploy_dir_image, 'environment-setup-' + real_multimach_target_sys)
logger.info(
"To use this SDK please source this: %s" % env_script)
def setup_modified_recipe(self, args, image_recipe, modified_recipe):
"""generate some helper scripts and config files
- Execute the do_install task
- Execute devtool deploy-target
- Generate a gdbinit file per executable
- Generate the oe-scripts sym-link
"""
script_path = modified_recipe.gen_install_deploy_script(args)
logger.info("Created: %s" % script_path)
self.initialize_gdb_cross_configs(image_recipe, modified_recipe)
IdeBase.gen_oe_scrtips_sym_link(modified_recipe)
def register_ide_plugin(ide_plugins):
ide_plugins['none'] = IdeNone