blob: 58957d7afabdb7a1477fd9ff83af4a12720e486c [file] [log] [blame]
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +01001#!/usr/bin/env python3
2
3""" build_helper.py:
4
5 Build helper instantiates a build manager with user provided arguments,
6 or default ones.
7 """
8
9from __future__ import print_function
10
11__copyright__ = """
12/*
13 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
14 *
15 * SPDX-License-Identifier: BSD-3-Clause
16 *
17 */
18 """
19__author__ = "Minos Galanakis"
20__email__ = "minos.galanakis@linaro.org"
21__project__ = "Trusted Firmware-M Open CI"
22__status__ = "stable"
Minos Galanakisea421232019-06-20 17:11:28 +010023__version__ = "1.1"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010024
25import os
26import sys
27import time
28import argparse
29import datetime
Minos Galanakisea421232019-06-20 17:11:28 +010030from build_helper_configs import _builtin_configs
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010031
32try:
Minos Galanakisea421232019-06-20 17:11:28 +010033 from tfm_ci_pylib.utils import get_cmd_args
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010034 from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager
35except ImportError:
36 dir_path = os.path.dirname(os.path.realpath(__file__))
37 sys.path.append(os.path.join(dir_path, "../"))
38 from tfm_ci_pylib.utils import get_cmd_args, load_json
39 from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager
40
41
Minos Galanakisea421232019-06-20 17:11:28 +010042def build(tfm_dir,
43 build_dir,
44 buid_report_f,
45 build_config,
46 parallel_builds=3,
47 build_threads=3,
48 build_install=True,
49 image_sizes=False,
50 relative_paths=False):
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010051 """ Instantiate a build manager class and build all configurations """
52
53 start_time = time.time()
54
55 bm = TFM_Build_Manager(tfm_dir=tfm_dir,
56 work_dir=build_dir,
57 cfg_dict=build_config,
58 report=buid_report_f,
Minos Galanakisea421232019-06-20 17:11:28 +010059 parallel_builds=parallel_builds,
60 build_threads=build_threads,
61 install=build_install,
62 img_sizes=image_sizes,
63 relative_paths=relative_paths)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010064 bm.start()
65 bm.join()
66 build_report = bm.get_report()
67 elapsed = time.time() - start_time
68 elapsed = str(datetime.timedelta(seconds=elapsed))
69 print("=============== Time Elapsed: %s ===================" % elapsed)
70 return bm.get_status(), build_report
71
72
73def main(user_args):
74 """ Main logic """
75
76 if user_args.config_f:
77 try:
78 build_config = load_json(user_args.config_f)
79 except Exception as e:
80 print("Failed to load config %s. Exception: %s" % (build_config,
81 e.msg))
82 sys.exit(1)
Minos Galanakisea421232019-06-20 17:11:28 +010083 elif user_args.config:
84 if user_args.config in _builtin_configs.keys():
85 build_config = _builtin_configs[user_args.config.lower()]
86 else:
87 print("Configuration %s is not defined in built-in configs" %
88 user_args.config)
89 sys.exit(1)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010090 else:
Minos Galanakisea421232019-06-20 17:11:28 +010091 print("Error: Configuration not specificed")
92 sys.exit(1)
93
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010094 # Build everything
95 build_status, build_report = build(user_args.tfm_dir,
96 user_args.build_dir,
97 user_args.report,
Minos Galanakisea421232019-06-20 17:11:28 +010098 build_config,
99 user_args.parallel_builds,
100 user_args.thread_no,
101 user_args.install,
102 user_args.image_sizes,
103 user_args.relative_paths)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100104
105 if not build_report:
106 print("Build Report Empty, check build status")
107 sys.exit(1)
108
109 if build_status:
110 print("Build Failed")
Minos Galanakisea421232019-06-20 17:11:28 +0100111 if user_args.eif:
112 sys.exit(1)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100113 # pprint(build_report)
Minos Galanakisea421232019-06-20 17:11:28 +0100114 print("Build Helper Quitting!")
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100115 sys.exit(0)
116
117
118if __name__ == "__main__":
119
Minos Galanakisea421232019-06-20 17:11:28 +0100120 # Calculate the workspace root directory relative to the script location
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100121 # Equivalent to realpath $(dirname ./build_helper/build_helper.py)/../../
122 root_path = os.path.dirname(os.path.realpath(__file__))
123 for i in range(2):
124 root_path = os.path.split(root_path)[0]
125
126 parser = argparse.ArgumentParser(description="")
127 parser.add_argument("-b", "--build_dir",
128 dest="build_dir",
129 action="store",
130 default="./builds",
131 help="Where to generate the artifacts")
Minos Galanakisea421232019-06-20 17:11:28 +0100132 parser.add_argument("-c", "--config",
133 dest="config",
134 action="store",
135 help="Which of the built-in configs to run."
136 "(%s)" % "/ ".join(_builtin_configs.keys()))
137 parser.add_argument("-e", "--error_if_failed",
138 dest="eif",
139 action="store_true",
140 help="If set will change the script exit code if one "
141 "or more builds fail")
142 parser.add_argument("-f", "--config_file",
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100143 dest="config_f",
144 action="store",
145 help="Manual configuration override file (JSON)")
146 parser.add_argument("-r", "--report",
147 dest="report",
148 action="store",
149 help="JSON file containing build report")
Minos Galanakisea421232019-06-20 17:11:28 +0100150 parser.add_argument("-i", "--install",
151 dest="install",
152 action="store_true",
153 help="Run make install after building config")
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100154 parser.add_argument("-t", "--tfm_dir",
155 dest="tfm_dir",
156 action="store",
157 default=os.path.join(root_path, "tf-m"),
158 help="TFM directory")
Minos Galanakisea421232019-06-20 17:11:28 +0100159 parser.add_argument("-s", "--image-sizes",
160 dest="image_sizes",
161 action="store_true",
162 help="Run arm-none-eabi-size to axf files "
163 "generated by build")
164 parser.add_argument("-l", "--relative-paths",
165 dest="relative_paths",
166 action="store_true",
167 help="When set paths stored in report will be stored"
168 "in a relative path to the execution directory."
169 "Recommended for Jenkins Builds.")
170 parser.add_argument("-p", "--parallel-builds",
171 type=int,
172 dest="parallel_builds",
173 action="store",
174 default=3,
175 help="Number of builds jobs to run in parallel.")
176 parser.add_argument("-n", "--number-of-threads",
177 type=int,
178 dest="thread_no",
179 action="store",
180 default=3,
181 help="Number of threads to use per build job.")
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100182 main(get_cmd_args(parser=parser))