LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
Classes | Functions
lsst.sconsUtils.builders Namespace Reference

Classes

class  DoxygenBuilder
 A callable to be used as an SCons Action to run Doxygen. More...
 

Functions

def SharedLibraryIncomplete
 Like SharedLibrary, but don't insist that all symbols are resolved. More...
 
def SwigLoadableModule
 Like LoadableModule, but don't insist that all symbols are resolved, and set some SWIG-specific flags. More...
 
def SourcesForSharedLibrary
 Prepare the list of files to be passed to a SharedLibrary constructor. More...
 
def filesToTag
 Return a list of files that need to be scanned for tags, starting at directory root. More...
 
def BuildETags
 Build Emacs tags (see man etags for more information). More...
 
def CleanTree
 Remove files matching the argument list starting at dir when scons is invoked with -c/–clean and no explicit targets are listed. More...
 
def ProductDir
 Return a product's PRODUCT_DIR, or None. More...
 
def Doxygen
 Generate a Doxygen config file and run Doxygen on it. More...
 
def VersionModule
 

Function Documentation

def lsst.sconsUtils.builders.BuildETags (   env,
  root = None,
  fileRegex = None,
  ignoreDirs = None 
)

Build Emacs tags (see man etags for more information).

Files are chosen if they match fileRegex; toplevel directories in list ignoreDirs are ignored This routine won't do anything unless you specified a "TAGS" target

Definition at line 153 of file builders.py.

154 def BuildETags(env, root=None, fileRegex=None, ignoreDirs=None):
155  toTag = filesToTag(root, fileRegex, ignoreDirs)
156  if toTag:
157  return env.Command("TAGS", toTag, "etags -o $TARGET $SOURCES")
158 
159 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def filesToTag
Return a list of files that need to be scanned for tags, starting at directory root.
Definition: builders.py:117
def BuildETags
Build Emacs tags (see man etags for more information).
Definition: builders.py:153
def lsst.sconsUtils.builders.CleanTree (   self,
  files,
  dir = ".",
  recurse = True,
  verbose = False 
)

Remove files matching the argument list starting at dir when scons is invoked with -c/–clean and no explicit targets are listed.

E.g. CleanTree(r"*~ core")

If recurse is True, recursively descend the file system; if verbose is True, print each filename after deleting it

Definition at line 170 of file builders.py.

171 def CleanTree(self, files, dir=".", recurse=True, verbose=False):
172  #
173  # Generate command that we may want to execute
174  #
175  files_expr = ""
176  for file in SCons.Script.Split(files):
177  if files_expr:
178  files_expr += " -o "
179 
180  files_expr += "-name %s" % re.sub(r"(^|[^\\])([[*])", r"\1\\\2",file) # quote unquoted * and []
181  #
182  # don't use xargs --- who knows what needs quoting?
183  #
184  action = "find %s" % dir
185  action += r" \( -name .svn -prune -o -name \* \) "
186  if not recurse:
187  action += " ! -name . -prune"
188 
189  file_action = "rm -f"
190 
191  action += r" \( %s \) -exec %s {} \;" % \
192  (files_expr, file_action)
193 
194  if verbose:
195  action += " -print"
196  #
197  # Clean up scons files --- users want to be able to say scons -c and get a clean copy
198  # We can't delete .sconsign.dblite if we use "scons clean" instead of "scons --clean",
199  # so the former is no longer supported.
200  #
201  action += " ; rm -rf .sconf_temp .sconsign.dblite .sconsign.tmp config.log"
202  #
203  # Do we actually want to clean up? We don't if the command is e.g. "scons -c install"
204  #
205  if "clean" in SCons.Script.COMMAND_LINE_TARGETS:
206  state.log.fail("'scons clean' is no longer supported; please use 'scons --clean'.")
207  elif not SCons.Script.COMMAND_LINE_TARGETS and self.GetOption("clean"):
208  self.Execute(self.Action([action]))
209 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def CleanTree
Remove files matching the argument list starting at dir when scons is invoked with -c/–clean and no e...
Definition: builders.py:170
def lsst.sconsUtils.builders.Doxygen (   self,
  config,
  kw 
)

Generate a Doxygen config file and run Doxygen on it.

Rather than parse a complete Doxygen config file for SCons sources and targets, this Doxygen builder builds a Doxygen config file, adding INPUT, FILE_PATTERNS, RECUSRIVE, EXCLUDE, XX_OUTPUT and GENERATE_XX options (and possibly others) to an existing proto-config file. Generated settings will override those in the proto-config file.

