All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sbndcode/sbndcode/gallery/python/cppUtils.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 
4 __doc__ = """
5 Collection of utilities to interface C++ code with Python via PyROOT.
6 
7 This module requires ROOT.
8 """
9 
10 __all__ = [
11  'readHeader',
12  'SourceCode',
13  ]
14 
15 import sys, os
16 from ROOTutils import ROOT
17 
18 
19 ################################################################################
20 def readHeader(headerPath):
21  """Make the ROOT C++ jit compiler read the specified header."""
22  ROOT.gROOT.ProcessLine('#include "%s"' % headerPath)
23 # readHeader()
24 
25 
26 ################################################################################
27 class SourceCentral:
28  """
29  A class keeping track of the sources and where to look for them.
30  """
31  AllPlatformInfo = {
32  'Linux': {
33  'Name': 'Linux',
34  'LibSuffix': '.so',
35  'LibEnvPath': 'LD_LIBRARY_PATH',
36  },
37  'Darwin': {
38  'Name': 'Darwin',
39  'LibSuffix': '.dylib',
40  'LibEnvPath': 'DYLD_LIBRARY_PATH', # might be not honoured
41  },
42  } # AllPlatformInfo
43  PlatformInfo = AllPlatformInfo[os.uname()[0]]
44 
45  def __init__(self, *includePaths):
46  self.headers = {}
47  self.libraries = {}
48  self.includePaths = []
49  self.addIncPaths(*includePaths)
50  # for
51  # __init__()
52 
53  def addIncPath(self, path, force=False):
54  expPath = os.path.expandvars(path)
55  if not os.path.isdir(expPath):
56  print >>sys.stderr, "Warning: include path '%s'" % path,
57  if path != expPath: print >>sys.stderr, " ( => '%s')" % expPath
58  print >>sys.stderr, " does not exist."
59  if force or expPath not in self.includePaths:
60  self.includePaths.append(expPath)
61  # addIncPath()
62 
63  def addIncPathEnv(self, varName, force = False):
64  self.addIncPath(os.environ[varName], force=force)
65 
66  def addIncPaths(self, *paths):
67  for path in paths: self.addIncPath(path)
68 
69  def addIncPathEnvs(self, *varNames):
70  self.addIncPaths(*map((lambda varName: os.environ[varName]), varNames))
71 
72  def find(self, relPath, extraPaths = []):
73  return self.findLibrary(relPath, extraPaths=extraPaths) if self.isLibrary(relPath) else self.findHeader(relPath, extraPaths=extraPaths)
74  # find()
75 
76  def findLibrary(self, libName, extraPaths = []):
77  expLibName = SourceCentral.expandLibraryName(libName)
78  for path in reversed(
79  SourceCentral.LibraryPaths() + map(os.path.expandvars, extraPaths)
80  ):
81  candidate = os.path.join(path, expLibName)
82  if os.path.exists(candidate): return candidate
83  else: return None
84  # findLibrary()
85 
86  def findHeader(self, relPath, extraPaths = []):
87  for path in reversed(self.includePaths + list(map(os.path.expandvars, extraPaths))):
88  candidate = os.path.join(path, relPath)
89  if os.path.exists(candidate): return candidate
90  else: return None
91  # findHeader()
92 
93  def loadLibrary(self, relPath, extraPaths = [], force = False):
94  expandedName = self.expandLibraryName(relPath)
95  res = ROOT.gSystem.Load(expandedName)
96  if res == 0: self.libraries[relPath] = expandedName
97  return res
98  # loadLibrary()
99 
100  def loadHeader(self, headerRelPath, extraPaths = [], force = False):
101  try: return self.headers[headerRelPath]
102  except KeyError: pass
103  headerPath = self.findHeader(headerRelPath, extraPaths=extraPaths)
104  if not headerPath: raise RuntimeError("Can't locate header file '%s'" % headerRelPath)
105  readHeader(headerPath)
106  self.headers[headerRelPath] = headerPath
107  return headerPath
108  # loadHeader()
109 
110 
111  def loadHeaderFromUPS(self, headerRelPath, extraPaths = [], force = False):
112  """
113  Loads a C++ header from a UPS product.
114 
115  Assumptions:
116  * the specified relative path of the header is under the include directory
117  of its UPS product
118  * the include directory path is set in a environment variable named with
119  the standard UPS pattern (`PRODUCTNAME_INC`)
120  * the header relative path starts with a directory that reflects the name
121  of the UPS product, `productname/relative/package/path/header.h`
122 
123  For example, for a `headerRelPath` of `larcorealg/Geometry/GeometryCore.h`,
124  the full path must be represented by
125  `${LARCOREALG_INC}/larcorealg/Geometry/GeometryCore.h`, with the content
126  of `LARCOREALG_INC` variable being an absolute path.
127  """
128  # make sure that if there is a INC variable for the package, that one is included
129  return self.loadHeader(
130  headerRelPath,
131  extraPaths
132  =([ '$' + self.packageVarNameFromHeaderPath('INC', headerRelPath) ] + extraPaths),
133  force=force
134  )
135  # loadHeaderFromUPS()
136 
137  def load(self, relPath, extraPaths = [], force = False):
138  return (self.loadLibrary if self.isLibrary(relPath) else self.loadHeader)(relPath, extraPaths=extraPaths, force=force)
139  # load()
140 
141  def isLibrary(self, path):
142  return os.path.splitext(path)[-1] in [ self.PlatformInfo['LibSuffix'], '' ]
143 
144  def expandLibraryName(self, name):
145  if not name.startswith('lib'): name = 'lib' + name
146  LibSuffix = self.PlatformInfo['LibSuffix']
147  if not name.endswith(LibSuffix): name += LibSuffix
148  return name
149  # expandLibraryName()
150 
151  @staticmethod
152  def packageNameFromHeaderPath(headerPath):
153  return os.path.split(os.path.dirname(headerPath))[0]
154 
155  @staticmethod
156  def packageVarNameFromHeaderPath(varSuffix, headerPath):
157  return SourceCentral.packageNameFromHeaderPath(headerPath).upper() + '_' + varSuffix
158 
159  @staticmethod
161  return os.getenv(SourceCentral.PlatformInfo['LibEnvPath']) \
162  .split(SourceCentral.PlatformInfo.get('LibEnvPathSep', ':'))
163  # LibraryPaths()
164 
165 # class SourceCentral
166 
167 ################################################################################
168 
169 # global instance of source tracking class
170 SourceCode = SourceCentral()
171 
172 ################################################################################
list
Definition: file_to_url.sh:28