summaryrefslogtreecommitdiffstats
path: root/scripts/oe-setup-build
blob: c0476992a2a4ee91d29a9793ae5931942c20b2a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python3
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

import argparse
import json
import os
import subprocess

def defaultlayers():
    return os.path.abspath(os.path.join(os.path.dirname(__file__), '.oe-layers.json'))

def makebuildpath(topdir, template):
    return os.path.join(topdir, "build-{}".format(template))

def discover_templates(layers_file):
    if not os.path.exists(layers_file):
        print("List of layers {} does not exist; were the layers set up using the setup-layers script?".format(layers_file))
        return None

    templates = []
    layers_list = json.load(open(layers_file))["layers"]
    for layer in layers_list:
        template_dir = os.path.join(os.path.dirname(layers_file), layer, 'conf','templates')
        if os.path.exists(template_dir):
            for d in sorted(os.listdir(template_dir)):
                templatepath = os.path.join(template_dir,d)
                if not os.path.isfile(os.path.join(templatepath,'local.conf.sample')):
                    continue
                layer_base = os.path.basename(layer)
                templatename = "{}-{}".format(layer_base[5:] if layer_base.startswith("meta-") else layer_base, d)
                buildpath = makebuildpath(os.getcwd(), templatename)
                notespath = os.path.join(template_dir, d, 'conf-notes.txt')
                try: notes = open(notespath).read()
                except: notes = None
                try: summary = open(os.path.join(template_dir, d, 'conf-summary.txt')).read()
                except: summary = None
                templates.append({"templatename":templatename,"templatepath":templatepath,"buildpath":buildpath,"notespath":notespath,"notes":notes,"summary":summary})

    return templates

def print_templates(templates, verbose):
    print("Available build configurations:\n")

    for i in range(len(templates)):
        t = templates[i]
        print("{}. {}".format(i+1, t["templatename"]))
        print("{}".format(t["summary"].strip() if t["summary"] else "This configuration does not have a summary."))
        if verbose:
            print("Configuration template path:", t["templatepath"])
            print("Build path:", t["buildpath"])
            print("Usage notes:", t["notespath"] if t["notes"] else "This configuration does not have usage notes.")
        print("")
    if not verbose:
        print("Re-run with 'list -v' to see additional information.")

def list_templates(args):
    templates = discover_templates(args.layerlist)
    if not templates:
        return

    verbose = args.v
    print_templates(templates, verbose)

def find_template(template_name, templates):
    print_templates(templates, False)
    if not template_name:
        n_s = input("Please choose a configuration by its number: ")
        try: return templates[int(n_s) - 1]
        except:
            print("Invalid selection, please try again.")
            return None
    else:
        for t in templates:
            if t["templatename"] == template_name:
                return t
        print("Configuration {} is not one of {}, please try again.".format(tempalte_name, [t["templatename"] for t in templates]))
        return None

def setup_build_env(args):
    templates = discover_templates(args.layerlist)
    if not templates:
        return

    template = find_template(args.c, templates)
    if not template:
        return
    builddir = args.b if args.b else template["buildpath"]
    no_shell = args.no_shell
    coredir = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
    cmd_base = ". {} {}".format(os.path.join(coredir, 'oe-init-build-env'), os.path.abspath(builddir))

    initbuild = os.path.join(builddir, 'init-build-env')
    if not os.path.exists(initbuild):
        os.makedirs(builddir, exist_ok=True)
        with open(initbuild, 'w') as f:
            f.write(cmd_base)
    print("\nRun '. {}' to initialize the build in a current shell session.\n".format(initbuild))

    cmd = "TEMPLATECONF={} {}".format(template["templatepath"], cmd_base)
    if not no_shell:
        cmd = cmd + " && {}".format(os.environ['SHELL'])
    print("Running:", cmd)
    subprocess.run(cmd, shell=True, executable=os.environ['SHELL'])

parser = 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.")
parser.add_argument("--layerlist", default=defaultlayers(), help='Where to look for available layers (as written out by setup-layers script) (default is {}).'.format(defaultlayers()))

subparsers = parser.add_subparsers()
parser_list_templates = subparsers.add_parser('list', help='List available configurations')
parser_list_templates.add_argument('-v', action='store_true',
        help='Print detailed information and usage notes for each available build configuration.')
parser_list_templates.set_defaults(func=list_templates)

parser_setup_env = subparsers.add_parser('setup', help='Set up a build environment and open a shell session with it, ready to run builds.')
parser_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)")
parser_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)")
parser_setup_env.add_argument('--no-shell', action='store_true',
        help='Create a build directory but do not start a shell session with the build environment from it.')
parser_setup_env.set_defaults(func=setup_build_env)

args = parser.parse_args()

if 'func' in args:
    args.func(args)
else:
    from argparse import Namespace
    setup_build_env(Namespace(layerlist=args.layerlist, c=None, b=None, no_shell=False))