Parameters
configA Doxygen config file, usually with the extension .conf.in; a new file with the .in removed will be generated and passed to Doxygen. Settings in the original config file will be overridden by those generated by this method.
inputsA sequence of folders or files to be passed as the INPUT setting for Doxygen. This list will be turned into absolute paths by SCons, so the "#folder" syntax will work. Otherwise, the list is passed in as-is, but the builder will also examine those directories to find which source files the Doxygen output actually depends on.
patternsA sequence of glob patterns for the FILE_PATTERNS Doxygen setting. This will be passed directly to Doxygen, but it is also used to determine which source files should be considered dependencies.
recursiveWhether the inputs should be searched recursively (used for the Doxygen RECURSIVE setting).
outputsA sequence of output formats which will also be used as output directories.
excludeA sequence of folders or files (not globs) to be ignored by Doxygen (the Doxygen EXCLUDE setting). Hidden directories are automatically ignored.
includesA sequence of Doxygen config files to include. These will automatically be separated into paths and files to fill in the @INCLUDE_PATH and @INCLUDE settings.
useTagsA sequence of Doxygen tag files to use. It will be assumed that the html directory for each tag file is in an "html" subdirectory in the same directory as the tag file.
makeTagA string indicating the name of a tag file to be generated.
projectNameSets the Doxygen PROJECT_NAME setting.
projectNumberSets the Doxygen PROJECT_NUMBER setting.
excludeSwigIf True (default), looks for SWIG .i files in the input directories and adds Python and C++ files generated by SWIG to the list of files to exclude. For this to work, the SWIG-generated filenames must be the default ones ("module.i" generates "module.py" and "moduleLib_wrap.cc").
Note
When building documentation from a clean source tree, generated source files (like headers generated with M4) will not be included among the dependencies, because they aren't present when we walk the input folders. The workaround is just to build the docs after building the source.

Definition at line 424 of file builders.py.

425 def Doxygen(self, config, **kw):
426  inputs = [d for d in ["#doc", "#include", "#python", "#src"]
427  if os.path.exists(SCons.Script.Entry(d).abspath)]
428  defaults = {
429  "inputs": inputs,
430  "recursive": True,
431  "patterns": ["*.h", "*.cc", "*.py", "*.dox"],
432  "outputs": ["html",],
433  "excludes": [],
434  "includes": [],
435  "useTags": [],
436  "makeTag": None,
437  "projectName": None,
438  "projectNumber": None,
439  "excludeSwig": True
440  }
441  for k in defaults:
442  if kw.get(k) is None:
443  kw[k] = defaults[k]
444  builder = DoxygenBuilder(**kw)
445  return builder(self, config)
446 
@memberOf(SConsEnvironment)
def memberOf
A Python decorator that injects functions into a class.
Definition: utils.py:84
def Doxygen
Generate a Doxygen config file and run Doxygen on it.
Definition: builders.py:424
A callable to be used as an SCons Action to run Doxygen.
Definition: builders.py:237
def lsst.sconsUtils.builders.filesToTag (   root = None,
  fileRegex = None,
  ignoreDirs = None 
)

Return a list of files that need to be scanned for tags, starting at directory root.

These tags are for advanced Emacs users, and should not be confused with SVN tags or Doxygen tags.

Files are chosen if they match fileRegex; toplevel directories in list ignoreDirs are ignored This routine won't do anything unless you specified a "TAGS" target

Definition at line 117 of file builders.py.

118 def filesToTag(root=None, fileRegex=None, ignoreDirs=None):
119  if root is None: root = "."
120  if fileRegex is None: fileRegex = r"^[a-zA-Z0-9_].*\.(cc|h(pp)?|py)$"
121  if ignoreDirs is None: ignoreDirs = ["examples", "tests"]
122 
123  if len(filter(lambda t: t == "TAGS", SCons.Script.COMMAND_LINE_TARGETS)) == 0:
124  return []
125 
126  files = []
127  for dirpath, dirnames, filenames in os.walk(root):
128  if dirpath == ".":
129  dirnames[:] = [d for d in dirnames if not re.search(r"^(%s)$" % "|".join(ignoreDirs), d)]
130 
131  dirnames[:] = [d for d in dirnames if not re.search(r"^(\.svn)$", d)] # ignore .svn tree
132  #
133  # List of possible files to tag, but there's some cleanup required for machine-generated files
134  #
135  candidates = [f for f in filenames if re.search(fileRegex, f)]
136  #
137  # Remove files generated by swig
138  #
139  for swigFile in [f for f in filenames if re.search(r"\.i$", f)]:
140  name = os.path.splitext(swigFile)[0]
141  candidates = [f for f in candidates if not re.search(r"%s(_wrap\.cc?|\.py)$" % name, f)]
142 
143  files += [os.path.join(dirpath, f) for f in candidates]
144 
145  return files
def filesToTag
Return a list of files that need to be scanned for tags, starting at directory root.
Definition: builders.py:117
def lsst.sconsUtils.builders.ProductDir (   env,
  product 
)

