Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
make_heptools.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 """
3 Small tool to generate the heptools toolchain from a given LCGCMT.
4 """
5 __author__ = "Marco Clemencic <marco.clemencic@cern.ch>"
6 
7 import os
8 import re
9 
10 class HepToolsGenerator(object):
11  """
12  Class wrapping the details needed to generate the toolchain file from LCGCMT.
13  """
14  __header__ = """cmake_minimum_required(VERSION 2.8.5)
15 
16 # Declare the version of HEP Tools we use
17 # (must be done before including heptools-common to allow evolution of the
18 # structure)
19 set(heptools_version %s)
20 
21 include(${CMAKE_CURRENT_LIST_DIR}/heptools-common.cmake)
22 
23 # please keep alphabetic order and the structure (tabbing).
24 # it makes it much easier to edit/read this file!
25 """
26  __trailer__ = """
27 # Prepare the search paths according to the versions above
28 LCG_prepare_paths()"""
29 
30  __AA_projects__ = ("COOL", "CORAL", "RELAX", "ROOT")
31 
32  __special_dirs__ = {"CLHEP": "clhep",
33  "fftw": "fftw3",
34  "Frontier_Client": "frontier_client",
35  "GCCXML": "gccxml",
36  "Qt": "qt",
37  "CASTOR": "castor",
38  "TBB": "tbb",
39  "cgsigsoap": "Grid/cgsi-gsoap",
40  "epel": "Grid/epel",
41  "gfal": "Grid/gfal",
42  "globus": "Grid/globus",
43  "gridftp_ifce": "Grid/gridftp-ifce",
44  "is_ifce": "Grid/is-ifce",
45  "lcgdmcommon": "Grid/lcg-dm-common",
46  "lfc": "Grid/LFC",
47  "srm_ifce": "Grid/srm-ifce",
48  "vomsapic": "Grid/voms-api-c",
49  "voms": "Grid/voms",
50  }
51 
52  __special_names__ = {"qt": "Qt"}
53 
54  def __init__(self, lcgcmt_root):
55  """
56  Prepare the instance.
57 
58  @param lcgcmt_root: path to the root directory of a given LCGCMT version
59  """
60  self.lcgcmt_root = lcgcmt_root
61 
62  def __repr__(self):
63  """
64  Representation of the instance.
65  """
66  return "HepToolsGenerator(%r)" % self.lcgcmt_root
67 
68  @property
69  def versions(self):
70  """
71  Extract the external names and versions from an installed LCGCMT.
72 
73  @return: dictionary mapping external names to versions
74  """
75  from itertools import imap
76  def statements(lines):
77  """
78  Generator of CMT statements from a list of lines.
79  """
80  statement = "" # we start with an empty statement
81  for l in imap(lambda l: l.rstrip(), lines): # CMT ignores spaces at the end of line when checking for '\'
82  # append the current line to the statement so far
83  statement += l
84  if statement.endswith("\\"):
85  # in this case we need to strip the '\' and continue the concatenation
86  statement = statement[:-1]
87  else:
88  # we can stop concatenating, but we return only non-trivial statements
89  statement = statement.strip()
90  if statement:
91  yield statement
92  statement = "" # we start collecting a new statement
93 
94  def tokens(statement):
95  """
96  Split a statement in tokens.
97 
98  Trivial implementation assuming the tokens do not contain spaces.
99  """
100  return statement.split()
101 
102  def macro(args):
103  """
104  Analyze the arguments of a macro command.
105 
106  @return: tuple (name, value, exceptionsDict)
107  """
108  unquote = lambda s: s.strip('"')
109  name = args[0]
110  value = unquote(args[1])
111  # make a dictionary of the even to odd remaining args (unquoting the values)
112  exceptions = dict(zip(args[2::2],
113  map(unquote, args[3::2])))
114  return name, value, exceptions
115 
116  # prepare the dictionary for the results
117  versions = {}
118  # We extract the statements from the requirements file of the LCG_Configuration package
119  req = open(os.path.join(self.lcgcmt_root, "LCG_Configuration", "cmt", "requirements"))
120  for toks in imap(tokens, statements(req)):
121  if toks.pop(0) == "macro": # get only the macros ...
122  name, value, exceptions = macro(toks)
123  if name.endswith("_config_version"): # that end with _config_version
124  name = name[:-len("_config_version")]
125  name = self.__special_names__.get(name, name)
126  for tag in ["target-slc"]: # we use the alternative for 'target-slc' if present
127  value = exceptions.get(tag, value)
128  versions[name] = value.replace('(', '{').replace(')', '}')
129  return versions
130 
131  def _content(self):
132  """
133  Generator producing the content (in blocks) of the toolchain file.
134  """
135  versions = self.versions
136 
137  yield self.__header__ % versions.pop("LCG")
138 
139  yield "\n# Application Area Projects"
140  for name in self.__AA_projects__:
141  # the width of the first string is bound to the length of the names
142  # in self.__AA_projects__
143  yield "LCG_AA_project(%-5s %s)" % (name, versions.pop(name))
144 
145  yield "\n# Compilers"
146  # @FIXME: to be made cleaner and more flexible
147  for compiler in [("gcc43", "gcc", "4.3.5"),
148  ("gcc46", "gcc", "4.6.2"),
149  ("gcc47", "gcc", "4.7.2"),
150  ("clang30", "clang", "3.0"),
151  ("gccmax", "gcc", "4.7.2")]:
152  yield "LCG_compiler(%s %s %s)" % compiler
153 
154  yield "\n# Externals"
155  lengths = (max(map(len, versions.keys())),
156  max(map(len, versions.values())),
157  max(map(len, self.__special_dirs__.values()))
158  )
159  template = "LCG_external_package(%%-%ds %%-%ds %%-%ds)" % lengths
160 
161  def packageSorting(pkg):
162  "special package sorting keys"
163  key = pkg.lower()
164  if key == "javajni":
165  key = "javasdk_javajni"
166  return key
167  for name in sorted(versions.keys(), key=packageSorting):
168  # special case
169  if name == "uuid":
170  yield "if(NOT ${LCG_OS}${LCG_OS_VERS} STREQUAL slc6) # uuid is not distributed with SLC6"
171  # LCG_external_package(CLHEP 1.9.4.7 clhep)
172  yield template % (name, versions[name], self.__special_dirs__.get(name, ""))
173  if name == "uuid":
174  yield "endif()"
175 
176  yield self.__trailer__
177 
178  def __str__(self):
179  """
180  Return the content of the toolchain file.
181  """
182  return "\n".join(self._content())
183 
184 if __name__ == '__main__':
185  import sys
186  if len(sys.argv) != 2 or not os.path.exists(sys.argv[1]):
187  print "Usage : %s <path to LCGCMT version>" % os.path.basename(sys.argv[0])
188  sys.exit(1)
189  print HepToolsGenerator(sys.argv[1])

Generated at Wed Dec 4 2013 14:33:06 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004