amtool.py :  » Build » Waf » waf-1.5.17 » utils » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Build » Waf 
Waf » waf 1.5.17 » utils » amtool.py
#! /usr/bin/env python

##
# @file
# waf Makefile.am related classed
#
# note: may be a future base of a Makefile.am to scons converter if someone like to write it
#
# (@) 2005 Ralf Habacker  - published under the GPL license
#

import os, re, types, sys, string, shutil, stat, glob

## print a dictionary
def printDict(dict,sep=' = ' ):
  for key in dict.keys():
    print key  + sep + dict[key]


## Makefile.am support class
#
# The class provides methods for the following tasks:
#    - parsing Makefile.am's and collecting targets and defines into class members
#    - extracting library dependencies and linker flags keyed by the related targets
#    - extracting target libraries and programs
#    - collecting detailled lists of libraries dependencies
#
#
class AMFile:
  def __init__(self):
    self.defines = {}
    self.targets = {}
    self.libadds = {}
    self.ldflags = {}
    self.libs    = {}
    self.progs   = {}
    self.sources = {}
    self.includes= {}
    self.headers = {}
    self.data    = {}
    self.datadirs= {}
    self.path    = ''
    self.subdirs = ''

  ## read and parse a Makefile.am
  #
  # The resulting lines are stored in the defines and targets class member.
  # note: Multiple lines in a target are separated by '###'
  # @param path - path for Makefile.am
  # @return 0 if file couldn't be read
  #
  def read(self,path):
    try:
      src=open(path, 'r')
    except:
      return 0
    self.path = path

    file  = src.read()
    lines = file.replace('\n\t','###')
    list = lines.replace('\\\n',' ').split('\n')
    for line in list:
      if line[:1] == '#' or len(line) == 0:
        continue

      index = 0
      while line[index].count('#'):
        index = line[index].index('#')
        if line[index:index+3] == "###":
          index += 3

      var = line.split('=')
      if len(var) == 2:
        self.defines[str(var[0]).strip()] = var[1].strip().replace("'",'').replace('\###',' ')
      else:
        target = line.split(':')
        if len(target) == 2:
          single_target = target[1].strip().replace("'",'')
          # TODO: (rh) split into list
          self.targets[str(target[0]).strip()] = single_target
    self.getLibraries()
    self.getPrograms()
    self.getIncludes()
    self.getHeaders()
    self.getSources()
    self.getLibraryDeps()
    self.getLinkerFlags()
    self.getSubdirs()
    self.getData()

    return 1

  ## adds library dependencies from another AMFile instance
  #
  # This method is mainly used for an instance collecting definitions
  # from instances from lower levels
  # @param src - AMFile instance, from which the dependencies are imported
  #
  def addLibraryDeps(self,src):
    for key in src.libadds.keys():
      self.libadds[key] = src.libadds[key]

  ## adds linker flags from another AMFile instance
  #
  # This method is mainly used for an instance collecting definitions
  # from instances from lower levels
  # @param src - AMFile instance, from which the flags are imported
  #
  def addLinkerFlags(self,src):
    for key in src.ldflags.keys():
      self.ldflags[key] = src.ldflags[key]

  def addSources(self,src):
    for key in src.sources.keys():
      self.sources[key] = src.sources[key]

  def addLibraries(self,src):
    for key in src.libs.keys():
      self.libs[key] = src.libs[key]

  def getSubdirs(self):
    if self.defines.has_key('SUBDIRS'):
      self.subdirs = self.defines['SUBDIRS']
      del self.defines['SUBDIRS']
  ## collect all LIBADDS definitions
  #
  # the function store the definitions in the libadds class member keyed
  # by the relating target
  # @return definition list
  #
  def getLibraryDeps(self):
    reg = re.compile("(.*?)_(?:l?a_)?LIBADD$")
    # TODO (rh) fix relative library pathes
    for key in self.defines.keys():
      result=reg.match(key)
      if result:
        libadd = self.findRealTargetname(str(result.group(1)))
        if not len(libadd):
          print "WARNING: no corresponding target for libadd item %s \n" % str(result.group(1))
          continue
        self.libadds[libadd] = self.defines[key]
        del self.defines[key]
    return self.libadds

  ## collect all LDFLAGS definitions
  #
  # the function store the definitions in the ldflags class member keyed
  # by the relating target
  # @return definition list
  #
  def getLinkerFlags(self):
    reg = re.compile("(.*?)_(?:l?a_)?LDFLAGS$")
    for key in self.defines.keys():
      result=reg.match(key)
      if result:
        ldflag = self.findRealTargetname(str(result.group(1)))
        if not len(ldflag):
          print "WARNING: no corresponding target for ldflag item %s \n" % str(result.group(1))
          continue
        self.ldflags[ldflag] = self.defines[key]
        del self.defines[key]
    return self.ldflags

  ## collect all LTLIBRARIES definitions
  #
  # the function store the definitions in the libraries class member keyed
  # by the relating target
  # @return definition list
  #
  def getLibraries(self):
    def stripLibname(val):
      reg = re.compile("(?:lib)?(.*)\.l?a$")
      files = val.split()
      retlist = []
      for file in files:
        result=reg.match(file)
        if result:
          retlist.append(str(result.group(1)))
      return ' '.join(retlist)
    reg = re.compile("(.*)(_l?a)?_(?:LT)?LIBRARIES$")
    for key in self.defines.keys():
      result=reg.match(key)
      if result:
        libtype = str(result.group(1))
        if not self.libs.has_key(libtype):
          self.libs[libtype] = ""
        self.libs[libtype] = stripLibname(self.defines[key])
        del self.defines[key]
    return self.libs

  def getPrograms(self):
    reg = re.compile("(.*)_PROGRAMS$")
    for key in self.defines.keys():
      result=reg.match(key)
      if result:
        progtype = str(result.group(1))
        if not self.progs.has_key(progtype):
          self.progs[progtype] = ""
        self.progs[progtype] = self.defines[key]
        del self.defines[key]
    return self.progs

  def getData(self):
    reg = re.compile("(.*)_DATA$")
    for key in self.defines.keys():
      result=reg.match(key)
      if result:
        dat = str(result.group(1))
        self.data[dat] = self.defines[key]
        del self.defines[key]
    for name in self.data.keys():
      if self.defines.has_key(name+"dir"):
        self.datadirs[name] = self.defines[name+"dir"]
        del self.defines[name+"dir"]
      else:
        del self.data[name]

    return self.data

  ## collect all SOURCES definitions
  #
  # the function store the definitions in the sources class member keyed
  # by the relating target
  # this function should be called after getPrograms and getLibraries
  # @return definition list
  #
  def getSources(self):
    reg = re.compile("(.*?)METASOURCES$")
    reg = re.compile("(.*?)_(?:l?a_)?SOURCES$")
    # TODO (rh) fix relative library paths
    for key in self.defines.keys():
      if key.endswith('METASOURCES') and self.defines[key] == "AUTO":
        del self.defines[key]
        continue

      result=reg.match(key)
      if result:
        source = self.findRealTargetname(str(result.group(1)))
        if not len(source):
          print "WARNING: no corresponding target for source item %s \n" % str(result.group(1))
          continue
        self.sources[source] = self.defines[key]
        del self.defines[key]
    return self.sources

  def findRealTargetname(self, target):
    def findInDict(dict, target):
      for key in dict.keys():
        targets = dict[key].split()
        if targets.count(target) > 0:
          return 1
      return 0
    if not findInDict(self.progs, target) and not findInDict(self.libs, target):
      if target[:3] == "lib":
        target = target[3:]
        if not findInDict(self.libs, target):
          target = ""
      else:
        target = ""
    return target

  def getIncludes(self):
    #if we've got a dir global includes, save it in self.includes['_DIR_GLOBAL_']
    if self.defines.has_key('INCLUDES'):
      self.defines['_DIR_GLOBAL__INCLUDES'] = self.defines['INCLUDES']
      del self.defines['INCLUDES']
    reg = re.compile("(.*?)_(?:l?a_)?INCLUDES")
    # TODO (rh) fix relative library pathes
    for key in self.defines.keys():
      result=reg.match(key)
      if result:
        include = self.findRealTargetname(str(result.group(1)))
        if not len(include):
          include = result.group(1)
        self.includes[include] = self.defines[key]
        del self.defines[key]
    return self.includes

  def convertMakeFileVariable(self, var):
    var = var.strip()
    if var[:2] == '$(' and var[-1:] == ')':
      return var[2:-1]
    else:
      return var

  def getHeaders(self):
    #if we've got a dir global includes, save it in self.headers['_DIR_GLOBAL_']
    if self.defines.has_key('HEADERS'):
      self.defines['_DIR_GLOBAL__HEADERS'] = self.defines['HEADERS']
      del self.defines['HEADERS']
    reg = re.compile("(.*?)_(?:l?a_)?HEADERS")
    # TODO (rh) fix relative library paths
    for key in self.defines.keys():
      result=reg.match(key)
      if result:
        header = self.findRealTargetname(str(result.group(1)))
        if not len(header):
          header = result.group(1)
        self.headers[header] = self.defines[key]
        del self.defines[key]
    return self.headers

  ## return a reverse usage list of dependencies
  #
  # The function scannes the recent library definitions and reorganice
  # the resulting list keyed by the used library
  # @return dependency list
  #
  def getReverseLibraryDeps(self):
    alist = {}
    for key in self.libadds.keys():
      for lib in self.libadds[key].split():
        if lib in alist:
          alist[str(lib)] += " " + key
        else:
          alist[str(lib)] = key
    return alist

  def printDefines(self):
    print "### DEFINES:"
    printDict(self.defines,' = ')

  def printTargets(self):
    print "### TARGETS:"
    printDict(self.targets,' : ')

  def printLibraryDeps(self):
    print "### LIBADD:"
    printDict(self.libadds,' : ')

  def printLinkerFlags(self):
    print "### LDFLAGS:"
    printDict(self.ldflags,' : ')

  def printLibraries(self):
    print "### Libraries:"
    printDict(self.libs,' : ')

  def printSources(self):
    print "### Sources:"
    printDict(self.sources,' : ')


