blob: d16e77b7f226ca2cf76e6fa7c8cf065fdc36ade6 [file] [log] [blame]
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from recipe_engine import recipe_api
class NinjaApi(recipe_api.RecipeApi):
"""APIs for interacting with Ninja.
Clients must call set_path before using this module, to point to the prebuilt Ninja
binary.
"""
def __init__(self, *args, **kwargs):
super(NinjaApi, self).__init__(*args, **kwargs)
self._exe = None
def __call__(self,
build_dir,
targets,
step_name='ninja',
job_count=None,
build_file=None,
fail_threshold=None,
verbose=False):
"""Runs Ninja.
Args:
build_dir (Path): CD into this directory before executing.
job_count (int): No. parallel jobs (Ninja default is to guess from available CPUs).
targets (List(string)): List of targets to build.
build_file (Path): Ninja build file (default=build.ninja)
fail_threshold (int): Keep going until this many jobs fail (Ninja default of 1).
step_name (string): Step name (default: 'ninja').
verbose (bool): Show all command lines when building.
Returns:
The step result of running Ninja.
"""
assert self._exe, 'missing executable. Did you call set_path?'
# Construct command for ninja
ninja_command = [
self._exe,
'-C',
build_dir,
]
if job_count:
ninja_command.extend(['-j', job_count])
if build_file:
ninja_command.extend(['-f', build_file])
if fail_threshold:
ninja_command.extend(['-k', fail_threshold])
if verbose:
ninja_command.append('-v')
# Sort the targets for a deterministic ordering. This will ease reviews,
# as a re-ordering of build logic will yield the same ninja invocation.
ninja_command.extend(sorted(targets))
# Use ninja_wrapper to run ninja build
ninja_wrapper_args = [
'--ninja_info_output',
self.m.json.output(
add_json_log='on_failure', name='failure_json_summary'),
'--failure_output',
self.m.raw_io.output(
add_output_log='on_failure', name='failure_raw_summary'),
]
ninja_wrapper_args.append('--')
ninja_wrapper_args.extend(ninja_command)
test_json = {
'failures': [{
'output_nodes': ['a.o'],
'rule': 'CXX',
'output': 'error info',
'dependencies': ['b/a.cc']
}]
}
test_failure_output = '[1/1] CXX a.o\nerror info\n'
step_test_data = (
lambda: self.m.json.test_api.output(test_json, name='ninja_info') + self
.m.raw_io.test_api.output(test_failure_output, name='failure_summary'))
return self.m.python(
step_name,
script=self.resource('ninja_wrapper.py'),
args=ninja_wrapper_args,
step_test_data=step_test_data)
def set_path(self, path):
"""Sets the path to the Ninja executable."""
self._exe = path