|
Gaudi Framework, version v23r4 |
| Home | Generated: Mon Sep 17 2012 |

Public Member Functions | |
| def | __init__ |
| def | generate |
| def | process |
Public Attributes | |
| path | |
| name | |
| requirements | |
| project | |
| uses | |
| version | |
| libraries | |
| applications | |
| documents | |
| macros | |
| singleton_patterns | |
| install_more_includes | |
| install_python_modules | |
| install_scripts | |
| QMTest | |
| god_headers | |
| god_dictionary | |
| PyQtResource | |
| PyQtUIC | |
| multi_patterns | |
| reflex_dictionary | |
| component_library | |
| linker_library | |
| reflex_dictionaries | |
| component_libraries | |
| linker_libraries | |
| log | |
Private Member Functions | |
| def | _parseRequirements |
Definition at line 116 of file cmt2cmake.py.
| def cmt2cmake::Package::__init__ | ( | self, | |
| path, | |||
project = None |
|||
| ) |
Definition at line 117 of file cmt2cmake.py.
00118 : 00119 self.path = os.path.realpath(path) 00120 if not isPackage(self.path): 00121 raise ValueError("%s is not a package" % self.path) 00122 00123 self.name = os.path.basename(self.path) 00124 self.requirements = os.path.join(self.path, "cmt", "requirements") 00125 self.project = project 00126 00127 # prepare attributes filled during parsing of requirements 00128 self.uses = {} 00129 self.version = None 00130 self.libraries = [] 00131 self.applications = [] 00132 self.documents = [] 00133 self.macros = {} 00134 00135 self.singleton_patterns = set(["QMTest", "install_python_modules", "install_scripts", 00136 "install_more_includes", "god_headers", "god_dictionary", 00137 "PyQtResource", "PyQtUIC"]) 00138 self.install_more_includes = {} 00139 self.install_python_modules = self.install_scripts = self.QMTest = False 00140 self.god_headers = {} 00141 self.god_dictionary = {} 00142 self.PyQtResource = {} 00143 self.PyQtUIC = {} 00144 00145 self.multi_patterns = set(["reflex_dictionary", 'component_library', 'linker_library']) 00146 self.reflex_dictionary = [] 00147 self.component_library = [] 00148 self.linker_library = [] 00149 00150 self.reflex_dictionaries = {} 00151 self.component_libraries = set() 00152 self.linker_libraries = set() 00153 00154 self.log = logging.getLogger('Package(%s)' % self.name) 00155 try: 00156 self._parseRequirements() 00157 except: 00158 print "Processing %s" % self.requirements 00159 raise 00160 # update the known subdirs 00161 known_subdirs[self.name] = {# list of linker libraries provided by the package 00162 'libraries': list(self.linker_libraries), 00163 # true if it's a headers-only package 00164 'includes': bool(self.install_more_includes and 00165 not self.linker_libraries)}
| def cmt2cmake::Package::_parseRequirements | ( | self ) | [private] |
Definition at line 442 of file cmt2cmake.py.
00443 : 00444 def requirements(): 00445 statement = "" 00446 for l in open(self.requirements): 00447 if '#' in l: 00448 l = l[:l.find('#')] 00449 l = l.strip() 00450 if l: 00451 statement += l 00452 if statement.endswith('\\'): 00453 statement = statement[:-1] + ' ' 00454 continue 00455 else: 00456 try: 00457 yield list(CMTParser.parseString(statement)) 00458 except: 00459 # ignore not know statements 00460 self.log.debug("Failed to parse statement: %r", statement) 00461 statement = "" 00462 00463 for args in requirements(): 00464 cmd = args.pop(0) 00465 if cmd == 'version': 00466 self.version = args[0] 00467 elif cmd == "use": 00468 if "-no_auto_imports" in args: 00469 imp = False 00470 args.remove("-no_auto_imports") 00471 else: 00472 imp = True 00473 if len(args) > 1: # only one argument means usually a conditional use 00474 if len(args) > 2: 00475 name = "%s/%s" % (args[2], args[0]) 00476 else: 00477 name = args[0] 00478 self.uses[name] = (args[1], imp) 00479 00480 elif cmd == "apply_pattern": 00481 pattern = args.pop(0) 00482 args = dict([x.split('=', 1) for x in args]) 00483 if pattern in self.singleton_patterns: 00484 setattr(self, pattern, args or True) 00485 elif pattern in self.multi_patterns: 00486 getattr(self, pattern).append(args) 00487 00488 elif cmd == 'library': 00489 name = args.pop(0) 00490 # digest arguments (options, variables, sources) 00491 imports = [] 00492 group = None 00493 sources = [] 00494 for a in args: 00495 if a.startswith('-'): # options 00496 if a.startswith('-import='): 00497 imports.append(a[8:]) 00498 elif a.startswith('-group='): 00499 group = a[7:] 00500 elif '=' in a: # variable 00501 pass 00502 else: # source 00503 sources.append(a) 00504 self.libraries.append((name, sources, group, imports)) 00505 00506 elif cmd == 'application': 00507 name = args.pop(0) 00508 # digest arguments (options, variables, sources) 00509 imports = [] 00510 group = None 00511 sources = [] 00512 for a in args: 00513 if a.startswith('-'): # options 00514 if a.startswith('-import='): 00515 imports.append(a[8:]) 00516 elif a.startswith('-group='): 00517 group = a[7:] 00518 elif a == '-check': # used for test applications 00519 group = 'tests' 00520 elif '=' in a: # variable 00521 pass 00522 else: # source 00523 sources.append(a) 00524 if 'test' in name.lower() or [s for s in sources if 'test' in s.lower()]: 00525 # usually, developers do not put tests in the right group 00526 group = 'tests' 00527 self.applications.append((name, sources, group, imports)) 00528 00529 elif cmd == 'document': 00530 name = args.pop(0) 00531 constituent = args.pop(0) 00532 sources = args 00533 self.documents.append((name, constituent, sources)) 00534 00535 elif cmd == 'macro': 00536 # FIXME: should handle macro tags 00537 name = args.pop(0) 00538 value = args[0].strip('"').strip("'") 00539 self.macros[name] = value 00540 00541 elif cmd == 'macro_append': 00542 # FIXME: should handle macro tags 00543 name = args.pop(0) 00544 value = args[0].strip('"').strip("'") 00545 self.macros[name] = self.macros.get(name, "") + value 00546 00547 00548 # classification of libraries in the package 00549 unquote = lambda x: x.strip('"').strip("'") 00550 self.component_libraries = set([unquote(l['library']) for l in self.component_library]) 00551 self.linker_libraries = set([unquote(l['library']) for l in self.linker_library]) 00552 self.reflex_dictionaries = dict([(unquote(l['dictionary']), l.get('options', '')) 00553 for l in self.reflex_dictionary])
| def cmt2cmake::Package::generate | ( | self ) |
Definition at line 166 of file cmt2cmake.py.
00167 : 00168 # header 00169 data = ["#" * 80, 00170 "# Package: %s" % self.name, 00171 "#" * 80, 00172 "gaudi_subdir(%s %s)" % (self.name, self.version), 00173 ""] 00174 # dependencies 00175 # subdirectories (excluding specials) 00176 subdirs = [n for n in sorted(self.uses) 00177 if not n.startswith("LCG_Interfaces/") 00178 and n not in ignore_dep_on_subdirs] 00179 00180 inc_dirs = [] 00181 if subdirs: 00182 # check if we are missing info for a subdir 00183 missing_subdirs = set([s.rsplit('/')[-1] for s in subdirs]) - set(known_subdirs) 00184 if missing_subdirs: 00185 self.log.warning('Missing info cache for subdirs %s', ' '.join(sorted(missing_subdirs))) 00186 # declare inclusion order 00187 data.append(callStringWithIndent('gaudi_depends_on_subdirs', subdirs)) 00188 data.append('') 00189 # consider header-only subdirs 00190 # for each required subdir that comes with only headers, add its 00191 # location to the call to 'include_directories' 00192 inc_only = lambda s: known_subdirs.get(s.rsplit('/')[-1], {}).get('includes') 00193 inc_dirs = filter(inc_only, subdirs) 00194 00195 00196 # externals (excluding specials) 00197 # - Python needs to be treated in a special way 00198 find_packages = {} 00199 for n in sorted(self.uses): 00200 if n.startswith("LCG_Interfaces/"): 00201 n = extName(n[15:]) 00202 # FIXME: find a general way to treat these special cases 00203 if n == "PythonLibs": 00204 if self.name not in needing_python: # only these packages actually link against Python 00205 continue 00206 # get custom link options 00207 linkopts = self.macros.get(n + '_linkopts', '') 00208 components = [m.group(1) or m.group(2) 00209 for m in re.finditer(r'(?:\$\(%s_linkopts_([^)]*)\))|(?:-l(\w*))' % n, 00210 linkopts)] 00211 # FIXME: find a general way to treat the special cases 00212 if n == 'COOL': 00213 components = ['CoolKernel', 'CoolApplication'] 00214 elif n == 'CORAL': 00215 components = ['CoralBase', 'CoralKernel', 'RelationalAccess'] 00216 00217 find_packages[n] = find_packages.get(n, []) + components 00218 00219 # this second loops avoid double entries do to converging results of extName() 00220 for n in sorted(find_packages): 00221 args = [n] 00222 components = find_packages[n] 00223 if components: 00224 args.append('COMPONENTS') 00225 args.extend(components) 00226 data.append('find_package(%s)' % ' '.join(args)) 00227 if find_packages: 00228 data.append("") 00229 00230 if self.name in no_pedantic: 00231 data.append('string(REPLACE "-pedantic" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")\n') 00232 00233 # the headers can be installed via "PUBLIC_HEADERS" or by hand 00234 if self.install_more_includes: 00235 headers = [d for d in self.install_more_includes.values() 00236 if os.path.isdir(os.path.join(self.path, d))] 00237 else: 00238 headers = [] 00239 00240 if self.god_headers or self.god_dictionary: 00241 data.append("include(GaudiObjDesc)") 00242 data.append("") 00243 00244 god_headers_dest = None 00245 if self.god_headers: 00246 godargs = [self.god_headers["files"].replace("../", "")] 00247 00248 godflags = self.macros.get('%sObj2Doth_GODflags' % self.name, "") 00249 godflags = re.search(r'-s\s*(\S+)', godflags) 00250 if godflags: 00251 god_headers_dest = os.path.normpath('Event/' + godflags.group(1)) 00252 godargs.append('DESTINATION ' + god_headers_dest) 00253 00254 data.append(callStringWithIndent('god_build_headers', godargs)) 00255 data.append("") 00256 00257 god_dict = [] 00258 if self.god_dictionary: 00259 god_dict = [('--GOD--', 00260 [self.god_dictionary["files"].replace("../", "")], 00261 None, [])] 00262 00263 rflx_dict = [] 00264 for d in self.reflex_dictionary: 00265 for k in d: 00266 v = d[k] 00267 v = v.replace("$(%sROOT)/" % self.name.upper(), "") 00268 v = v.replace("../", "") 00269 d[k] = v 00270 imports = [i.strip('"').replace('-import=', '') for i in d.get('imports', '').strip().split()] 00271 rflx_dict.append((d['dictionary'] + 'Dict', 00272 [d['headerfiles'], d['selectionfile']], 00273 None, 00274 imports)) 00275 00276 # libraries 00277 global_imports = [extName(name[15:]) 00278 for name in self.uses 00279 if name.startswith('LCG_Interfaces/') and self.uses[name][1]] # list of imported ext 00280 if 'PythonLibs' in global_imports and self.name not in needing_python: 00281 global_imports.remove('PythonLibs') 00282 00283 subdir_imports = [s.rsplit('/')[-1] for s in subdirs if self.uses[s][1]] 00284 local_links = [] # keep track of linker libraries found so far 00285 applications_names = set([a[0] for a in self.applications]) 00286 # Note: a god_dictionary, a reflex_dictionary or an application is like a module 00287 for name, sources, group, imports in self.libraries + god_dict + rflx_dict + self.applications: 00288 isGODDict = isRflxDict = isComp = isApp = isLinker = False 00289 if name == '--GOD--': 00290 isGODDict = True 00291 name = '' # no library name for GOD dictionaries 00292 elif name.endswith('Dict') and name[:-4] in self.reflex_dictionaries: 00293 isRflxDict = True 00294 name = name[:-4] 00295 elif name in self.component_libraries: 00296 isComp = True 00297 elif name in applications_names: 00298 isApp = True 00299 else: 00300 if name not in self.linker_libraries: 00301 self.log.warning('library %s not declared as component or linker, assume linker', name) 00302 isLinker = True 00303 00304 # prepare the bits of the command: cmd, name, sources, args 00305 if isComp: 00306 cmd = 'gaudi_add_module' 00307 elif isGODDict: 00308 cmd = 'god_build_dictionary' 00309 elif isRflxDict: 00310 cmd = 'gaudi_add_dictionary' 00311 elif isApp: 00312 cmd = 'gaudi_add_executable' 00313 else: # i.e. isLinker (a fallback) 00314 cmd = 'gaudi_add_library' 00315 00316 if not sources: 00317 self.log.warning("Missing sources for target %s", name) 00318 00319 args = [] 00320 if isLinker: 00321 if headers: 00322 args.append('PUBLIC_HEADERS ' + ' '.join(headers)) 00323 else: 00324 args.append('NO_PUBLIC_HEADERS') 00325 elif isGODDict: 00326 if god_headers_dest: 00327 args.append('HEADERS_DESTINATION ' + god_headers_dest) 00328 # check if we have a customdict in the documents 00329 for docname, _, docsources in self.documents: 00330 if docname == 'customdict': 00331 args.append('EXTEND ' + docsources[0].replace('../', '')) 00332 break 00333 00334 00335 # # collection of link libraries. # 00336 # Externals and subdirs are treated differently: 00337 # - externals: just use the package name 00338 # - subdirs: find the exported libraries in the global var known_subdirs 00339 # We also have to add the local linker libraries. 00340 00341 # separate external and subdir explicit imports 00342 subdirsnames = [s.rsplit('/')[-1] for s in subdirs] 00343 subdir_local_imports = [i for i in imports if i in subdirsnames] 00344 ext_local_imports = [extName(i) for i in imports if i not in subdir_local_imports] 00345 00346 # prepare the link list with the externals 00347 links = global_imports + ext_local_imports 00348 if links or inc_dirs: 00349 # external links need the include dirs 00350 args.append('INCLUDE_DIRS ' + ' '.join(links + inc_dirs)) 00351 # add subdirs... 00352 for s in subdir_imports + subdir_local_imports: 00353 if s in known_subdirs: 00354 links.extend(known_subdirs[s]['libraries']) 00355 # ... and local libraries 00356 links.extend(local_links) 00357 if 'AIDA' in links: 00358 links.remove('AIDA') # FIXME: AIDA does not have a library 00359 00360 if links: 00361 not_included = set(links).difference(find_packages, set([s.rsplit('/')[-1] for s in subdirs])) 00362 if not_included: 00363 self.log.warning('imports without use: %s', ', '.join(sorted(not_included))) 00364 # note: in some cases we get quoted library names 00365 args.append('LINK_LIBRARIES ' + ' '.join([l.strip('"') for l in links])) 00366 00367 if isRflxDict and self.reflex_dictionaries[name]: 00368 args.append('OPTIONS ' + self.reflex_dictionaries[name]) 00369 00370 if isLinker: 00371 local_links.append(name) 00372 00373 # FIXME: very very special case :( 00374 if name == 'garbage' and self.name == 'FileStager': 00375 data.append('# only for the applications\nfind_package(Boost COMPONENTS program_options)\n') 00376 00377 # write command 00378 sources = [s.replace('../src/', '') for s in sources] 00379 # FIXME: special case 00380 sources = [s.replace('$(GAUDICONFROOT)', '${CMAKE_SOURCE_DIR}/GaudiConf') for s in sources] 00381 libdata = callStringWithIndent(cmd, [name] + sources + args) 00382 00383 # FIXME: wrap the test libraries in one if block (instead of several) 00384 if group in ('tests', 'test'): 00385 # increase indentation 00386 libdata = [' ' + l for l in libdata.splitlines()] 00387 # and wrap 00388 libdata.insert(0, 'if(BUILD_TESTS)') 00389 libdata.append('endif()') 00390 libdata = '\n'.join(libdata) 00391 data.append(libdata) 00392 data.append('') # empty line 00393 00394 # PyQt resources and UIs 00395 if self.PyQtResource or self.PyQtUIC: 00396 data.append("# gen_pyqt_* functions are provided by 'pygraphics'") 00397 if self.PyQtResource: 00398 qrc_files = self.PyQtResource["qrc_files"].replace("../", "") 00399 qrc_dest = self.PyQtResource["outputdir"].replace("../python/", "") 00400 qrc_target = qrc_dest.replace('/', '.') + '.Resources' 00401 data.append('gen_pyqt_resource(%s %s %s)' % (qrc_target, qrc_dest, qrc_files)) 00402 if self.PyQtUIC: 00403 ui_files = self.PyQtUIC["ui_files"].replace("../", "") 00404 ui_dest = self.PyQtUIC["outputdir"].replace("../python/", "") 00405 ui_target = qrc_dest.replace('/', '.') + '.UI' 00406 data.append('gen_pyqt_uic(%s %s %s)' % (ui_target, ui_dest, ui_files)) 00407 if self.PyQtResource or self.PyQtUIC: 00408 data.append('') # empty line 00409 00410 # installation 00411 installs = [] 00412 if headers and not self.linker_libraries: # not installed yet 00413 installs.append("gaudi_install_headers(%s)" % (" ".join(headers))) 00414 if self.install_python_modules: 00415 # if we install Python modules, we need to check if we have special 00416 # names for the ConfUser modules 00417 if (self.name + 'ConfUserModules') in self.macros: 00418 installs.append('set_property(DIRECTORY PROPERTY CONFIGURABLE_USER_MODULES %s)' 00419 % self.macros[self.name + 'ConfUserModules']) 00420 installs.append("gaudi_install_python_modules()") 00421 if self.install_scripts: 00422 installs.append("gaudi_install_scripts()") 00423 if installs: 00424 data.extend(installs) 00425 data.append('') # empty line 00426 # tests 00427 if self.QMTest: 00428 data.append("\ngaudi_add_test(QMTest QMTEST)") 00429 00430 return "\n".join(data) + "\n"
| def cmt2cmake::Package::process | ( | self, | |
force = False |
|||
| ) |
Definition at line 431 of file cmt2cmake.py.
00432 : 00433 # @FIXME: do something for the package 00434 cml = os.path.join(self.path, "CMakeLists.txt") 00435 if not force and os.path.exists(cml): 00436 self.log.warning("file %s already exists", cml) 00437 return 00438 data = self.generate() 00439 f = open(cml, "w") 00440 f.write(data) 00441 f.close()
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.
Definition at line 117 of file cmt2cmake.py.