def amview():
  uses = 0
  libadds = 0
  ldflags = 0
  defines = 0
  targets = 0
  libs = 0
  sources = 0
  if len(sys.argv) == 1:
    print "amtool [options] Makefile.am [Makefile.am] ..."
    print "list Makefile.am content"
    print "options:"
    print "    --uses print where a library is used"
    print "    --libadd print all LIBADD depenencies "
    print "    --ldflags print all LDFLAGS definitions"
    print "    --defines print all Makefile variables"
    print "    --targets print all Makefile targets"
    print "    --libs print all library definitions"
    print "    --sources print all source definitions"
  else:
    all_ams = AMFile()
    for a in range(1,len(sys.argv)):
      if sys.argv[a][:6] == '--uses':
        uses = 1
      elif sys.argv[a][:8] == '--libadd':
        libadds = 1
      elif sys.argv[a][:9] == '--defines':
        defines = 1
      elif sys.argv[a][:9] == '--targets':
        targets = 1
      elif sys.argv[a][:9] == '--ldflags':
        ldflags = 1
      elif sys.argv[a][:6] == '--libs':
        libs = 1
      elif sys.argv[a][:9] == '--sources':
        sources = 1
      if  libadds or defines or targets or ldflags or libs or sources:
        uses = 2

    for a in range(1,len(sys.argv)):
      if sys.argv[a][:2] == '--':
        continue
      am_file = AMFile()

      if not am_file.read(sys.argv[a]):
        continue

      if uses == 2:
        print "### " + sys.argv[a]

      if defines:
        am_file.printDefines()
      if targets:
        am_file.printTargets()
      if libadds:
        am_file.printLibraryDeps()
      if ldflags:
        am_file.printLinkerFlags()
      if libs:
        am_file.printLibraries()
      if sources:
        am_file.printSources()

      all_ams.addLibraryDeps(am_file)
      all_ams.addLinkerFlags(am_file)
      all_ams.addSources(am_file)
      all_ams.addLibraries(am_file)

    if uses == 0:
      all_ams.printLibraryDeps()
    elif uses == 1:
      a = all_ams.getReverseLibraryDeps()
      printDict(a)

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.