blob: d82cead55a3378cca27c3f3e38161aa2616d39d2 [file]
# Copyright 2023 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Gonk build script."""
import argparse
import logging
from pathlib import Path
import shutil
import sys
import pw_cli.log
from pw_build.build_recipe import (
BuildCommand,
BuildRecipe,
)
from pw_build.project_builder_argparse import add_project_builder_arguments
from pw_build.build_recipe import should_gn_gen_with_args
from pw_build.project_builder import ProjectBuilder
from pw_presubmit.build import gn_args
_LOG = logging.getLogger('pw_build')
_ENABLE_FPGA_BUILD = (
shutil.which('nextpnr-ice40')
and shutil.which('yosys')
and shutil.which('icepack')
and shutil.which('icetime')
)
def build_project() -> int:
"""Use pw_build to compile Gonk.
Defines BuildRecipes and passes them to Pigweed's ProjectBuilder.
Returns:
An int representing the success or failure status of the build; 0 if
successful, 1 if failed.
Command line usage examples:
.. code-block:: bash
pw build
"""
default_gn_gen_command = [
'gn',
'gen',
'{build_dir}',
'--export-compile-commands',
]
default_gn_args: dict[str, str] = {}
default_gn_gen_command.append(gn_args(**default_gn_args))
default_targets = ['default']
if _ENABLE_FPGA_BUILD:
# Build the FPGA image, gonk tools bundle, and pip install the
# gonk_firmware package into the bootstrap venv.
default_targets += ['fpga', 'gonk_bundle', 'pip_install_gonk_firmware']
else:
_LOG.warning(
'FPGA build disabled. The following tools were not found: '
'icepack, icetime, nextpnr-ice40, yosys.'
)
default_build_steps = [
BuildCommand(
run_if=should_gn_gen_with_args(default_gn_args),
command=default_gn_gen_command,
),
BuildCommand(
build_system_command='ninja',
targets=default_targets,
),
]
build_recipes = [
BuildRecipe(
build_dir=Path('out/gn'),
title='default',
steps=default_build_steps,
),
]
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser = add_project_builder_arguments(parser)
args = parser.parse_args()
log_level = logging.DEBUG if args.debug_logging else logging.INFO
pw_cli.log.install(
level=log_level,
use_color=args.colors,
hide_timestamp=False,
)
builder = ProjectBuilder(
build_recipes=build_recipes,
jobs=args.jobs,
banners=args.banners,
keep_going=args.keep_going,
colors=args.colors,
separate_build_file_logging=args.separate_logfiles,
root_logfile=args.logfile,
root_logger=_LOG,
log_level=log_level,
)
if builder.should_use_progress_bars():
builder.use_stdout_proxy()
workers = 1
if args.parallel:
# If parallel is requested and parallel_workers is set to 0 run all
# recipes in parallel. That is, use the number of recipes as the worker
# count.
if args.parallel_workers == 0:
workers = len(builder)
else:
workers = args.parallel_workers
return builder.run_builds(workers)
if __name__ == '__main__':
sys.exit(build_project())