[PATCH] bitbake-setup: pass install-buildtools options from config and CLI
Jaipaul Cheernam <[email protected]> Mon, 15 Jun 2026 14:18:56 +0200
| Newsgroups | org.openembedded.lists.bitbake-devel |
|---|---|
| Message-ID | <[email protected]> |
Allow distro-specific buildtools to be configured with a custom URL, filename, and SDK name via an install-buildtools section in config-upstream.json. Expose the same options as CLI arguments: --url, --filename, --sdk-name, --no-check. CLI arguments take precedence over config values. This requires the --sdk-name option to be available in oe-scripts/install-buildtools from openembedded-core. AI-Generated: Kiro with Claude Opus 4.6 Signed-off-by: Jaipaul Cheernam <[email protected]> --- bin/bitbake-setup | 49 +++++++++++- .../bitbake-user-manual-environment-setup.rst | 33 ++++++++ lib/bb/tests/setup.py | 80 ++++++++++++++++++- setup-schema/bitbake-setup.schema.json | 30 +++++++ 4 files changed, 188 insertions(+), 4 deletions(-) diff --git a/bin/bitbake-setup b/bin/bitbake-setup index fe3b6b0e6..343d428e8 100755 --- a/bin/bitbake-setup +++ b/bin/bitbake-setup @@ -1052,10 +1052,49 @@ def install_buildtools(top_dir, settings, args, d): return shutil.rmtree(buildtools_install_dir) - install_buildtools = os.path.join(args.setup_dir, 'layers/oe-scripts/install-buildtools') + install_buildtools_script = os.path.join(args.setup_dir, 'layers/oe-scripts/install-buildtools') buildtools_download_dir = add_unique_timestamp_to_path(os.path.join(args.setup_dir, 'buildtools-downloads/buildtools')) + + buildtools_config = {} + upstream_config_path = os.path.join(args.setup_dir, 'config', 'config-upstream.json') + try: + with open(upstream_config_path) as f: + upstream_config = json.load(f) + buildtools_config = upstream_config.get('data', {}).get('bitbake-setup', {}).get('install-buildtools', {}) + except FileNotFoundError: + pass + except json.JSONDecodeError as e: + logger.error("Failed to parse %s: %s" % (upstream_config_path, e)) + sys.exit(1) + + url = args.url if args.url is not None else buildtools_config.get('url') + filename = args.filename if args.filename is not None else buildtools_config.get('filename') + sdk_name = args.sdk_name if args.sdk_name is not None else buildtools_config.get('sdk-name') + + for name, value in (("url", url), ("filename", filename), ("sdk-name", sdk_name)): + if value == "": + logger.error("%s is empty" % name) + sys.exit(1) + no_check = args.no_check if args.no_check is not None else buildtools_config.get('no-check', False) + + if (url is None) != (filename is None): + logger.error("url and filename must both be set (from CLI or config) or both omitted") + sys.exit(1) + + cmd = [ + install_buildtools_script, + '-d', buildtools_install_dir, + '--downloads-directory', buildtools_download_dir, + ] + if url and filename: + cmd += ['--url', url, '--filename', filename] + if sdk_name: + cmd += ['--sdk-name', sdk_name] + if no_check: + cmd.append('--no-check') + logger.plain("Buildtools archive is downloaded into {} and its content installed into {}".format(buildtools_download_dir, buildtools_install_dir)) - subprocess.check_call("{} -d {} --downloads-directory {}".format(install_buildtools, buildtools_install_dir, buildtools_download_dir), shell=True) + subprocess.check_call(cmd) def create_siteconf(top_dir, non_interactive, settings): siteconfpath = os.path.join(top_dir, 'site.conf') @@ -1285,6 +1324,12 @@ def main(): parser_install_buildtools = subparsers.add_parser('install-buildtools', help='Install buildtools which can help fulfil missing or incorrect dependencies on the host machine') add_setup_dir_arg(parser_install_buildtools) parser_install_buildtools.add_argument('--force', action='store_true', help='Force a reinstall of buildtools over the previous installation.') + parser_install_buildtools.add_argument('--url', action='store', help='URL from where to fetch the buildtools SDK installer, not including filename. Requires --filename. Overrides config value.') + parser_install_buildtools.add_argument('--filename', action='store', help='Filename for the buildtools SDK installer. Requires --url. Overrides config value.') + parser_install_buildtools.add_argument('--sdk-name', action='store', default=None, help='SDK name used in the environment setup script (e.g. customsdk). Overrides config value.') + check_group = parser_install_buildtools.add_mutually_exclusive_group() + check_group.add_argument('--no-check', action='store_const', const=True, default=None, dest='no_check', help='Disable checksum validation. Overrides config value.') + check_group.add_argument('--check', action='store_const', const=False, dest='no_check', help='Enable checksum validation. Overrides config no-check: true.') parser_install_buildtools.set_defaults(func=install_buildtools) parser_settings_arg_global = argparse.ArgumentParser(add_help=False) diff --git a/doc/bitbake-user-manual/bitbake-user-manual-environment-setup.rst b/doc/bitbake-user-manual/bitbake-user-manual-environment-setup.rst index aa546c30b..931fda798 100644 --- a/doc/bitbake-user-manual/bitbake-user-manual-environment-setup.rst +++ b/doc/bitbake-user-manual/bitbake-user-manual-environment-setup.rst @@ -660,6 +660,39 @@ In addition, the command can take the following arguments: - ``--setup-dir``: path to the :term:`Setup` to check to status for. Not required if :term:`BBPATH` is already configured. +- ``--url``: URL from where to fetch the buildtools SDK installer, not + including filename. Requires ``--filename``. Overrides the value from the + configuration file. + +- ``--filename``: filename of the buildtools installer. Requires ``--url``. + Overrides the value from the configuration file. + +- ``--sdk-name``: SDK name used in the environment setup script installed + by the buildtools tarball (e.g. ``customsdk`` for + ``environment-setup-<arch>-customsdk-linux``). Defaults to ``pokysdk``. + Overrides the value from the configuration file. + +- ``--no-check``: disable checksum validation when the server does not + provide a ``.sha256sum`` file alongside the installer. Checksum + validation is enabled by default. + +The ``url``, ``filename``, ``sdk-name`` and ``no-check`` options can also be +set in the :term:`Configuration File` under the ``bitbake-setup`` section:: + + "bitbake-setup": { + "install-buildtools": { + "url": "https://example.com/buildtools", + "filename": "x86_64-buildtools-extended-nativesdk-standalone-5.0.sh", + "sdk-name": "customsdk", + "no-check": true + }, + "configurations": [ ... ] + } + +CLI arguments take precedence over values in the configuration file. +Note that setting ``no-check`` to ``false`` in the configuration file has no +effect; omit the key to use the default (enabled). + .. _ref-bbsetup-command-settings: ``bitbake-setup settings`` diff --git a/lib/bb/tests/setup.py b/lib/bb/tests/setup.py index 5592e8196..f14da5a60 100644 --- a/lib/bb/tests/setup.py +++ b/lib/bb/tests/setup.py @@ -11,6 +11,7 @@ import glob import hashlib import json import os +import shutil import stat from bb.tests.support.httpserver import HTTPService @@ -61,13 +62,22 @@ import getopt import sys import os -opts, args = getopt.getopt(sys.argv[1:], "d:", ["downloads-directory="]) +opts, args = getopt.getopt(sys.argv[1:], "d:", ["downloads-directory=", "url=", "filename=", "sdk-name=", "no-check"]) +installdir = None for option, value in opts: if option == '-d': installdir = value + elif option == '--url': + print("install-buildtools url={}".format(value)) + elif option == '--filename': + print("install-buildtools filename={}".format(value)) + elif option == '--sdk-name': + print("install-buildtools sdk-name={}".format(value)) + elif option == '--no-check': + print("install-buildtools no-check") print("Buildtools installed into {}".format(installdir)) -os.makedirs(installdir) +os.makedirs(installdir, exist_ok=True) """ self.add_file_to_testrepo('scripts/install-buildtools', installbuildtools, script=True) @@ -644,6 +654,72 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"])) def _count_layer_backups(self, layers_path): return len([f for f in os.listdir(layers_path) if 'backup' in f]) + def test_install_buildtools_options(self): + """Test that url, filename, sdk-name and no-check are passed through to install-buildtools""" + if 'BBPATH' in os.environ: + del os.environ['BBPATH'] + os.chdir(self.tempdir) + + self.runbbsetup("settings set default registry 'git://{};protocol=file;branch=master;rev=master'".format(self.registrypath)) + self.add_file_to_testrepo('test-file', 'initial\n') + self.add_json_config_to_registry('test-config-bt.conf.json', 'master', 'master') + self.runbbsetup("init --non-interactive test-config-bt gadget") + setuppath = self.get_setup_path('test-config-bt', 'gadget') + + # test CLI options are passed through + out = self.runbbsetup("install-buildtools --setup-dir {} " + "--url https://example.com/buildtools " + "--filename x86_64-buildtools.sh " + "--sdk-name customsdk " + "--no-check".format(setuppath)) + self.assertIn("install-buildtools url=https://example.com/buildtools", out[0]) + self.assertIn("install-buildtools filename=x86_64-buildtools.sh", out[0]) + self.assertIn("install-buildtools sdk-name=customsdk", out[0]) + self.assertIn("install-buildtools no-check", out[0]) + + # test config options are passed through + shutil.rmtree(os.path.join(setuppath, 'buildtools')) + with open(os.path.join(setuppath, 'config', 'config-upstream.json')) as f: + config_upstream = json.load(f) + config_upstream['data']['bitbake-setup']['install-buildtools'] = { + 'url': 'https://example.com/buildtools', + 'filename': 'x86_64-buildtools-from-config.sh', + 'sdk-name': 'customsdk', + 'no-check': True + } + with open(os.path.join(setuppath, 'config', 'config-upstream.json'), 'w') as f: + json.dump(config_upstream, f) + out = self.runbbsetup("install-buildtools --setup-dir {}".format(setuppath)) + self.assertIn("install-buildtools url=https://example.com/buildtools", out[0]) + self.assertIn("install-buildtools filename=x86_64-buildtools-from-config.sh", out[0]) + self.assertIn("install-buildtools sdk-name=customsdk", out[0]) + self.assertIn("install-buildtools no-check", out[0]) + + # test CLI overrides config — pass --url/--filename on CLI to avoid implicit dependency on case 2 config state + shutil.rmtree(os.path.join(setuppath, 'buildtools')) + out = self.runbbsetup("install-buildtools --setup-dir {} " + "--url https://example.com/buildtools " + "--filename x86_64-buildtools.sh " + "--sdk-name overridden".format(setuppath)) + self.assertIn("install-buildtools sdk-name=overridden", out[0]) + self.assertIn("install-buildtools url=https://example.com/buildtools", out[0]) + self.assertIn("install-buildtools filename=x86_64-buildtools.sh", out[0]) + + # test --check overrides config no-check: true + shutil.rmtree(os.path.join(setuppath, 'buildtools')) + out = self.runbbsetup("install-buildtools --setup-dir {} --check".format(setuppath)) + self.assertNotIn("install-buildtools no-check", out[0]) + + # test --url without --filename is rejected + with open(os.path.join(setuppath, 'config', 'config-upstream.json')) as f: + config_upstream = json.load(f) + config_upstream['data']['bitbake-setup'].pop('install-buildtools', None) + with open(os.path.join(setuppath, 'config', 'config-upstream.json'), 'w') as f: + json.dump(config_upstream, f) + # --force used instead of shutil.rmtree since buildtools dir exists from prior subcase + with self.assertRaises(bb.process.ExecutionError): + self.runbbsetup("install-buildtools --setup-dir {} --force --url https://example.com/buildtools".format(setuppath)) + def test_update_rebase_conflicts_strategy(self): """Test the --rebase-conflicts-strategy option for the update command. diff --git a/setup-schema/bitbake-setup.schema.json b/setup-schema/bitbake-setup.schema.json index 99f47f73d..2a967c96e 100644 --- a/setup-schema/bitbake-setup.schema.json +++ b/setup-schema/bitbake-setup.schema.json @@ -141,6 +141,36 @@ }, "additionalProperties": false } + }, + "install-buildtools": { + "type": "object", + "description": "Optional settings passed through to oe-scripts/install-buildtools", + "properties": { + "url": { + "type": "string", + "minLength": 1, + "description": "URL from where to fetch the buildtools SDK installer, not including filename. Requires 'filename'." + }, + "filename": { + "type": "string", + "minLength": 1, + "description": "Filename for the buildtools SDK installer. Requires 'url'." + }, + "sdk-name": { + "type": "string", + "minLength": 1, + "description": "SDK name in the environment setup script (e.g. 'customsdk'). Defaults to 'pokysdk'." + }, + "no-check": { + "type": "boolean", + "description": "Set to true to disable checksum validation when the server does not provide a .sha256sum file. no-check: false is equivalent to omitting the key." + } + }, + "dependencies": { + "url": ["filename"], + "filename": ["url"] + }, + "additionalProperties": false } }, "additionalProperties": false -- 2.34.1