LSSTApplications  11.0-13-gbb96280,12.1+18,12.1+7,12.1-1-g14f38d3+72,12.1-1-g16c0db7+5,12.1-1-g5961e7a+84,12.1-1-ge22e12b+23,12.1-11-g06625e2+4,12.1-11-g0d7f63b+4,12.1-19-gd507bfc,12.1-2-g7dda0ab+38,12.1-2-gc0bc6ab+81,12.1-21-g6ffe579+2,12.1-21-gbdb6c2a+4,12.1-24-g941c398+5,12.1-3-g57f6835+7,12.1-3-gf0736f3,12.1-37-g3ddd237,12.1-4-gf46015e+5,12.1-5-g06c326c+20,12.1-5-g648ee80+3,12.1-5-gc2189d7+4,12.1-6-ga608fc0+1,12.1-7-g3349e2a+5,12.1-7-gfd75620+9,12.1-9-g577b946+5,12.1-9-gc4df26a+10
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
 
def SwigLoadableModule
 
def SourcesForSharedLibrary
 Prepare the list of files to be passed to a SharedLibrary constructor. More...
 
def filesToTag
 
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
 
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 163 of file builders.py.

164 def BuildETags(env, root=None, fileRegex=None, ignoreDirs=None):
165  toTag = filesToTag(root, fileRegex, ignoreDirs)
166  if toTag:
167  return env.Command("TAGS", toTag, "etags -o $TARGET $SOURCES")
168 
169 
170 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def BuildETags
Build Emacs tags (see man etags for more information).
Definition: builders.py:163
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 181 of file builders.py.

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

454 def Doxygen(self, config, **kw):
455  inputs = [d for d in ["#doc", "#include", "#python", "#src"]
456  if os.path.exists(SCons.Script.Entry(d).abspath)]
457  defaults = {
458  "inputs": inputs,
459  "recursive": True,
460  "patterns": ["*.h", "*.cc", "*.py", "*.dox"],
461  "outputs": ["html", "xml"],
462  "excludes": [],
463  "includes": [],
464  "useTags": [],
465  "makeTag": None,
466  "projectName": None,
467  "projectNumber": None,
468  "excludeSwig": True
469  }
470  for k in defaults:
471  if kw.get(k) is None:
472  kw[k] = defaults[k]
473  builder = DoxygenBuilder(**kw)
474  return builder(self, config)
475 
476 
@memberOf(SConsEnvironment)
def memberOf
A Python decorator that injects functions into a class.
Definition: utils.py:157
def Doxygen
Generate a Doxygen config file and run Doxygen on it.
Definition: builders.py:453
A callable to be used as an SCons Action to run Doxygen.
Definition: builders.py:250
def lsst.sconsUtils.builders.filesToTag (   root = None,
  fileRegex = None,
  ignoreDirs = None 
)

Definition at line 123 of file builders.py.

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

Definition at line 224 of file builders.py.

225 def ProductDir(env, product):
226  from . import eupsForScons
227  global _productDirs
228  try:
229  _productDirs
230  except:
231  try:
232  _productDirs = eupsForScons.productDir(eupsenv=eupsForScons.getEups())
233  except TypeError: # old version of eups (pre r18588)
234  _productDirs = None
235  if _productDirs:
236  pdir = _productDirs.get(product)
237  else:
238  pdir = eupsForScons.productDir(product)
239  if pdir == "none":
240  pdir = None
241  return pdir
242 
243 
244 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def lsst.sconsUtils.builders.SharedLibraryIncomplete (   self,
  target,
  source,
  keywords 
)

Definition at line 23 of file builders.py.

23 
24 def SharedLibraryIncomplete(self, target, source, **keywords):
25  myenv = self.Clone()
26  if myenv['PLATFORM'] == 'darwin':
27  myenv['SHLINKFLAGS'] += ["-undefined", "suppress", "-flat_namespace", "-headerpad_max_install_names"]
28  return myenv.SharedLibrary(target, source, **keywords)
29 
30 
31 # @brief Like LoadableModule, but don't insist that all symbols are resolved, and set
32 # some SWIG-specific flags.
@memberOf(SConsEnvironment)
def memberOf
A Python decorator that injects functions into a class.
Definition: utils.py:157
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 66 of file builders.py.

