| # Copyright (c) 2013, 2015-2017 ARM Limited | |
| # All rights reserved. | |
| # | |
| # The license below extends only to copyright in the software and shall | |
| # not be construed as granting a license to any other intellectual | |
| # property including but not limited to intellectual property relating | |
| # to a hardware implementation of the functionality of the software | |
| # licensed hereunder. You may use the software subject to the license | |
| # terms below provided that you ensure that this notice is replicated | |
| # unmodified and in its entirety in all distributions of the software, | |
| # modified or unmodified, in source code or in binary form. | |
| # | |
| # Copyright (c) 2011 Advanced Micro Devices, Inc. | |
| # Copyright (c) 2009 The Hewlett-Packard Development Company | |
| # Copyright (c) 2004-2005 The Regents of The University of Michigan | |
| # All rights reserved. | |
| # | |
| # Redistribution and use in source and binary forms, with or without | |
| # modification, are permitted provided that the following conditions are | |
| # met: redistributions of source code must retain the above copyright | |
| # notice, this list of conditions and the following disclaimer; | |
| # redistributions in binary form must reproduce the above copyright | |
| # notice, this list of conditions and the following disclaimer in the | |
| # documentation and/or other materials provided with the distribution; | |
| # neither the name of the copyright holders nor the names of its | |
| # contributors may be used to endorse or promote products derived from | |
| # this software without specific prior written permission. | |
| # | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| import os | |
| from gem5_scons.util import get_termcap | |
| termcap = get_termcap() | |
| def strip_build_path(path, env): | |
| path = str(path) | |
| build_base = 'build/' | |
| variant_base = env['BUILDROOT'] + os.path.sep | |
| if path.startswith(variant_base): | |
| path = path[len(variant_base):] | |
| elif path.startswith(build_base): | |
| path = path[len(build_base):] | |
| return path | |
| # Generate a string of the form: | |
| # common/path/prefix/src1, src2 -> tgt1, tgt2 | |
| # to print while building. | |
| class Transform(object): | |
| # all specific color settings should be here and nowhere else | |
| tool_color = termcap.Normal | |
| pfx_color = termcap.Yellow | |
| srcs_color = termcap.Yellow + termcap.Bold | |
| arrow_color = termcap.Blue + termcap.Bold | |
| tgts_color = termcap.Yellow + termcap.Bold | |
| def __init__(self, tool, max_sources=99): | |
| self.format = self.tool_color + (" [%8s] " % tool) \ | |
| + self.pfx_color + "%s" \ | |
| + self.srcs_color + "%s" \ | |
| + self.arrow_color + " -> " \ | |
| + self.tgts_color + "%s" \ | |
| + termcap.Normal | |
| self.max_sources = max_sources | |
| def __call__(self, target, source, env, for_signature=None): | |
| # truncate source list according to max_sources param | |
| source = source[0:self.max_sources] | |
| def strip(f): | |
| return strip_build_path(str(f), env) | |
| if len(source) > 0: | |
| srcs = map(strip, source) | |
| else: | |
| srcs = [''] | |
| tgts = map(strip, target) | |
| # surprisingly, os.path.commonprefix is a dumb char-by-char string | |
| # operation that has nothing to do with paths. | |
| com_pfx = os.path.commonprefix(srcs + tgts) | |
| com_pfx_len = len(com_pfx) | |
| if com_pfx: | |
| # do some cleanup and sanity checking on common prefix | |
| if com_pfx[-1] == ".": | |
| # prefix matches all but file extension: ok | |
| # back up one to change 'foo.cc -> o' to 'foo.cc -> .o' | |
| com_pfx = com_pfx[0:-1] | |
| elif com_pfx[-1] == "/": | |
| # common prefix is directory path: OK | |
| pass | |
| else: | |
| src0_len = len(srcs[0]) | |
| tgt0_len = len(tgts[0]) | |
| if src0_len == com_pfx_len: | |
| # source is a substring of target, OK | |
| pass | |
| elif tgt0_len == com_pfx_len: | |
| # target is a substring of source, need to back up to | |
| # avoid empty string on RHS of arrow | |
| sep_idx = com_pfx.rfind(".") | |
| if sep_idx != -1: | |
| com_pfx = com_pfx[0:sep_idx] | |
| else: | |
| com_pfx = '' | |
| elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".": | |
| # still splitting at file extension: ok | |
| pass | |
| else: | |
| # probably a fluke; ignore it | |
| com_pfx = '' | |
| # recalculate length in case com_pfx was modified | |
| com_pfx_len = len(com_pfx) | |
| def fmt(files): | |
| f = map(lambda s: s[com_pfx_len:], files) | |
| return ', '.join(f) | |
| return self.format % (com_pfx, fmt(srcs), fmt(tgts)) | |
| __all__ = ['Transform'] |