| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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])