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:
282
sources/poky/scripts/lib/devtool/ide_plugins/__init__.py
Normal file
282
sources/poky/scripts/lib/devtool/ide_plugins/__init__.py
Normal 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
|
||||
463
sources/poky/scripts/lib/devtool/ide_plugins/ide_code.py
Normal file
463
sources/poky/scripts/lib/devtool/ide_plugins/ide_code.py
Normal 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
|
||||
53
sources/poky/scripts/lib/devtool/ide_plugins/ide_none.py
Normal file
53
sources/poky/scripts/lib/devtool/ide_plugins/ide_none.py
Normal 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
|
||||
Reference in New Issue
Block a user