summaryrefslogtreecommitdiff
path: root/firmware_builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'firmware_builder.py')
-rwxr-xr-xfirmware_builder.py250
1 files changed, 0 insertions, 250 deletions
diff --git a/firmware_builder.py b/firmware_builder.py
deleted file mode 100755
index d5a7e6ac8d..0000000000
--- a/firmware_builder.py
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Build, bundle, or test all of the EC boards.
-
-This is the entry point for the custom firmware builder workflow recipe. It
-gets invoked by chromite/api/controller/firmware.py.
-"""
-
-import argparse
-import multiprocessing
-import os
-import subprocess
-import sys
-
-# pylint: disable=import-error
-from google.protobuf import json_format
-# TODO(crbug/1181505): Code outside of chromite should not be importing from
-# chromite.api.gen. Import json_format after that so we get the matching one.
-from chromite.api.gen.chromite.api import firmware_pb2
-
-
-DEFAULT_BUNDLE_DIRECTORY = '/tmp/artifact_bundles'
-DEFAULT_BUNDLE_METADATA_FILE = '/tmp/artifact_bundle_metadata'
-
-# The the list of boards whose on-device unit tests we will verify compilation.
-# TODO(b/172501728) On-device unit tests should build for all boards, but
-# they've bit rotted, so we only build the ones that compile.
-BOARDS_UNIT_TEST = [
- 'bloonchipper',
- 'dartmonkey',
-]
-
-
-def build(opts):
- """Builds all EC firmware targets
-
- Note that when we are building unit tests for code coverage, we don't
- need this step. It builds EC **firmware** targets, but unit tests with
- code coverage are all host-based. So if the --code-coverage flag is set,
- we don't need to build the firmware targets and we can return without
- doing anything but creating the metrics file and giving an informational
- message.
- """
- # TODO(b/169178847): Add appropriate metric information
- metrics = firmware_pb2.FwBuildMetricList()
- with open(opts.metrics, 'w') as f:
- f.write(json_format.MessageToJson(metrics))
-
- if opts.code_coverage:
- print("When --code-coverage is selected, 'build' is a no-op. "
- "Run 'test' with --code-coverage instead.")
- return
-
- cmd = ['make', 'buildall_only', '-j{}'.format(opts.cpus)]
- print(f'# Running {" ".join(cmd)}.')
- subprocess.run(cmd,
- cwd=os.path.dirname(__file__),
- check=True)
-
-
-def bundle(opts):
- if opts.code_coverage:
- bundle_coverage(opts)
- else:
- bundle_firmware(opts)
-
-
-def get_bundle_dir(opts):
- """Get the directory for the bundle from opts or use the default.
-
- Also create the directory if it doesn't exist.
- """
- bundle_dir = opts.output_dir if opts.output_dir else \
- DEFAULT_BUNDLE_DIRECTORY
- if not os.path.isdir(bundle_dir):
- os.mkdir(bundle_dir)
- return bundle_dir
-
-
-def write_metadata(opts, info):
- """Write the metadata about the bundle."""
- bundle_metadata_file = opts.metadata if opts.metadata else \
- DEFAULT_BUNDLE_METADATA_FILE
- with open(bundle_metadata_file, 'w') as f:
- f.write(json_format.MessageToJson(info))
-
-
-def bundle_coverage(opts):
- """Bundles the artifacts from code coverage into its own tarball."""
- info = firmware_pb2.FirmwareArtifactInfo()
- info.bcs_version_info.version_string = opts.bcs_version
- bundle_dir = get_bundle_dir(opts)
- ec_dir = os.path.dirname(__file__)
- tarball_name = 'coverage.tbz2'
- tarball_path = os.path.join(bundle_dir, tarball_name)
- cmd = ['tar', 'cvfj', tarball_path, 'lcov.info']
- subprocess.run(cmd, cwd=os.path.join(ec_dir, 'build/coverage'), check=True)
- meta = info.objects.add()
- meta.file_name = tarball_name
- meta.lcov_info.type = (
- firmware_pb2.FirmwareArtifactInfo.LcovTarballInfo.LcovType.LCOV)
-
- write_metadata(opts, info)
-
-
-def bundle_firmware(opts):
- """Bundles the artifacts from each target into its own tarball."""
- info = firmware_pb2.FirmwareArtifactInfo()
- info.bcs_version_info.version_string = opts.bcs_version
- bundle_dir = get_bundle_dir(opts)
- ec_dir = os.path.dirname(__file__)
- for build_target in sorted(os.listdir(os.path.join(ec_dir, 'build'))):
- tarball_name = ''.join([build_target, '.firmware.tbz2'])
- tarball_path = os.path.join(bundle_dir, tarball_name)
- cmd = [
- 'tar', 'cvfj', tarball_path, '--exclude=*.o.d', '--exclude=*.o', '.'
- ]
- subprocess.run(
- cmd, cwd=os.path.join(ec_dir, 'build', build_target), check=True)
- meta = info.objects.add()
- meta.file_name = tarball_name
- meta.tarball_info.type = (
- firmware_pb2.FirmwareArtifactInfo.TarballInfo.FirmwareType.EC)
- # TODO(kmshelton): Populate the rest of metadata contents as it gets
- # defined in infra/proto/src/chromite/api/firmware.proto.
-
- write_metadata(opts, info)
-
-
-def test(opts):
- """Runs all of the unit tests for EC firmware"""
- # TODO(b/169178847): Add appropriate metric information
- metrics = firmware_pb2.FwTestMetricList()
- with open(opts.metrics, 'w') as f:
- f.write(json_format.MessageToJson(metrics))
-
- # If building for code coverage, build the 'coverage' target, which
- # builds the posix-based unit tests for code coverage and assembles
- # the LCOV information.
- #
- # Otherwise, build the 'runtests' target, which verifies all
- # posix-based unit tests build and pass.
- target = 'coverage' if opts.code_coverage else 'runtests'
- cmd = ['make', target, '-j{}'.format(opts.cpus)]
- print(f'# Running {" ".join(cmd)}.')
- subprocess.run(cmd,
- cwd=os.path.dirname(__file__),
- check=True)
-
- if not opts.code_coverage:
- # Verify compilation of the on-device unit test binaries.
- # TODO(b/172501728) These should build for all boards, but they've bit
- # rotted, so we only build the ones that compile.
- cmd = ['make', '-j{}'.format(opts.cpus)]
- cmd.extend(['tests-' + b for b in BOARDS_UNIT_TEST])
- print(f'# Running {" ".join(cmd)}.')
- subprocess.run(cmd,
- cwd=os.path.dirname(__file__),
- check=True)
-
-
-def main(args):
- """Builds, bundles, or tests all of the EC targets.
-
- Additionally, the tool reports build metrics.
- """
- opts = parse_args(args)
-
- if not hasattr(opts, 'func'):
- print('Must select a valid sub command!')
- return -1
-
- # Run selected sub command function
- try:
- opts.func(opts)
- except subprocess.CalledProcessError:
- return 1
- else:
- return 0
-
-
-def parse_args(args):
- parser = argparse.ArgumentParser(description=__doc__)
-
- parser.add_argument(
- '--cpus',
- default=multiprocessing.cpu_count(),
- help='The number of cores to use.',
- )
-
- parser.add_argument(
- '--metrics',
- dest='metrics',
- required=True,
- help='File to write the json-encoded MetricsList proto message.',
- )
-
- parser.add_argument(
- '--metadata',
- required=False,
- help='Full pathname for the file in which to write build artifact '
- 'metadata.',
- )
-
- parser.add_argument(
- '--output-dir',
- required=False,
- help='Full pathanme for the directory in which to bundle build '
- 'artifacts.',
- )
-
- parser.add_argument(
- '--code-coverage',
- required=False,
- action='store_true',
- help='Build host-based unit tests for code coverage.',
- )
-
- parser.add_argument(
- '--bcs-version',
- dest='bcs_version',
- default='',
- required=False,
- # TODO(b/180008931): make this required=True.
- 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.set_defaults(func=build)
-
- build_cmd = sub_cmds.add_parser('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.set_defaults(func=test)
-
- return parser.parse_args(args)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))