LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
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 154 of file builders.py.

155 def BuildETags(env, root=None, fileRegex=None, ignoreDirs=None):
156  toTag = filesToTag(root, fileRegex, ignoreDirs)
157  if toTag:
158  return env.Command("TAGS", toTag, "etags -o $TARGET $SOURCES")
159 
160 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def filesToTag
Return a list of files that need to be scanned for tags, starting at directory root.
Definition: builders.py:118
def BuildETags
Build Emacs tags (see man etags for more information).
Definition: builders.py:154
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 171 of file builders.py.

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

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

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

Return a product's PRODUCT_DIR, or None.

Definition at line 213 of file builders.py.

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

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

Definition at line 21 of file builders.py.

21 
22 def SharedLibraryIncomplete(self, target, source, **keywords):
23  myenv = self.Clone()
24  if myenv['PLATFORM'] == 'darwin':
25  myenv['SHLINKFLAGS'] += ["-undefined", "suppress", "-flat_namespace", "-headerpad_max_install_names"]
26  return myenv.SharedLibrary(target, source, **keywords)
def SharedLibraryIncomplete
Like SharedLibrary, but don't insist that all symbols are resolved.
Definition: builders.py:21
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 61 of file builders.py.

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

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

Definition at line 448 of file builders.py.

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