Return a product's PRODUCT_DIR, or None.

Definition at line 212 of file builders.py.

213 def ProductDir(env, product):
214  import eupsForScons
215  global _productDirs
216  try:
217  _productDirs
218  except:
219  try:
220  _productDirs = eupsForScons.productDir(eupsenv=eupsForScons.getEups())
221  except TypeError: # old version of eups (pre r18588)
222  _productDirs = None
223  if _productDirs:
224  pdir = _productDirs.get(product)
225  else:
226  pdir = eupsForScons.productDir(product)
227  if pdir == "none":
228  pdir = None
229  return pdir
230 
231 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def ProductDir
Return a product's PRODUCT_DIR, or None.
Definition: builders.py:212
def lsst.sconsUtils.builders.SharedLibraryIncomplete (   self,
  target,
  source,
  keywords 
)

Like SharedLibrary, but don't insist that all symbols are resolved.

Definition at line 20 of file builders.py.

20 
21 def SharedLibraryIncomplete(self, target, source, **keywords):
22  myenv = self.Clone()
23  if myenv['PLATFORM'] == 'darwin':
24  myenv['SHLINKFLAGS'] += ["-undefined", "suppress", "-flat_namespace"]
25  return myenv.SharedLibrary(target, source, **keywords)
def SharedLibraryIncomplete
Like SharedLibrary, but don't insist that all symbols are resolved.
Definition: builders.py:20
def lsst.sconsUtils.builders.SourcesForSharedLibrary (   self,
  files 
)

Prepare the list of files to be passed to a SharedLibrary constructor.

In particular, ensure that any files listed in env.NoOptFiles (set by the command line option noOptFile="file1 file2") are built without optimisation and files listed in env.optFiles are built with optimisation

The usage pattern in an SConscript file is: ccFiles = env.SourcesForSharedLibrary(Glob("../src/*/*.cc")) env.SharedLibrary('afw', ccFiles, LIBS=env.getLibs("self")))

This is automatically used by scripts.BasicSConscript.lib().

Definition at line 60 of file builders.py.

60 
61 def SourcesForSharedLibrary(self, files):
62 
63  files = [SCons.Script.File(file) for file in files]
64 
65  if not (self.get("optFiles") or self.get("noOptFiles")):
66  files.sort()
67  return files
68 
69  if self.get("optFiles"):
70  optFiles = self["optFiles"].replace(".", r"\.") # it'll be used in an RE
71  optFiles = SCons.Script.Split(optFiles.replace(",", " "))
72  optFilesRe = "/(%s)$" % "|".join(optFiles)
73  else:
74  optFilesRe = None
75 
76  if self.get("noOptFiles"):
77  noOptFiles = self["noOptFiles"].replace(".", r"\.") # it'll be used in an RE
78  noOptFiles = SCons.Script.Split(noOptFiles.replace(",", " "))
79  noOptFilesRe = "/(%s)$" % "|".join(noOptFiles)
80  else:
81  noOptFilesRe = None
82 
83  if self.get("opt"):
84  opt = int(self["opt"])
85  else:
86  opt = 0
87 
88  if opt == 0:
89  opt = 3
90 
91  CCFLAGS_OPT = re.sub(r"-O(\d|s)\s*", "-O%d " % opt, " ".join(self["CCFLAGS"]))
92  CCFLAGS_NOOPT = re.sub(r"-O(\d|s)\s*", "-O0 ", " ".join(self["CCFLAGS"])) # remove -O flags from CCFLAGS
93 
94  sources = []
95  for ccFile in files:
96  if optFilesRe and re.search(optFilesRe, ccFile.abspath):
97  self.SharedObject(ccFile, CCFLAGS=CCFLAGS_OPT)
98  ccFile = os.path.splitext(ccFile.abspath)[0] + self["SHOBJSUFFIX"]
99  elif noOptFilesRe and re.search(noOptFilesRe, ccFile.abspath):
100  self.SharedObject(ccFile, CCFLAGS=CCFLAGS_NOOPT)
101  ccFile = os.path.splitext(ccFile.abspath)[0] + self["SHOBJSUFFIX"]
102 
103  sources.append(ccFile)
104 
105  sources.sort()
106  return sources
107 
108 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def SourcesForSharedLibrary
Prepare the list of files to be passed to a SharedLibrary constructor.
Definition: builders.py:60
def lsst.sconsUtils.builders.SwigLoadableModule (   self,
  target,
  source,
  keywords 
)

