/ scripts / cfg / helper.py
helper.py
  1  #
  2  # Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved.
  3  #
  4  # Redistribution and use in source and binary forms, with or without modification,
  5  # are permitted provided that the following conditions are met:
  6  # 1. Redistributions of source code must retain the above copyright notice,
  7  #    this list of conditions and the following disclaimer.
  8  # 2. Redistributions in binary form must reproduce the above copyright notice,
  9  #    this list of conditions and the following disclaimer in the documentation
 10  #    and/or other materials provided with the distribution.
 11  # 3. Neither the name of the copyright holder nor the names of its contributors
 12  #    may be used to endorse or promote products derived from this software without
 13  #    specific prior written permission.
 14  #
 15  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 16  # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 17  # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 18  # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 19  # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 20  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 21  # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 22  # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 24  # POSSIBILITY OF SUCH DAMAGE.
 25  
 26  from SCons.Script import GetOption
 27  
 28  import os
 29  
 30  def strip_build_path(path, env):
 31      path = str(path)
 32      #print('path before-> ' , path)
 33      bld_root = env['BUILDROOT'] + '/'
 34      #bld_root_src = bld_root + 'src' + '/'
 35      bases = ['src/', 'tests/', bld_root] #, bld_root_src]
 36      for b in bases:
 37          if path.startswith(b):
 38              path = path[len(b):]
 39              #break
 40      #print('path', path)
 41      return path
 42  
 43  #
 44  # Parts are taken from Gem5, many thanks to Gem5 authors
 45  class Transform(object):
 46      def __init__(self, tool, hidesrc = False, max_sources=99):
 47          self.hidesrc =  hidesrc
 48          if hidesrc:
 49              self.format = (" [%6s] " % tool) + "%s"
 50          else:
 51              self.format = (" [%6s] " % tool) + "%s" " => " + "%s"
 52          self.max_sources = max_sources
 53  
 54      def __call__(self, target, source, env, for_signature=None):
 55          #print('call called', target, source)
 56          source = source[0:self.max_sources]
 57          def strip(f):
 58              return strip_build_path(str(f), env)
 59  
 60          if len(source) > 0:
 61              srcs = map(strip, source)
 62          else:
 63              srcs = ['']
 64  
 65  
 66          newsrcs = list(srcs)
 67          #import pdb
 68          #pdb.set_trace()
 69          tgts = map(strip, target)
 70          #print("==>", srcs, tgts)
 71          newtgts = list(tgts)
 72  
 73          from os.path import commonprefix
 74          # surprisingly, os.path.commonprefix is a dumb char-by-char string
 75          # operation that has nothing to do with paths.
 76          com_pfx = '' # commonprefix(newsrcs + newtgts)
 77          com_pfx_len = len(com_pfx)
 78  
 79          if com_pfx:
 80              # do some cleanup and sanity checking on common prefix
 81              if com_pfx[-1] == ".":
 82                  # prefix matches all but file extension: ok
 83                  # back up one to change 'foo.cc -> o' to 'foo.cc -> .o'
 84                  com_pfx = os.path.dirname(com_pfx[0:-1]) + os.path.sep
 85              elif com_pfx[-1] == "/":
 86                  # common prefix is directory path: OK
 87                  pass
 88              else:
 89                  src0_len = len(newsrcs[0])
 90                  tgt0_len = len(newtgts[0])
 91  
 92                  if src0_len == com_pfx_len:
 93                      # source is a substring of target, OK
 94                      pass
 95                  elif tgt0_len == com_pfx_len:
 96                      # target is a substring of source, need to back up to
 97                      # avoid empty string on RHS of arrow
 98                      sep_idx = com_pfx.rfind(".")
 99                      if sep_idx != -1:
100                          com_pfx = com_pfx[0:sep_idx]
101                      else:
102                          com_pfx = ''
103                  elif src0_len > com_pfx_len and newsrcs[0][com_pfx_len] == ".":
104                      # still splitting at file extension: ok
105                      pass
106                  else:
107                      # probably a fluke; ignore it
108                      com_pfx += os.path.sep
109  
110          com_pfx_len = len(com_pfx)
111  
112          def fmt(files):
113              #f = []
114              #for s in files:
115              #    if s.startswith(com_pfx):
116              #        f.append(s[com_pfx_len:])
117              #    else:
118              #        f.append(s)
119  
120              f = map(lambda s: s[com_pfx_len:] if s.startswith(com_pfx) else s, files)
121              return ', '.join(f)
122  
123          if self.hidesrc:
124              return self.format%(fmt(newtgts))
125  
126          return self.format%(fmt(newsrcs), fmt(newtgts))
127  
128      def __str__(self):
129          return self.format
130  
131  def UpdateEnvComStr(env):
132      if not env['verbose']:
133          env['CCCOMSTR']     = Transform('CC')
134          env['CXXCOMSTR']    = Transform('CXX')
135          env['ASCOMSTR']     = Transform('AS')
136          env['ARCOMSTR']     = Transform('AR', hidesrc=True)
137          env['ASPPCOMSTR']   = Transform('AS')
138          env['LINKCOMSTR']   = Transform('LINK', hidesrc=True)
139          env['RANLIBCOMSTR'] = Transform('RANLIB', hidesrc=True)
140          env["SHCCCOMSTR"]   = Transform('SHCC')
141          env["SHLINKCOMSTR"] = Transform('SHLINK', hidesrc=True)
142  
143  def MakeBuildRoot(env):
144      """Build root has
145         build/<libabi>-<debug/release/developer>
146      """
147      try:
148          b = env['BUILDROOT']
149      except KeyError:
150          b = 'build'
151  
152      build_mode_to_dir = {
153          'debug'     : '-debug',
154          'release'   : '-release',
155          'developer' : '-dev'
156      }
157  
158      b += '/' + '%s'%(env['libabi'])
159      if  env['debug_mode'] != GetOption('debug_mode'):
160          dbg = GetOption('debug_mode')
161      else:
162          dbg = env['debug_mode']
163  
164      if dbg == 'libs' or dbg == 'all':
165          b += "%s"%build_mode_to_dir['debug']
166      else:
167          if env['developer'] > 0:
168              b += "%s%d"%(build_mode_to_dir['developer'],env['developer'])
169          else:
170              b += build_mode_to_dir['release']
171  
172      env['BUILDROOT'] = b
173      #print('buildroot', b)
174  
175  def SetupConfiguration(env):
176          """Build the test program;
177          prepends "test_" to src and target,
178          and puts target into testdir."""
179          #print(env.Dump())
180          MakeBuildRoot(env)
181          UpdateEnvComStr(env)
182  
183          if env['debug_mode'] != 'no':
184              env.Append(CPPDEFINES = {'DEBUG': '1'})
185  
186  def PrintBanner(env):
187          print("====================== Configuration ======================")
188          print("""
189          Compiler     : %-20s  Build    : %s
190          ABI          : %-20s  Developer: %s
191          ToolchainDir : %s
192          BuildDir     : %s
193          """% (
194              env['compiler'], env['build'],
195              env['libabi'], env['developer'],
196              env['toolchain_base'],
197              env['BUILDROOT']
198          ))
199          print("===========================================================")
200