summaryrefslogtreecommitdiff
path: root/zephyr/firmware_builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/firmware_builder.py')
-rwxr-xr-xzephyr/firmware_builder.py209
1 files changed, 108 insertions, 101 deletions
diff --git a/zephyr/firmware_builder.py b/zephyr/firmware_builder.py
index f77e51d6c4..c0963a84db 100755
--- a/zephyr/firmware_builder.py
+++ b/zephyr/firmware_builder.py
@@ -15,14 +15,12 @@ import re
import subprocess
import sys
-from google.protobuf import json_format # pylint: disable=import-error
import zmake.project
-
from chromite.api.gen_sdk.chromite.api import firmware_pb2
+from google.protobuf import json_format # pylint: disable=import-error
-
-DEFAULT_BUNDLE_DIRECTORY = '/tmp/artifact_bundles'
-DEFAULT_BUNDLE_METADATA_FILE = '/tmp/artifact_bundle_metadata'
+DEFAULT_BUNDLE_DIRECTORY = "/tmp/artifact_bundles"
+DEFAULT_BUNDLE_METADATA_FILE = "/tmp/artifact_bundle_metadata"
def build(opts):
@@ -33,54 +31,52 @@ def build(opts):
platform_ec = zephyr_dir.resolve().parent
subprocess.run([platform_ec / "util" / "check_clang_format.py"], check=True)
- cmd = ['zmake', '-D', 'build', '-a']
+ cmd = ["zmake", "-D", "build", "-a"]
if opts.code_coverage:
- cmd.append('--coverage')
+ cmd.append("--coverage")
subprocess.run(cmd, cwd=pathlib.Path(__file__).parent, check=True)
if not opts.code_coverage:
for project in zmake.project.find_projects(zephyr_dir).values():
if project.config.is_test:
continue
- build_dir = (
- platform_ec / 'build' / 'zephyr' / project.config.project_name
- )
+ build_dir = platform_ec / "build" / "zephyr" / project.config.project_name
metric = metric_list.value.add()
metric.target_name = project.config.project_name
metric.platform_name = project.config.zephyr_board
for (variant, _) in project.iter_builds():
- build_log = build_dir / f'build-{variant}' / 'build.log'
+ build_log = build_dir / f"build-{variant}" / "build.log"
parse_buildlog(build_log, metric, variant.upper())
- with open(opts.metrics, 'w') as file:
+ with open(opts.metrics, "w") as file:
file.write(json_format.MessageToJson(metric_list))
return 0
UNITS = {
- 'B': 1,
- 'KB': 1024,
- 'MB': 1024 * 1024,
- 'GB': 1024 * 1024 * 1024,
+ "B": 1,
+ "KB": 1024,
+ "MB": 1024 * 1024,
+ "GB": 1024 * 1024 * 1024,
}
def parse_buildlog(filename, metric, variant):
"""Parse the build.log generated by zmake to find the size of the image."""
- with open(filename, 'r') as infile:
+ with open(filename, "r") as infile:
# Skip over all lines until the memory report is found
while True:
line = infile.readline()
if not line:
return
- if line.startswith('Memory region'):
+ if line.startswith("Memory region"):
break
for line in infile.readlines():
# Skip any lines that are not part of the report
- if not line.startswith(' '):
+ if not line.startswith(" "):
continue
parts = line.split()
fw_section = metric.fw_section.add()
- fw_section.region = variant + '_' + parts[0][:-1]
+ fw_section.region = variant + "_" + parts[0][:-1]
fw_section.used = int(parts[1]) * UNITS[parts[2]]
fw_section.total = int(parts[3]) * UNITS[parts[4]]
fw_section.track_on_gerrit = False
@@ -114,7 +110,7 @@ def write_metadata(opts, info):
bundle_metadata_file = (
opts.metadata if opts.metadata else DEFAULT_BUNDLE_METADATA_FILE
)
- with open(bundle_metadata_file, 'w') as file:
+ with open(bundle_metadata_file, "w") as file:
file.write(json_format.MessageToJson(info))
@@ -125,10 +121,10 @@ def bundle_coverage(opts):
bundle_dir = get_bundle_dir(opts)
zephyr_dir = pathlib.Path(__file__).parent
platform_ec = zephyr_dir.resolve().parent
- build_dir = platform_ec / 'build' / 'zephyr'
- tarball_name = 'coverage.tbz2'
+ build_dir = platform_ec / "build" / "zephyr"
+ tarball_name = "coverage.tbz2"
tarball_path = bundle_dir / tarball_name
- cmd = ['tar', 'cvfj', tarball_path, 'lcov.info']
+ cmd = ["tar", "cvfj", tarball_path, "lcov.info"]
subprocess.run(cmd, cwd=build_dir, check=True)
meta = info.objects.add()
meta.file_name = tarball_name
@@ -149,13 +145,11 @@ def bundle_firmware(opts):
for project in zmake.project.find_projects(zephyr_dir).values():
if project.config.is_test:
continue
- build_dir = (
- platform_ec / 'build' / 'zephyr' / project.config.project_name
- )
- artifacts_dir = build_dir / 'output'
- tarball_name = f'{project.config.project_name}.firmware.tbz2'
+ build_dir = platform_ec / "build" / "zephyr" / project.config.project_name
+ artifacts_dir = build_dir / "output"
+ tarball_name = f"{project.config.project_name}.firmware.tbz2"
tarball_path = bundle_dir.joinpath(tarball_name)
- cmd = ['tar', 'cvfj', tarball_path, '.']
+ cmd = ["tar", "cvfj", tarball_path, "."]
subprocess.run(cmd, cwd=artifacts_dir, check=True)
meta = info.objects.add()
meta.file_name = tarball_name
@@ -176,76 +170,92 @@ def test(opts):
# Run zmake tests to ensure we have a fully working zmake before
# proceeding.
- subprocess.run([zephyr_dir / 'zmake' / 'run_tests.sh'], check=True)
+ subprocess.run([zephyr_dir / "zmake" / "run_tests.sh"], check=True)
# Run formatting checks on all BUILD.py files.
- config_files = zephyr_dir.rglob('**/BUILD.py')
- subprocess.run(['black', '--diff', '--check', *config_files], check=True)
+ config_files = zephyr_dir.rglob("**/BUILD.py")
+ subprocess.run(["black", "--diff", "--check", *config_files], check=True)
- cmd = ['zmake', '-D', 'test', '-a', '--no-rebuild']
+ cmd = ["zmake", "-D", "test", "-a", "--no-rebuild"]
if opts.code_coverage:
- cmd.append('--coverage')
+ cmd.append("--coverage")
ret = subprocess.run(cmd, check=True).returncode
if ret:
return ret
if opts.code_coverage:
platform_ec = zephyr_dir.parent
- build_dir = platform_ec / 'build' / 'zephyr'
+ build_dir = platform_ec / "build" / "zephyr"
# Merge lcov files here because bundle failures are "infra" failures.
cmd = [
- '/usr/bin/lcov',
- '-o',
- build_dir / 'zephyr_merged.info',
- '--rc',
- 'lcov_branch_coverage=1',
- '-a',
- build_dir / 'all_tests.info',
- '-a',
- build_dir / 'all_builds.info',
+ "/usr/bin/lcov",
+ "-o",
+ build_dir / "zephyr_merged.info",
+ "--rc",
+ "lcov_branch_coverage=1",
+ "-a",
+ build_dir / "all_tests.info",
+ "-a",
+ build_dir / "all_builds.info",
]
output = subprocess.run(
- cmd, cwd=pathlib.Path(__file__).parent, check=True,
- stdout=subprocess.PIPE, universal_newlines=True).stdout
- _extract_lcov_summary('EC_ZEPHYR_MERGED', metrics, output)
+ cmd,
+ cwd=pathlib.Path(__file__).parent,
+ check=True,
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ ).stdout
+ _extract_lcov_summary("EC_ZEPHYR_MERGED", metrics, output)
output = subprocess.run(
- ['/usr/bin/lcov', '--summary', build_dir / 'all_tests.info'],
- cwd=pathlib.Path(__file__).parent, check=True,
- stdout=subprocess.PIPE, universal_newlines=True).stdout
- _extract_lcov_summary('EC_ZEPHYR_TESTS', metrics, output)
-
- cmd = ['make', 'coverage', f'-j{opts.cpus}']
+ ["/usr/bin/lcov", "--summary", build_dir / "all_tests.info"],
+ cwd=pathlib.Path(__file__).parent,
+ check=True,
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ ).stdout
+ _extract_lcov_summary("EC_ZEPHYR_TESTS", metrics, output)
+
+ cmd = ["make", "coverage", f"-j{opts.cpus}"]
print(f"# Running {' '.join(cmd)}.")
subprocess.run(cmd, cwd=platform_ec, check=True)
output = subprocess.run(
- ['/usr/bin/lcov', '--summary', platform_ec / 'build/coverage/lcov.info'],
- cwd=pathlib.Path(__file__).parent, check=True,
- stdout=subprocess.PIPE, universal_newlines=True).stdout
- _extract_lcov_summary('EC_LEGACY_MERGED', metrics, output)
+ ["/usr/bin/lcov", "--summary", platform_ec / "build/coverage/lcov.info"],
+ cwd=pathlib.Path(__file__).parent,
+ check=True,
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ ).stdout
+ _extract_lcov_summary("EC_LEGACY_MERGED", metrics, output)
cmd = [
- '/usr/bin/lcov',
- '-o',
- build_dir / 'lcov.info',
- '--rc',
- 'lcov_branch_coverage=1',
- '-a',
- build_dir / 'zephyr_merged.info',
- '-a',
- platform_ec / 'build/coverage/lcov.info',
+ "/usr/bin/lcov",
+ "-o",
+ build_dir / "lcov.info",
+ "--rc",
+ "lcov_branch_coverage=1",
+ "-a",
+ build_dir / "zephyr_merged.info",
+ "-a",
+ platform_ec / "build/coverage/lcov.info",
]
output = subprocess.run(
- cmd, cwd=pathlib.Path(__file__).parent, check=True,
- stdout=subprocess.PIPE, universal_newlines=True).stdout
- _extract_lcov_summary('ALL_MERGED', metrics, output)
-
- with open(opts.metrics, 'w') as file:
+ cmd,
+ cwd=pathlib.Path(__file__).parent,
+ check=True,
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ ).stdout
+ _extract_lcov_summary("ALL_MERGED", metrics, output)
+
+ with open(opts.metrics, "w") as file:
file.write(json_format.MessageToJson(metrics))
return 0
-COVERAGE_RE = re.compile(r'lines\.*: *([0-9\.]+)% \(([0-9]+) of ([0-9]+) lines\)')
+COVERAGE_RE = re.compile(r"lines\.*: *([0-9\.]+)% \(([0-9]+) of ([0-9]+) lines\)")
+
+
def _extract_lcov_summary(name, metrics, output):
re_match = COVERAGE_RE.search(output)
if re_match:
@@ -255,12 +265,13 @@ def _extract_lcov_summary(name, metrics, output):
metric.covered_lines = int(re_match.group(2))
metric.total_lines = int(re_match.group(3))
+
def main(args):
"""Builds and tests all of the Zephyr targets and reports build metrics"""
opts = parse_args(args)
- if not hasattr(opts, 'func'):
- print('Must select a valid sub command!')
+ if not hasattr(opts, "func"):
+ print("Must select a valid sub command!")
return -1
# Run selected sub command function
@@ -272,70 +283,66 @@ def parse_args(args):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
- '--cpus',
+ "--cpus",
default=multiprocessing.cpu_count(),
- help='The number of cores to use.',
+ help="The number of cores to use.",
)
parser.add_argument(
- '--metrics',
- dest='metrics',
+ "--metrics",
+ dest="metrics",
required=True,
- help='File to write the json-encoded MetricsList proto message.',
+ help="File to write the json-encoded MetricsList proto message.",
)
parser.add_argument(
- '--metadata',
+ "--metadata",
required=False,
help=(
- 'Full pathname for the file in which to write build artifact '
- 'metadata.'
+ "Full pathname for the file in which to write build artifact " "metadata."
),
)
parser.add_argument(
- '--output-dir',
+ "--output-dir",
required=False,
- help=(
- 'Full pathname for the directory in which to bundle build '
- 'artifacts.'
- ),
+ help=("Full pathname for the directory in which to bundle build " "artifacts."),
)
parser.add_argument(
- '--code-coverage',
+ "--code-coverage",
required=False,
- action='store_true',
- help='Build host-based unit tests for code coverage.',
+ action="store_true",
+ help="Build host-based unit tests for code coverage.",
)
parser.add_argument(
- '--bcs-version',
- dest='bcs_version',
- default='',
+ "--bcs-version",
+ dest="bcs_version",
+ default="",
required=False,
# TODO(b/180008931): make this required=True.
- help='BCS version to include in metadata.',
+ help="BCS version to include in metadata.",
)
# Would make this required=True, but not available until 3.7
sub_cmds = parser.add_subparsers()
- build_cmd = sub_cmds.add_parser('build', help='Builds all firmware targets')
+ build_cmd = sub_cmds.add_parser("build", help="Builds all firmware targets")
build_cmd.set_defaults(func=build)
build_cmd = sub_cmds.add_parser(
- 'bundle',
- help='Creates a tarball containing build '
- 'artifacts from all firmware targets',
+ "bundle",
+ help="Creates a tarball containing build "
+ "artifacts from all firmware targets",
)
build_cmd.set_defaults(func=bundle)
- test_cmd = sub_cmds.add_parser('test', help='Runs all firmware unit tests')
+ test_cmd = sub_cmds.add_parser("test", help="Runs all firmware unit tests")
test_cmd.set_defaults(func=test)
return parser.parse_args(args)
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))