@@ -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)
@@ -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``
@@ -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.
@@ -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
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 <jaipaul.cheernam@est.tech> --- 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(-)