Like LoadableModule, but don't insist that all symbols are resolved, and set some SWIG-specific flags.

Definition at line 29 of file builders.py.

29 
30 def SwigLoadableModule(self, target, source, **keywords):
31  myenv = self.Clone()
32  if myenv['PLATFORM'] == 'darwin':
33  myenv.Append(LDMODULEFLAGS = ["-undefined", "suppress", "-flat_namespace",])
34  #
35  # Swig-generated .cc files cast pointers to long longs and back,
36  # which is illegal. This flag tells g++ about the sin
37  #
38  try:
39  if myenv.whichCc == "gcc":
40  myenv.Append(CCFLAGS = ["-fno-strict-aliasing",])
41  except AttributeError:
42  pass
43  return myenv.LoadableModule(target, source, **keywords)
44 
45 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def SwigLoadableModule
Like LoadableModule, but don't insist that all symbols are resolved, and set some SWIG-specific flags...
Definition: builders.py:29
def lsst.sconsUtils.builders.VersionModule (   self,
  filename,
  versionString = None 
)

Definition at line 447 of file builders.py.

448 def VersionModule(self, filename, versionString=None):
449  if versionString is None:
450  for n in ("git", "hg", "svn",):
451  if os.path.isdir(".%s" % n):
452  versionString = n
453 
454  if not versionString:
455  versionString = "git"
456 
457  def calcMd5(filename):
458  try:
459  import hashlib
460  md5 = hashlib.md5("\n".join(open(filename).readlines())).hexdigest()
461  except IOError:
462  md5 = None
463 
464  return md5
465 
466  oldMd5 = calcMd5(filename)
467 
468  def makeVersionModule(target, source, env):
469  try:
470  version = determineVersion(state.env, versionString)
471  except RuntimeError:
472  version = "unknown"
473  parts = version.split("+")
474 
475  names = []
476  with open(target[0].abspath, "w") as outFile:
477  outFile.write("#--------- This file is automatically generated by LSST's sconsUtils ---------#\n")
478 
479  what = "__version__"
480  outFile.write("%s = '%s'\n" % (what, version))
481  names.append(what)
482 
483  what = "__repo_version__"
484  outFile.write("%s = '%s'\n" % (what, parts[0]))
485  names.append(what)
486 
487  what = "__repo_version__"
488  outFile.write("%s = '%s'\n" % (what, parts[0]))
489  names.append(what)
490 
491  what = "__fingerprint__"
492  outFile.write("%s = '%s'\n" % (what, getFingerprint(versionString)))
493  names.append(what)
494 
495  try:
496  info = tuple(int(v) for v in parts[0].split("."))
497  what = "__version_info__"
498  names.append(what)
499  outFile.write("%s = %r\n" % (what, info))
500  except ValueError:
501  pass
502 
503  if len(parts) > 1:
504  try:
505  what = "__rebuild_version__"
506  outFile.write("%s = %s\n" % (what, int(parts[1])))
507  names.append(what)
508  except ValueError:
509  pass
510 
511  what = "__dependency_versions__"
512  names.append(what)
513  outFile.write("%s = {\n" % (what))
514  for name, mod in env.dependencies.packages.iteritems():
515  if mod is None:
516  outFile.write(" '%s': None,\n" % name)
517  elif hasattr(mod.config, "version"):
518  outFile.write(" '%s': '%s',\n" % (name, mod.config.version))
519  else:
520  outFile.write(" '%s': 'unknown',\n" % name)
521  outFile.write("}\n")
522 
523  outFile.write("__all__ = %r\n" % (tuple(names),))
524 
525  if calcMd5(target[0].abspath) != oldMd5: # only print if something's changed
526  print "makeVersionModule([\"%s\"], [])" % str(target[0])
527 
528  result = self.Command(filename, [], self.Action(makeVersionModule, strfunction=lambda *args: None))
529 
530  self.AlwaysBuild(result)
531  return result
def getFingerprint
Return a unique fingerprint for a version (e.g.
Definition: installation.py:73
def determineVersion
Set a version ID from env, or a version control ID string ($name$ or $HeadURL$)
Definition: installation.py:46