10def run_make(platform, CC, build_type, args):
11 env = os.environ.copy()
12 env.update({
"platform": platform,
"CC": CC,
"build_type": build_type})
13 exe_path = env[
"PATH"]
14 exe_path = os.path.abspath(
"tools/avr-install/bin") +
":" + exe_path
15 env[
"PATH"] = exe_path
16 if args.coverage
and platform ==
"native" and build_type ==
"debug":
17 env[
"coverage"] =
"TRUE"
19 outdir =
"build/{}_{}_{}".format(platform, CC, build_type)
20 outdir = os.path.abspath(outdir)
23 subprocess.run([
"make",
"clean"], env=env, check=
True)
24 except subprocess.CalledProcessError
as e:
27 subprocess.run([
"make",
"install"], env=env, check=
True)
28 except subprocess.CalledProcessError
as e:
33 print(outdir, flush=
True)
34 for fn
in os.listdir(outdir):
37 fnabs = os.path.join(outdir, fn)
39 cmpltProc = subprocess.run(
42 stdout=subprocess.PIPE,
43 stderr=subprocess.STDOUT,
47 "\n==========================================================\n\n"
49 stdout +=
"build/{}_{}_{}/{}\n\n".format(platform, CC, build_type, fn)
50 stdout += cmpltProc.stdout
51 success = success
and (cmpltProc.returncode == 0)
52 if args.coverage
and platform ==
"native" and build_type ==
"debug":
53 coverage_dir = os.path.join(outdir,
"coverage")
55 os.mkdir(coverage_dir)
56 except FileExistsError:
58 coverage_html_base = os.path.join(coverage_dir,
"index.html")
59 coverage_text = os.path.join(coverage_dir,
"coverage.txt")
61 [
"gcovr",
"-o", coverage_text,
"-e",
"src/externals/.*"],
77 return success, stdout
81def run_integration_tests():
82 env = os.environ.copy()
84 test_dir =
"integration_tests"
85 tests = os.listdir(test_dir)
88 print(
"========== Integration Tests =============")
92 if test[-3:] !=
".py":
94 testfn = os.path.join(test_dir, test)
95 cmpltProc = subprocess.run(
96 [
"python3",
"-m",
"unittest", testfn],
98 stdout=subprocess.PIPE,
99 stderr=subprocess.STDOUT,
102 success = success
and (cmpltProc.returncode == 0)
103 print(cmpltProc.stdout, flush=
True)
104 stdout += cmpltProc.stdout
106 print(
"Integration Tests All Pass!")
108 print(
"Integration Test Failure")
109 return success, stdout
112def print_FW_size(targets):
113 env = os.environ.copy()
114 exe_path = env[
"PATH"]
115 exe_path = os.path.abspath(
"tools/avr-install/bin") +
":" + exe_path
116 env[
"PATH"] = exe_path
120 for target
in sorted(targets):
121 for build_type
in [
"debug",
"opt"]:
122 target_list = target.split(
"_")
123 assert len(target_list) == 2
124 platform = target_list[0]
125 if "avr" in platform:
127 outdir =
"build/{}_{}_{}".format(platform, CC, build_type)
128 outdir = os.path.abspath(outdir)
129 outfiles = os.listdir(outdir)
130 fwfiles = [os.path.join(outdir, x)
for x
in outfiles
if x[-2:] !=
".a"]
131 avr_fwfiles += fwfiles
132 elif "cortex" in platform:
134 outdir =
"build/{}_{}_{}".format(platform, CC, build_type)
135 outdir = os.path.abspath(outdir)
136 outfiles = os.listdir(outdir)
137 fwfiles = [os.path.join(outdir, x)
for x
in outfiles
if x[-2:] !=
".a"]
138 cortex_fwfiles += fwfiles
139 elif "rv32" in platform:
141 outdir =
"build/{}_{}_{}".format(platform, CC, build_type)
142 outdir = os.path.abspath(outdir)
143 outfiles = os.listdir(outdir)
144 fwfiles = [os.path.join(outdir, x)
for x
in outfiles
if x[-4:] ==
".elf"]
145 rv32_fwfiles += fwfiles
146 if len(avr_fwfiles) + len(cortex_fwfiles) + len(rv32_fwfiles) == 0:
148 print(
"========= Firmware Size ==========")
149 cmpltProc = subprocess.run([
"avr-size",
"-G"] + avr_fwfiles, env=env, text=
True,)
150 cmpltProc = subprocess.run(
151 [
"arm-none-eabi-size",
"-G"] + cortex_fwfiles, env=env, text=
True,
153 cmpltProc = subprocess.run(
154 [
"riscv32-unknown-elf-size",
"-G"] + rv32_fwfiles, env=env, text=
True,
159 cmpltProc = subprocess.run([
"doxygen",
"doc/Doxyfile"],)
164 available_targets = [
186 parser = argparse.ArgumentParser(
187 description=
"Build tool for ASCII-Serial-Com. Will stop and exit with status 1 if build fails, but continue if tests fail."
191 help=
"Targets to build; defaults: {}".format(default_targets),
194 choices=available_targets,
197 "--unittest",
"-u", help=
"Perform unittests after building", action=
"store_true"
202 help=
"Collect coverage info when unittests are performed (sets -u)",
205 args = parser.parse_args()
207 targets = args.targets
210 if type(targets) == str:
211 targets = default_targets
212 elif "all" in targets:
213 targets = available_targets
214 targets.remove(
"all")
215 targets.remove(
"default")
216 elif "default" in targets:
217 targets += default_targets
218 targets.remove(
"default")
226 for target
in targets:
227 target_list = target.split(
"_")
228 assert len(target_list) == 2
229 platform = target_list[0]
231 build_types = [
"debug",
"opt"]
232 if "native" in target:
233 build_types.append(
"profile")
234 for build_type
in build_types:
235 testPass, testOutput = run_make(platform, CC, build_type, args)
237 testOutBuffer += testOutput
238 testsAllPass = testsAllPass
and testPass
240 pythonTestsPass =
False
243 print(
"==========================================")
244 print(
"========== Unit Test Results =============")
245 print(
"==========================================")
250 print(
"Unit Tests All Pass!")
252 print(
"Unit Test Failure")
254 print_FW_size(targets)
258 print(
"============= Test Summary ===============")
262 print(
"Unit Tests All Pass!")
264 print(
"Unit Test Failure")
269if __name__ ==
"__main__":