112246Sgabeblack@google.com# Copyright (c) 2013, 2015-2017 ARM Limited
212246Sgabeblack@google.com# All rights reserved.
312246Sgabeblack@google.com#
412246Sgabeblack@google.com# The license below extends only to copyright in the software and shall
512246Sgabeblack@google.com# not be construed as granting a license to any other intellectual
612246Sgabeblack@google.com# property including but not limited to intellectual property relating
712246Sgabeblack@google.com# to a hardware implementation of the functionality of the software
812246Sgabeblack@google.com# licensed hereunder.  You may use the software subject to the license
912246Sgabeblack@google.com# terms below provided that you ensure that this notice is replicated
1012246Sgabeblack@google.com# unmodified and in its entirety in all distributions of the software,
1112246Sgabeblack@google.com# modified or unmodified, in source code or in binary form.
1212246Sgabeblack@google.com#
1312246Sgabeblack@google.com# Copyright (c) 2011 Advanced Micro Devices, Inc.
1412246Sgabeblack@google.com# Copyright (c) 2009 The Hewlett-Packard Development Company
1512246Sgabeblack@google.com# Copyright (c) 2004-2005 The Regents of The University of Michigan
1612246Sgabeblack@google.com# All rights reserved.
1712246Sgabeblack@google.com#
1812246Sgabeblack@google.com# Redistribution and use in source and binary forms, with or without
1912246Sgabeblack@google.com# modification, are permitted provided that the following conditions are
2012246Sgabeblack@google.com# met: redistributions of source code must retain the above copyright
2112246Sgabeblack@google.com# notice, this list of conditions and the following disclaimer;
2212246Sgabeblack@google.com# redistributions in binary form must reproduce the above copyright
2312246Sgabeblack@google.com# notice, this list of conditions and the following disclaimer in the
2412246Sgabeblack@google.com# documentation and/or other materials provided with the distribution;
2512246Sgabeblack@google.com# neither the name of the copyright holders nor the names of its
2612246Sgabeblack@google.com# contributors may be used to endorse or promote products derived from
2712246Sgabeblack@google.com# this software without specific prior written permission.
2812246Sgabeblack@google.com#
2912246Sgabeblack@google.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3012246Sgabeblack@google.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3112246Sgabeblack@google.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3212246Sgabeblack@google.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3312246Sgabeblack@google.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3412246Sgabeblack@google.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3512246Sgabeblack@google.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3612246Sgabeblack@google.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3712246Sgabeblack@google.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3812246Sgabeblack@google.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3912246Sgabeblack@google.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4012246Sgabeblack@google.com
4112246Sgabeblack@google.comimport os
4212246Sgabeblack@google.com
4312246Sgabeblack@google.comfrom gem5_scons.util import get_termcap
4412246Sgabeblack@google.com
4512246Sgabeblack@google.comtermcap = get_termcap()
4612246Sgabeblack@google.com
4712246Sgabeblack@google.comdef strip_build_path(path, env):
4812246Sgabeblack@google.com    path = str(path)
4912246Sgabeblack@google.com    build_base = 'build/'
5012246Sgabeblack@google.com    variant_base = env['BUILDROOT'] + os.path.sep
5112246Sgabeblack@google.com    if path.startswith(variant_base):
5212246Sgabeblack@google.com        path = path[len(variant_base):]
5312246Sgabeblack@google.com    elif path.startswith(build_base):
5412246Sgabeblack@google.com        path = path[len(build_base):]
5512246Sgabeblack@google.com    return path
5612246Sgabeblack@google.com
5712246Sgabeblack@google.com# Generate a string of the form:
5812246Sgabeblack@google.com#   common/path/prefix/src1, src2 -> tgt1, tgt2
5912246Sgabeblack@google.com# to print while building.
6012246Sgabeblack@google.comclass Transform(object):
6112246Sgabeblack@google.com    # all specific color settings should be here and nowhere else
6212246Sgabeblack@google.com    tool_color = termcap.Normal
6312246Sgabeblack@google.com    pfx_color = termcap.Yellow
6412246Sgabeblack@google.com    srcs_color = termcap.Yellow + termcap.Bold
6512246Sgabeblack@google.com    arrow_color = termcap.Blue + termcap.Bold
6612246Sgabeblack@google.com    tgts_color = termcap.Yellow + termcap.Bold
6712246Sgabeblack@google.com
6812246Sgabeblack@google.com    def __init__(self, tool, max_sources=99):
6912246Sgabeblack@google.com        self.format = self.tool_color + (" [%8s] " % tool) \
7012246Sgabeblack@google.com                      + self.pfx_color + "%s" \
7112246Sgabeblack@google.com                      + self.srcs_color + "%s" \
7212246Sgabeblack@google.com                      + self.arrow_color + " -> " \
7312246Sgabeblack@google.com                      + self.tgts_color + "%s" \
7412246Sgabeblack@google.com                      + termcap.Normal
7512246Sgabeblack@google.com        self.max_sources = max_sources
7612246Sgabeblack@google.com
7712246Sgabeblack@google.com    def __call__(self, target, source, env, for_signature=None):
7812246Sgabeblack@google.com        # truncate source list according to max_sources param
7912246Sgabeblack@google.com        source = source[0:self.max_sources]
8012246Sgabeblack@google.com        def strip(f):
8112246Sgabeblack@google.com            return strip_build_path(str(f), env)
8212246Sgabeblack@google.com        if len(source) > 0:
8312246Sgabeblack@google.com            srcs = map(strip, source)
8412246Sgabeblack@google.com        else:
8512246Sgabeblack@google.com            srcs = ['']
8612246Sgabeblack@google.com        tgts = map(strip, target)
8712246Sgabeblack@google.com        # surprisingly, os.path.commonprefix is a dumb char-by-char string
8812246Sgabeblack@google.com        # operation that has nothing to do with paths.
8912246Sgabeblack@google.com        com_pfx = os.path.commonprefix(srcs + tgts)
9012246Sgabeblack@google.com        com_pfx_len = len(com_pfx)
9112246Sgabeblack@google.com        if com_pfx:
9212246Sgabeblack@google.com            # do some cleanup and sanity checking on common prefix
9312246Sgabeblack@google.com            if com_pfx[-1] == ".":
9412246Sgabeblack@google.com                # prefix matches all but file extension: ok
9512246Sgabeblack@google.com                # back up one to change 'foo.cc -> o' to 'foo.cc -> .o'
9612246Sgabeblack@google.com                com_pfx = com_pfx[0:-1]
9712246Sgabeblack@google.com            elif com_pfx[-1] == "/":
9812246Sgabeblack@google.com                # common prefix is directory path: OK
9912246Sgabeblack@google.com                pass
10012246Sgabeblack@google.com            else:
10112246Sgabeblack@google.com                src0_len = len(srcs[0])
10212246Sgabeblack@google.com                tgt0_len = len(tgts[0])
10312246Sgabeblack@google.com                if src0_len == com_pfx_len:
10412246Sgabeblack@google.com                    # source is a substring of target, OK
10512246Sgabeblack@google.com                    pass
10612246Sgabeblack@google.com                elif tgt0_len == com_pfx_len:
10712246Sgabeblack@google.com                    # target is a substring of source, need to back up to
10812246Sgabeblack@google.com                    # avoid empty string on RHS of arrow
10912246Sgabeblack@google.com                    sep_idx = com_pfx.rfind(".")
11012246Sgabeblack@google.com                    if sep_idx != -1:
11112246Sgabeblack@google.com                        com_pfx = com_pfx[0:sep_idx]
11212246Sgabeblack@google.com                    else:
11312246Sgabeblack@google.com                        com_pfx = ''
11412246Sgabeblack@google.com                elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".":
11512246Sgabeblack@google.com                    # still splitting at file extension: ok
11612246Sgabeblack@google.com                    pass
11712246Sgabeblack@google.com                else:
11812246Sgabeblack@google.com                    # probably a fluke; ignore it
11912246Sgabeblack@google.com                    com_pfx = ''
12012246Sgabeblack@google.com        # recalculate length in case com_pfx was modified
12112246Sgabeblack@google.com        com_pfx_len = len(com_pfx)
12212246Sgabeblack@google.com        def fmt(files):
12312246Sgabeblack@google.com            f = map(lambda s: s[com_pfx_len:], files)
12412246Sgabeblack@google.com            return ', '.join(f)
12512246Sgabeblack@google.com        return self.format % (com_pfx, fmt(srcs), fmt(tgts))
12612246Sgabeblack@google.com
12712246Sgabeblack@google.com__all__ = ['Transform']
128