#!/usr/bin/env python3
# Copyright (c) 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Summarize the last ninja build, invoked with ninja's -C syntax.

This script is designed to be automatically run after each ninja build in
order to summarize the build's performance. Making build performance information
more visible should make it easier to notice anomalies and opportunities. To use
this script on Windows just set NINJA_SUMMARIZE_BUILD=1 and run autoninja.bat.

On Linux you can get autoninja to invoke this script using this syntax:

$ NINJA_SUMMARIZE_BUILD=1 autoninja -C out/Default/ chrome

You can also call this script directly using ninja's syntax to specify the
output directory of interest:

> python3 post_build_ninja_summary.py -C out/Default

Typical output looks like this:

>ninja -C out\debug_component base
ninja.exe -C out\debug_component base -j 960 -l 48  -d keeprsp
ninja: Entering directory `out\debug_component'
[1 processes, 1/1 @ 0.3/s : 3.092s ] Regenerating ninja files
Longest build steps:
       0.1 weighted s to build obj/base/base/trace_log.obj (6.7 s elapsed time)
       0.2 weighted s to build nasm.exe, nasm.exe.pdb (0.2 s elapsed time)
       0.3 weighted s to build obj/base/base/win_util.obj (12.4 s elapsed time)
       1.2 weighted s to build base.dll, base.dll.lib (1.2 s elapsed time)
Time by build-step type:
       0.0 s weighted time to generate 6 .lib files (0.3 s elapsed time sum)
       0.1 s weighted time to generate 25 .stamp files (1.2 s elapsed time sum)
       0.2 s weighted time to generate 20 .o files (2.8 s elapsed time sum)
       1.7 s weighted time to generate 4 PEFile (linking) files (2.0 s elapsed
time sum)
      23.9 s weighted time to generate 770 .obj files (974.8 s elapsed time sum)
26.1 s weighted time (982.9 s elapsed time sum, 37.7x parallelism)
839 build steps completed, average of 32.17/s

If no gn clean has been done then results will be for the last non-NULL
invocation of ninja. Ideas for future statistics, and implementations are
appreciated.

The "weighted" time is the elapsed time of each build step divided by the number
of tasks that were running in parallel. This makes it an excellent approximation
of how "important" a slow step was. A link that is entirely or mostly serialized
will have a weighted time that is the same or similar to its elapsed time. A
compile that runs in parallel with 999 other compiles will have a weighted time
that is tiny."""

import argparse
import errno
import fnmatch
import os
import sys


# The number of long build times to report:
long_count = 10
# The number of long times by extension to report
long_ext_count = 10


class Target:
    """Represents a single line read for a .ninja_log file."""
    def __init__(self, start, end):
        """Creates a target object by passing in the start/end times in seconds
        as a float."""
        self.start = start
        self.end = end
        # A list of targets, appended to by the owner of this object.
        self.targets = []
        self.weighted_duration = 0.0

    def Duration(self):
        """Returns the task duration in seconds as a float."""
        return self.end - self.start

    def SetWeightedDuration(self, weighted_duration):
        """Sets the duration, in seconds, passed in as a float."""
        self.weighted_duration = weighted_duration

    def WeightedDuration(self):
        """Returns the task's weighted duration in seconds as a float.

        Weighted_duration takes the elapsed time of the task and divides it
        by how many other tasks were running at the same time. Thus, it
        represents the approximate impact of this task on the total build time,
        with serialized or serializing steps typically ending up with much
        longer weighted durations.
        weighted_duration should always be the same or shorter than duration.
        """
        # Allow for modest floating-point errors
        epsilon = 0.000002
        if (self.weighted_duration > self.Duration() + epsilon):
          print('%s > %s?' % (self.weighted_duration, self.Duration()))
        assert(self.weighted_duration <= self.Duration() + epsilon)
        return self.weighted_duration

    def DescribeTargets(self):
        """Returns a printable string that summarizes the targets."""
        # Some build steps generate dozens of outputs - handle them sanely.
        # The max_length was chosen so that it can fit most of the long
        # single-target names, while minimizing word wrapping.
        result = ', '.join(self.targets)
        max_length = 65
        if len(result) > max_length:
          result = result[:max_length] + '...'
        return result


# Copied with some modifications from ninjatracing
def ReadTargets(log, show_all):
    """Reads all targets from .ninja_log file |log_file|, sorted by duration.

    The result is a list of Target objects."""
    header = log.readline()
    assert header == '# ninja log v5\n', \
           'unrecognized ninja log version %r' % header
    targets_dict = {}
    last_end_seen = 0.0
    for line in log:
        parts = line.strip().split('\t')
        if len(parts) != 5:
          # If ninja.exe is rudely halted then the .ninja_log file may be
          # corrupt. Silently continue.
          continue
        start, end, _, name, cmdhash = parts # Ignore restat.
        # Convert from integral milliseconds to float seconds.
        start = int(start) / 1000.0
        end = int(end) / 1000.0
        if not show_all and end < last_end_seen:
            # An earlier time stamp means that this step is the first in a new
            # build, possibly an incremental build. Throw away the previous
            # data so that this new build will be displayed independently.
            # This has to be done by comparing end times because records are
            # written to the .ninja_log file when commands complete, so end
            # times are guaranteed to be in order, but start times are not.
            targets_dict = {}
        target = None
        if cmdhash in targets_dict:
          target = targets_dict[cmdhash]
          if not show_all and (target.start != start or target.end != end):
            # If several builds in a row just run one or two build steps then
            # the end times may not go backwards so the last build may not be
            # detected as such. However in many cases there will be a build step
            # repeated in the two builds and the changed start/stop points for
            # that command, identified by the hash, can be used to detect and
            # reset the target dictionary.
            targets_dict = {}
            target = None
        if not target:
          targets_dict[cmdhash] = target = Target(start, end)
        last_end_seen = end
        target.targets.append(name)
    return list(targets_dict.values())


def GetExtension(target, extra_patterns):
  """Return the file extension that best represents a target.

  For targets that generate multiple outputs it is important to return a
  consistent 'canonical' extension. Ultimately the goal is to group build steps
  by type."""
  for output in target.targets:
    if extra_patterns:
      for fn_pattern in extra_patterns.split(';'):
        if fnmatch.fnmatch(output, '*' + fn_pattern + '*'):
          return fn_pattern
    # Not a true extension, but a good grouping.
    if output.endswith('type_mappings'):
      extension = 'type_mappings'
      break

    # Capture two extensions if present. For example: file.javac.jar should be
    # distinguished from file.interface.jar.
    root, ext1 = os.path.splitext(output)
    _, ext2 = os.path.splitext(root)
    extension = ext2 + ext1 # Preserve the order in the file name.

    if len(extension) == 0:
      extension = '(no extension found)'

    if ext1 in ['.pdb', '.dll', '.exe']:
      extension = 'PEFile (linking)'
      # Make sure that .dll and .exe are grouped together and that the
      # .dll.lib files don't cause these to be listed as libraries
      break
    if ext1 in ['.so', '.TOC']:
      extension = '.so (linking)'
      # Attempt to identify linking, avoid identifying as '.TOC'
      break
    # Make sure .obj files don't get categorized as mojo files
    if ext1 in ['.obj', '.o']:
      break
    # Jars are the canonical output of java targets.
    if ext1 == '.jar':
      break
    # Normalize all mojo related outputs to 'mojo'.
    if output.count('.mojom') > 0:
      extension = 'mojo'
      break
  return extension


def SummarizeEntries(entries, extra_step_types):
    """Print a summary of the passed in list of Target objects."""

    # Create a list that is in order by time stamp and has entries for the
    # beginning and ending of each build step (one time stamp may have multiple
    # entries due to multiple steps starting/stopping at exactly the same time).
    # Iterate through this list, keeping track of which tasks are running at all
    # times. At each time step calculate a running total for weighted time so
    # that when each task ends its own weighted time can easily be calculated.
    task_start_stop_times = []

    earliest = -1
    latest = 0
    total_cpu_time = 0
    for target in entries:
      if earliest < 0 or target.start < earliest:
        earliest = target.start
      if target.end > latest:
        latest = target.end
      total_cpu_time += target.Duration()
      task_start_stop_times.append((target.start, 'start', target))
      task_start_stop_times.append((target.end, 'stop', target))
    length = latest - earliest
    weighted_total = 0.0

    # Sort by the time/type records and ignore |target|
    task_start_stop_times.sort(key=lambda times: times[:2])
    # Now we have all task start/stop times sorted by when they happen. If a
    # task starts and stops on the same time stamp then the start will come
    # first because of the alphabet, which is important for making this work
    # correctly.
    # Track the tasks which are currently running.
    running_tasks = {}
    # Record the time we have processed up to so we know how to calculate time
    # deltas.
    last_time = task_start_stop_times[0][0]
    # Track the accumulated weighted time so that it can efficiently be added
    # to individual tasks.
    last_weighted_time = 0.0
    # Scan all start/stop events.
    for event in task_start_stop_times:
      time, action_name, target = event
      # Accumulate weighted time up to now.
      num_running = len(running_tasks)
      if num_running > 0:
        # Update the total weighted time up to this moment.
        last_weighted_time += (time - last_time) / float(num_running)
      if action_name == 'start':
        # Record the total weighted task time when this task starts.
        running_tasks[target] = last_weighted_time
      if action_name == 'stop':
        # Record the change in the total weighted task time while this task ran.
        weighted_duration = last_weighted_time - running_tasks[target]
        target.SetWeightedDuration(weighted_duration)
        weighted_total += weighted_duration
        del running_tasks[target]
      last_time = time
    assert(len(running_tasks) == 0)

    # Warn if the sum of weighted times is off by more than half a second.
    if abs(length - weighted_total) > 500:
      print('Warning: Possible corrupt ninja log, results may be '
            'untrustworthy. Length = %.3f, weighted total = %.3f' % (
            length, weighted_total))

    # Print the slowest build steps (by weighted time).
    print('    Longest build steps:')
    entries.sort(key=lambda x: x.WeightedDuration())
    for target in entries[-long_count:]:
      print('      %8.1f weighted s to build %s (%.1f s elapsed time)' % (
            target.WeightedDuration(),
            target.DescribeTargets(), target.Duration()))

    # Sum up the time by file extension/type of the output file
    count_by_ext = {}
    time_by_ext = {}
    weighted_time_by_ext = {}
    # Scan through all of the targets to build up per-extension statistics.
    for target in entries:
      extension = GetExtension(target, extra_step_types)
      time_by_ext[extension] = time_by_ext.get(extension, 0) + target.Duration()
      weighted_time_by_ext[extension] = weighted_time_by_ext.get(extension,
              0) + target.WeightedDuration()
      count_by_ext[extension] = count_by_ext.get(extension, 0) + 1

    print('    Time by build-step type:')
    # Copy to a list with extension name and total time swapped, to (time, ext)
    weighted_time_by_ext_sorted = sorted((y, x) for (x, y) in
                                          weighted_time_by_ext.items())
    # Print the slowest build target types (by weighted time):
    for time, extension in weighted_time_by_ext_sorted[-long_ext_count:]:
        print('      %8.1f s weighted time to generate %d %s files '
               '(%1.1f s elapsed time sum)' % (time, count_by_ext[extension],
                                        extension, time_by_ext[extension]))

    print('    %.1f s weighted time (%.1f s elapsed time sum, %1.1fx '
          'parallelism)' % (length, total_cpu_time,
          total_cpu_time * 1.0 / length))
    print('    %d build steps completed, average of %1.2f/s' % (
          len(entries), len(entries) / (length)))


def main():
    log_file = '.ninja_log'
    parser = argparse.ArgumentParser()
    parser.add_argument('-C', dest='build_directory',
                        help='Build directory.')
    parser.add_argument(
        '-s',
        '--step-types',
        help='semicolon separated fnmatch patterns for build-step grouping')
    parser.add_argument('--log-file',
                        help="specific ninja log file to analyze.")
    args, _extra_args = parser.parse_known_args()
    if args.build_directory:
        log_file = os.path.join(args.build_directory, log_file)
    if args.log_file:
        log_file = args.log_file
    if not args.step_types:
      # Offer a convenient way to add extra step types automatically, including
      # when this script is run by autoninja. get() returns None if the variable
      # isn't set.
      args.step_types = os.environ.get('chromium_step_types')
    if args.step_types:
      # Make room for the extra build types.
      global long_ext_count
      long_ext_count += len(args.step_types.split(';'))

    try:
      with open(log_file, 'r') as log:
        entries = ReadTargets(log, False)
        SummarizeEntries(entries, args.step_types)
    except IOError:
      print('Log file %r not found, no build summary created.' % log_file)
      return errno.ENOENT


if __name__ == '__main__':
    sys.exit(main())
