blob: 9f578289437df4478ee87f947253722f3c7c025f [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()
Karl Zhangaff558a2020-05-15 14:28:23 +010054 print("relative_paths %s done \r\n" % relative_paths)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010055
56 bm = TFM_Build_Manager(tfm_dir=tfm_dir,
57 work_dir=build_dir,
58 cfg_dict=build_config,
59 report=buid_report_f,
Minos Galanakisea421232019-06-20 17:11:28 +010060 parallel_builds=parallel_builds,
61 build_threads=build_threads,
62 install=build_install,
63 img_sizes=image_sizes,
64 relative_paths=relative_paths)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010065 bm.start()
66 bm.join()
67 build_report = bm.get_report()
68 elapsed = time.time() - start_time
69 elapsed = str(datetime.timedelta(seconds=elapsed))
70 print("=============== Time Elapsed: %s ===================" % elapsed)
71 return bm.get_status(), build_report
72
73
74def main(user_args):
75 """ Main logic """
76
77 if user_args.config_f:
78 try:
79 build_config = load_json(user_args.config_f)
80 except Exception as e:
81 print("Failed to load config %s. Exception: %s" % (build_config,
82 e.msg))
83 sys.exit(1)
Minos Galanakisea421232019-06-20 17:11:28 +010084 elif user_args.config:
85 if user_args.config in _builtin_configs.keys():
86 build_config = _builtin_configs[user_args.config.lower()]
Karl Zhangaff558a2020-05-15 14:28:23 +010087 print("main %s done \r\n" % build_config)
Minos Galanakisea421232019-06-20 17:11:28 +010088 else:
89 print("Configuration %s is not defined in built-in configs" %
90 user_args.config)
91 sys.exit(1)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010092 else:
Minos Galanakisea421232019-06-20 17:11:28 +010093 print("Error: Configuration not specificed")
94 sys.exit(1)
95
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010096 # Build everything
97 build_status, build_report = build(user_args.tfm_dir,
98 user_args.build_dir,
Karl Zhangaff558a2020-05-15 14:28:23 +010099 #user_args.report,
100 "summary_" + user_args.config.lower() + ".json",
Minos Galanakisea421232019-06-20 17:11:28 +0100101 build_config,
Karl Zhangaff558a2020-05-15 14:28:23 +0100102 os.cpu_count(),
Minos Galanakisea421232019-06-20 17:11:28 +0100103 user_args.thread_no,
104 user_args.install,
105 user_args.image_sizes,
106 user_args.relative_paths)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100107
108 if not build_report:
109 print("Build Report Empty, check build status")
110 sys.exit(1)
111
112 if build_status:
113 print("Build Failed")
Minos Galanakisea421232019-06-20 17:11:28 +0100114 if user_args.eif:
115 sys.exit(1)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100116 # pprint(build_report)
Minos Galanakisea421232019-06-20 17:11:28 +0100117 print("Build Helper Quitting!")
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100118 sys.exit(0)
119
120
121if __name__ == "__main__":
122
Minos Galanakisea421232019-06-20 17:11:28 +0100123 # Calculate the workspace root directory relative to the script location
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100124 # Equivalent to realpath $(dirname ./build_helper/build_helper.py)/../../
125 root_path = os.path.dirname(os.path.realpath(__file__))
126 for i in range(2):
127 root_path = os.path.split(root_path)[0]
128
129 parser = argparse.ArgumentParser(description="")
130 parser.add_argument("-b", "--build_dir",
131 dest="build_dir",
132 action="store",
133 default="./builds",
134 help="Where to generate the artifacts")
Minos Galanakisea421232019-06-20 17:11:28 +0100135 parser.add_argument("-c", "--config",
136 dest="config",
137 action="store",
138 help="Which of the built-in configs to run."
139 "(%s)" % "/ ".join(_builtin_configs.keys()))
140 parser.add_argument("-e", "--error_if_failed",
141 dest="eif",
142 action="store_true",
143 help="If set will change the script exit code if one "
144 "or more builds fail")
145 parser.add_argument("-f", "--config_file",
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100146 dest="config_f",
147 action="store",
148 help="Manual configuration override file (JSON)")
149 parser.add_argument("-r", "--report",
150 dest="report",
151 action="store",
152 help="JSON file containing build report")
Minos Galanakisea421232019-06-20 17:11:28 +0100153 parser.add_argument("-i", "--install",
154 dest="install",
155 action="store_true",
156 help="Run make install after building config")
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100157 parser.add_argument("-t", "--tfm_dir",
158 dest="tfm_dir",
159 action="store",
160 default=os.path.join(root_path, "tf-m"),
161 help="TFM directory")
Minos Galanakisea421232019-06-20 17:11:28 +0100162 parser.add_argument("-s", "--image-sizes",
163 dest="image_sizes",
164 action="store_true",
165 help="Run arm-none-eabi-size to axf files "
166 "generated by build")
167 parser.add_argument("-l", "--relative-paths",
168 dest="relative_paths",
169 action="store_true",
170 help="When set paths stored in report will be stored"
171 "in a relative path to the execution directory."
172 "Recommended for Jenkins Builds.")
173 parser.add_argument("-p", "--parallel-builds",
174 type=int,
175 dest="parallel_builds",
176 action="store",
177 default=3,
178 help="Number of builds jobs to run in parallel.")
179 parser.add_argument("-n", "--number-of-threads",
180 type=int,
181 dest="thread_no",
182 action="store",
183 default=3,
184 help="Number of threads to use per build job.")
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100185 main(get_cmd_args(parser=parser))