1# Copyright (c) 2013, 2015-2017 ARM Limited 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated 10# unmodified and in its entirety in all distributions of the software, 11# modified or unmodified, in source code or in binary form. 12# 13# Copyright (c) 2011 Advanced Micro Devices, Inc. 14# Copyright (c) 2009 The Hewlett-Packard Development Company 15# Copyright (c) 2004-2005 The Regents of The University of Michigan 16# All rights reserved. 17# 18# Redistribution and use in source and binary forms, with or without 19# modification, are permitted provided that the following conditions are 20# met: redistributions of source code must retain the above copyright 21# notice, this list of conditions and the following disclaimer; 22# redistributions in binary form must reproduce the above copyright 23# notice, this list of conditions and the following disclaimer in the 24# documentation and/or other materials provided with the distribution; 25# neither the name of the copyright holders nor the names of its 26# contributors may be used to endorse or promote products derived from 27# this software without specific prior written permission. 28# 29# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 41import os 42 43from gem5_scons.util import get_termcap 44 45termcap = get_termcap() 46 47def strip_build_path(path, env): 48 path = str(path) 49 build_base = 'build/' 50 variant_base = env['BUILDROOT'] + os.path.sep 51 if path.startswith(variant_base): 52 path = path[len(variant_base):] 53 elif path.startswith(build_base): 54 path = path[len(build_base):] 55 return path 56 57# Generate a string of the form: 58# common/path/prefix/src1, src2 -> tgt1, tgt2 59# to print while building. 60class Transform(object): 61 # all specific color settings should be here and nowhere else 62 tool_color = termcap.Normal 63 pfx_color = termcap.Yellow 64 srcs_color = termcap.Yellow + termcap.Bold 65 arrow_color = termcap.Blue + termcap.Bold 66 tgts_color = termcap.Yellow + termcap.Bold 67 68 def __init__(self, tool, max_sources=99): 69 self.format = self.tool_color + (" [%8s] " % tool) \ 70 + self.pfx_color + "%s" \ 71 + self.srcs_color + "%s" \ 72 + self.arrow_color + " -> " \ 73 + self.tgts_color + "%s" \ 74 + termcap.Normal 75 self.max_sources = max_sources 76 77 def __call__(self, target, source, env, for_signature=None): 78 # truncate source list according to max_sources param 79 source = source[0:self.max_sources] 80 def strip(f): 81 return strip_build_path(str(f), env) 82 if len(source) > 0: 83 srcs = map(strip, source) 84 else: 85 srcs = [''] 86 tgts = map(strip, target) 87 # surprisingly, os.path.commonprefix is a dumb char-by-char string 88 # operation that has nothing to do with paths. 89 com_pfx = os.path.commonprefix(srcs + tgts) 90 com_pfx_len = len(com_pfx) 91 if com_pfx: 92 # do some cleanup and sanity checking on common prefix 93 if com_pfx[-1] == ".": 94 # prefix matches all but file extension: ok 95 # back up one to change 'foo.cc -> o' to 'foo.cc -> .o' 96 com_pfx = com_pfx[0:-1] 97 elif com_pfx[-1] == "/": 98 # common prefix is directory path: OK 99 pass 100 else: 101 src0_len = len(srcs[0]) 102 tgt0_len = len(tgts[0]) 103 if src0_len == com_pfx_len: 104 # source is a substring of target, OK 105 pass 106 elif tgt0_len == com_pfx_len: 107 # target is a substring of source, need to back up to 108 # avoid empty string on RHS of arrow 109 sep_idx = com_pfx.rfind(".") 110 if sep_idx != -1: 111 com_pfx = com_pfx[0:sep_idx] 112 else: 113 com_pfx = '' 114 elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".": 115 # still splitting at file extension: ok 116 pass 117 else: 118 # probably a fluke; ignore it 119 com_pfx = '' 120 # recalculate length in case com_pfx was modified 121 com_pfx_len = len(com_pfx) 122 def fmt(files): 123 f = map(lambda s: s[com_pfx_len:], files) 124 return ', '.join(f) 125 return self.format % (com_pfx, fmt(srcs), fmt(tgts)) 126 127__all__ = ['Transform'] 128