66 
67 def SourcesForSharedLibrary(self, files):
68 
69  files = [SCons.Script.File(file) for file in files]
70 
71  if not (self.get("optFiles") or self.get("noOptFiles")):
72  objs = [self.SharedObject(ccFile) for ccFile in sorted(state.env.Flatten(files), key=str)]
73  return objs
74 
75  if self.get("optFiles"):
76  optFiles = self["optFiles"].replace(".", r"\.") # it'll be used in an RE
77  optFiles = SCons.Script.Split(optFiles.replace(",", " "))
78  optFilesRe = "/(%s)$" % "|".join(optFiles)
79  else:
80  optFilesRe = None
81 
82  if self.get("noOptFiles"):
83  noOptFiles = self["noOptFiles"].replace(".", r"\.") # it'll be used in an RE
84  noOptFiles = SCons.Script.Split(noOptFiles.replace(",", " "))
85  noOptFilesRe = "/(%s)$" % "|".join(noOptFiles)
86  else:
87  noOptFilesRe = None
88 
89  if self.get("opt"):
90  opt = int(self["opt"])
91  else:
92  opt = 0
93 
94  if opt == 0:
95  opt = 3
96 
97  CCFLAGS_OPT = re.sub(r"-O(\d|s)\s*", "-O%d " % opt, " ".join(self["CCFLAGS"]))
98  CCFLAGS_NOOPT = re.sub(r"-O(\d|s)\s*", "-O0 ", " ".join(self["CCFLAGS"])) # remove -O flags from CCFLAGS
99 
100  objs = []
101  for ccFile in files:
102  if optFilesRe and re.search(optFilesRe, ccFile.abspath):
103  obj = self.SharedObject(ccFile, CCFLAGS=CCFLAGS_OPT)
104  elif noOptFilesRe and re.search(noOptFilesRe, ccFile.abspath):
105  obj = self.SharedObject(ccFile, CCFLAGS=CCFLAGS_NOOPT)
106  else:
107  obj = self.SharedObject(ccFile)
108  objs.append(obj)
109 
110  objs = sorted(state.env.Flatten(sources), key=str)
111  return objs
112 
113 
114 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
115 
116 #
117 # @brief Return a list of files that need to be scanned for tags, starting at directory root
118 #
119 # These tags are for advanced Emacs users, and should not be confused with SVN tags or Doxygen tags.
120 #
121 # Files are chosen if they match fileRegex; toplevel directories in list ignoreDirs are ignored
122 # This routine won't do anything unless you specified a "TAGS" target
#
def SourcesForSharedLibrary
Prepare the list of files to be passed to a SharedLibrary constructor.
Definition: builders.py:66
def lsst.sconsUtils.builders.SwigLoadableModule (   self,
  target,
  source,
  keywords 
)

Definition at line 33 of file builders.py.

33 
34 def SwigLoadableModule(self, target, source, **keywords):
35  myenv = self.Clone()
36  if myenv['PLATFORM'] == 'darwin':
37  myenv.Append(LDMODULEFLAGS=["-undefined", "suppress",
38  "-flat_namespace", "-headerpad_max_install_names"])
39  #
40  # Swig-generated .cc files cast pointers to long longs and back,
41  # which is illegal. This flag tells g++ about the sin
42  #
43  try:
44  if myenv.whichCc == "gcc":
45  myenv.Append(CCFLAGS=["-fno-strict-aliasing"])
46  except AttributeError:
47  pass
48  return myenv.LoadableModule(target, source, **keywords)
49 
50 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
51 
def lsst.sconsUtils.builders.VersionModule (   self,
  filename,
  versionString = None 
)

Definition at line 477 of file builders.py.

478 def VersionModule(self, filename, versionString=None):
479  if versionString is None:
480  for n in ("git", "hg", "svn",):
481  if os.path.isdir(".%s" % n):
482  versionString = n
483 
484  if not versionString:
485  versionString = "git"
486 
487  def calcMd5(filename):
488  try:
489  import hashlib
490  md5 = hashlib.md5("\n".join(open(filename).readlines())).hexdigest()
491  except IOError:
492  md5 = None
493 
494  return md5
495 
496  oldMd5 = calcMd5(filename)
497 
498  def makeVersionModule(target, source, env):
499  try:
500  version = determineVersion(state.env, versionString)
501  except RuntimeError:
502  version = "unknown"
503  parts = version.split("+")
504 
505  names = []
506  with open(target[0].abspath, "w") as outFile:
507  outFile.write("#--------- This file is automatically generated by LSST's sconsUtils ---------#\n")
508 
509  what = "__version__"
510  outFile.write("%s = '%s'\n" % (what, version))
511  names.append(what)
512 
513  what = "__repo_version__"
514  outFile.write("%s = '%s'\n" % (what, parts[0]))
515  names.append(what)
516 
517  what = "__fingerprint__"
518  outFile.write("%s = '%s'\n" % (what, getFingerprint(versionString)))
519  names.append(what)
520 
521  try:
522  info = tuple(int(v) for v in parts[0].split("."))
523  what = "__version_info__"
524  names.append(what)
525  outFile.write("%s = %r\n" % (what, info))
526  except ValueError:
527  pass
528 
529  if len(parts) > 1:
530  try:
531  what = "__rebuild_version__"
532  outFile.write("%s = %s\n" % (what, int(parts[1])))
533  names.append(what)
534  except ValueError:
535  pass
536 
537  what = "__dependency_versions__"
538  names.append(what)
539  outFile.write("%s = {\n" % (what))
540  for name, mod in env.dependencies.packages.items():
541  if mod is None:
542  outFile.write(" '%s': None,\n" % name)
543  elif hasattr(mod.config, "version"):
544  outFile.write(" '%s': '%s',\n" % (name, mod.config.version))
545  else:
546  outFile.write(" '%s': 'unknown',\n" % name)
547  outFile.write("}\n")
548 
549  outFile.write("__all__ = %r\n" % (tuple(names),))
550 
551  if calcMd5(target[0].abspath) != oldMd5: # only print if something's changed
552  state.log.info("makeVersionModule([\"%s\"], [])" % str(target[0]))
553 
554  result = self.Command(filename, [], self.Action(makeVersionModule, strfunction=lambda *args: None))
555 
556  self.AlwaysBuild(result)
557  return result