summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorAlexander Kanavin <alex.kanavin@gmail.com>2024-02-16 12:52:22 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-02-19 11:47:53 +0000
commitc390b2e615930b60db0d7f3e72d056e0c67ef5bc (patch)
tree1b23fb12a523e91ae3762b63fbb00608fd3cd694 /scripts
parent01d0ee1b834ef58fbb1f6a69a81c0e9a4e2a83d9 (diff)
downloadpoky-c390b2e615930b60db0d7f3e72d056e0c67ef5bc.tar.gz
oe-setup-build: add a tool for discovering config templates and setting up builds
This is another piece of the puzzle in setting up builds from nothing without having to write custom scripts or use external tools. After layers have been fetched and placed into their respective locations by oe-setup-layers, one would surely want to proceed to the actual build, and here's how: 1. Without arguments the tool reads available layers from .oe-layers.json file (written out by oe-setup-layers or a fallback under scripts/), prints what templates it has found, and asks the user to select one, as seen below. This will land the user in a shell ready to run bitbake: ============================================= alex@Zen2:/srv/work/alex$ ./setup-build Available build configurations: 1. alex-configuration-gadget This configuration will set up a build for the purposes of supporting gadget. 2. alex-configuration-gizmo This configuration allows building a gizmo. 3. poky-default This is the default build configuration for the Poky reference distribution. Re-run with 'list -v' to see additional information. Please choose a configuration by its number: 1 Running: TEMPLATECONF=/srv/work/alex/meta-alex/conf/templates/configuration-gadget . /srv/work/alex/poky/oe-init-build-env /srv/work/alex/build-alex-configuration-gadget && /bin/bash You had no conf/local.conf file. This configuration file has therefore been created for you from /srv/work/alex/meta-alex/conf/templates/configuration-gadget/local.conf.sample You may wish to edit it to, for example, select a different MACHINE (target hardware). You had no conf/bblayers.conf file. This configuration file has therefore been created for you from /srv/work/alex/meta-alex/conf/templates/configuration-gadget/bblayers.conf.sample To add additional metadata layers into your configuration please add entries to conf/bblayers.conf. The Yocto Project has extensive documentation about OE including a reference manual which can be found at: https://docs.yoctoproject.org For more information about OpenEmbedded see the website: https://www.openembedded.org/ This configuration will set up a build for the purposes of supporting gadget. Please refer to meta-alex/README for additional details and available bitbake targets. ============================================== 2. It is also possible to list available configurations without selecting one using 'setup-build list' or to select and setup one non-interactively with 'setup-build setup'. 3. The full set of command line options is: $ ./setup-build --help usage: setup-build [-h] [--layerlist LAYERLIST] {list,setup} ... A script that discovers available build configurations and sets up a build environment based on one of them. Run without arguments to choose one interactively. positional arguments: {list,setup} list List available configurations setup Set up a build environment and open a shell session with it, ready to run builds. optional arguments: -h, --help show this help message and exit --layerlist LAYERLIST Where to look for available layers (as written out by setup-layers script) (default is /srv/work/alex/.oe-layers.json). $ ./setup-build list --help usage: setup-build list [-h] [-v] optional arguments: -h, --help show this help message and exit -v Print detailed information and usage notes for each available build configuration. $ ./setup-build setup --help usage: setup-build setup [-h] [-c configuration_name] [-b build_path] [--no-shell] optional arguments: -h, --help show this help message and exit -c configuration_name Use a build configuration configuration_name to set up a build environment (run this script with 'list' to see what is available) -b build_path Set up a build directory in build_path (run this script with 'list -v' to see where it would be by default) --no-shell Create a build directory but do not start a shell session with the build environment from it. 4. There's an an added hint in oe-setup-layers about how to proceed (as it is really not user-friendly to fetch the layer repos successfully and then exit without a word), and a symlink to the script from the top level layer checkout directory. 5. The selftest to check layer setup has been adjusted to run a basic check for template discovery and build setup. The revision of poky to be cloned has been bumped to 4.1, as that's the first version with a default template in a standard location. (From OE-Core rev: 1360b64e88cda7dddfb0eca6a64f70c13dafb890) Signed-off-by: Alexander Kanavin <alex@linutronix.de> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.oe-layers.json7
-rwxr-xr-xscripts/oe-setup-build122
-rwxr-xr-xscripts/oe-setup-layers10
3 files changed, 139 insertions, 0 deletions
diff --git a/scripts/.oe-layers.json b/scripts/.oe-layers.json
new file mode 100644
index 0000000000..1b00a84b54
--- /dev/null
+++ b/scripts/.oe-layers.json
@@ -0,0 +1,7 @@
1{
2 "layers": [
3 "../meta-poky",
4 "../meta"
5 ],
6 "version": "1.0"
7}
diff --git a/scripts/oe-setup-build b/scripts/oe-setup-build
new file mode 100755
index 0000000000..5364f2b481
--- /dev/null
+++ b/scripts/oe-setup-build
@@ -0,0 +1,122 @@
1#!/usr/bin/env python3
2#
3# Copyright OpenEmbedded Contributors
4#
5# SPDX-License-Identifier: MIT
6#
7
8import argparse
9import json
10import os
11import subprocess
12
13def defaultlayers():
14 return os.path.abspath(os.path.join(os.path.dirname(__file__), '.oe-layers.json'))
15
16def makebuildpath(topdir, template):
17 return os.path.join(topdir, "build-{}".format(template))
18
19def discover_templates(layers_file):
20 if not os.path.exists(layers_file):
21 print("List of layers {} does not exist; were the layers set up using the setup-layers script?".format(layers_file))
22 return None
23
24 templates = []
25 layers_list = json.load(open(layers_file))["layers"]
26 for layer in layers_list:
27 template_dir = os.path.join(os.path.dirname(layers_file), layer, 'conf','templates')
28 if os.path.exists(template_dir):
29 for d in sorted(os.listdir(template_dir)):
30 templatepath = os.path.join(template_dir,d)
31 if not os.path.isfile(os.path.join(templatepath,'local.conf.sample')):
32 continue
33 layer_base = os.path.basename(layer)
34 templatename = "{}-{}".format(layer_base[5:] if layer_base.startswith("meta-") else layer_base, d)
35 buildpath = makebuildpath(os.getcwd(), templatename)
36 notespath = os.path.join(template_dir, d, 'conf-notes.txt')
37 try: notes = open(notespath).read()
38 except: notes = None
39 try: summary = open(os.path.join(template_dir, d, 'conf-summary.txt')).read()
40 except: summary = None
41 templates.append({"templatename":templatename,"templatepath":templatepath,"buildpath":buildpath,"notespath":notespath,"notes":notes,"summary":summary})
42
43 return templates
44
45def print_templates(templates, verbose):
46 print("Available build configurations:\n")
47
48 for i in range(len(templates)):
49 t = templates[i]
50 print("{}. {}".format(i+1, t["templatename"]))
51 print("{}".format(t["summary"].strip() if t["summary"] else "This configuration does not have a summary."))
52 if verbose:
53 print("Configuration template path:", t["templatepath"])
54 print("Build path:", t["buildpath"])
55 print("Usage notes:", t["notespath"] if t["notes"] else "This configuration does not have usage notes.")
56 print("")
57 if not verbose:
58 print("Re-run with 'list -v' to see additional information.")
59
60def list_templates(args):
61 templates = discover_templates(args.layerlist)
62 if not templates:
63 return
64
65 verbose = args.v
66 print_templates(templates, verbose)
67
68def find_template(template_name, templates):
69 print_templates(templates, False)
70 if not template_name:
71 n_s = input("Please choose a configuration by its number: ")
72 try: return templates[int(n_s) - 1]
73 except:
74 print("Invalid selection, please try again.")
75 return None
76 else:
77 for t in templates:
78 if t["templatename"] == template_name:
79 return t
80 print("Configuration {} is not one of {}, please try again.".format(tempalte_name, [t["templatename"] for t in templates]))
81 return None
82
83def setup_build_env(args):
84 templates = discover_templates(args.layerlist)
85 if not templates:
86 return
87
88 template = find_template(args.c, templates)
89 if not template:
90 return
91 builddir = args.b if args.b else template["buildpath"]
92 no_shell = args.no_shell
93 coredir = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
94 cmd = "TEMPLATECONF={} . {} {}".format(template["templatepath"], os.path.join(coredir, 'oe-init-build-env'), builddir)
95 if not no_shell:
96 cmd = cmd + " && {}".format(os.environ['SHELL'])
97 print("Running:", cmd)
98 subprocess.run(cmd, shell=True, executable=os.environ['SHELL'])
99
100parser = argparse.ArgumentParser(description="A script that discovers available build configurations and sets up a build environment based on one of them. Run without arguments to choose one interactively.")
101parser.add_argument("--layerlist", default=defaultlayers(), help='Where to look for available layers (as written out by setup-layers script) (default is {}).'.format(defaultlayers()))
102
103subparsers = parser.add_subparsers()
104parser_list_templates = subparsers.add_parser('list', help='List available configurations')
105parser_list_templates.add_argument('-v', action='store_true',
106 help='Print detailed information and usage notes for each available build configuration.')
107parser_list_templates.set_defaults(func=list_templates)
108
109parser_setup_env = subparsers.add_parser('setup', help='Set up a build environment and open a shell session with it, ready to run builds.')
110parser_setup_env.add_argument('-c', metavar='configuration_name', help="Use a build configuration configuration_name to set up a build environment (run this script with 'list' to see what is available)")
111parser_setup_env.add_argument('-b', metavar='build_path', help="Set up a build directory in build_path (run this script with 'list -v' to see where it would be by default)")
112parser_setup_env.add_argument('--no-shell', action='store_true',
113 help='Create a build directory but do not start a shell session with the build environment from it.')
114parser_setup_env.set_defaults(func=setup_build_env)
115
116args = parser.parse_args()
117
118if 'func' in args:
119 args.func(args)
120else:
121 from argparse import Namespace
122 setup_build_env(Namespace(layerlist=args.layerlist, c=None, b=None, no_shell=False))
diff --git a/scripts/oe-setup-layers b/scripts/oe-setup-layers
index bee4ef0fec..6fbfefd656 100755
--- a/scripts/oe-setup-layers
+++ b/scripts/oe-setup-layers
@@ -63,6 +63,7 @@ def _write_layer_list(dest, repodirs):
63def _do_checkout(args, json): 63def _do_checkout(args, json):
64 repos = json['sources'] 64 repos = json['sources']
65 repodirs = [] 65 repodirs = []
66 oesetupbuild = None
66 for r_name in repos: 67 for r_name in repos:
67 r_data = repos[r_name] 68 r_data = repos[r_name]
68 repodir = os.path.abspath(os.path.join(args['destdir'], r_data['path'])) 69 repodir = os.path.abspath(os.path.join(args['destdir'], r_data['path']))
@@ -108,9 +109,18 @@ def _do_checkout(args, json):
108 109
109 if _contains_submodules(repodir): 110 if _contains_submodules(repodir):
110 print("Repo {} contains submodules, use 'git submodule update' to ensure they are up to date".format(repodir)) 111 print("Repo {} contains submodules, use 'git submodule update' to ensure they are up to date".format(repodir))
112 if os.path.exists(os.path.join(repodir, 'scripts/oe-setup-build')):
113 oesetupbuild = os.path.join(repodir, 'scripts/oe-setup-build')
111 114
112 _write_layer_list(args['destdir'], repodirs) 115 _write_layer_list(args['destdir'], repodirs)
113 116
117 if oesetupbuild:
118 oesetupbuild_symlink = os.path.join(args['destdir'], 'setup-build')
119 if os.path.exists(oesetupbuild_symlink):
120 os.remove(oesetupbuild_symlink)
121 os.symlink(os.path.relpath(oesetupbuild,args['destdir']),oesetupbuild_symlink)
122 print("\nRun '{}' to list available build configuration templates and set up a build from one of them.".format(oesetupbuild_symlink))
123
114parser = argparse.ArgumentParser(description="A self contained python script that fetches all the needed layers and sets them to correct revisions using data in a json format from a separate file. The json data can be created from an active build directory with 'bitbake-layers create-layers-setup destdir' and there's a sample file and a schema in meta/files/") 124parser = argparse.ArgumentParser(description="A self contained python script that fetches all the needed layers and sets them to correct revisions using data in a json format from a separate file. The json data can be created from an active build directory with 'bitbake-layers create-layers-setup destdir' and there's a sample file and a schema in meta/files/")
115 125
116parser.add_argument('--force-bootstraplayer-checkout', action='store_true', 126parser.add_argument('--force-bootstraplayer-checkout', action='store_true',