13 from .
import dependencies
14 from .
import builders
15 from .
import installation
20 name, ext = os.path.splitext(os.path.basename(str(node)))
51 def __new__(cls, packageName, versionString=None, eupsProduct=None, eupsProductPath=None, cleanExt=None,
52 defaultTargets=(
"lib",
"python",
"tests",
"examples",
"doc"),
53 subDirList=
None, ignoreRegex=
None,
54 versionModuleName=
"python/lsst/%s/version.py", noCfgFile=
False):
55 cls.initialize(packageName, versionString, eupsProduct, eupsProductPath, cleanExt,
56 versionModuleName, noCfgFile=noCfgFile)
57 cls.finish(defaultTargets, subDirList, ignoreRegex)
82 def initialize(cls, packageName, versionString=None, eupsProduct=None, eupsProductPath=None,
83 cleanExt=
None, versionModuleName=
"python/lsst/%s/version.py", noCfgFile=
False):
85 state.log.fail(
"Recursion detected; an SConscript file should not call BasicSConstruct.")
86 cls._initializing =
True
88 cleanExt =
r"*~ core *.so *.os *.o *.pyc *.pkgc"
89 dependencies.configure(packageName, versionString, eupsProduct, eupsProductPath, noCfgFile)
90 state.env.BuildETags()
91 state.env.CleanTree(cleanExt)
92 if versionModuleName
is not None:
94 versionModuleName = versionModuleName %
"/".join(packageName.split(
"_"))
97 state.targets[
"version"] = state.env.VersionModule(versionModuleName)
98 for root, dirs, files
in os.walk(
"."):
99 if "SConstruct" in files
and root !=
".":
102 dirs[:] = [d
for d
in dirs
if (
not d.startswith(
'.'))]
104 if "SConscript" in files:
105 state.log.info(
"Using Sconscript at %s/SConscript" % root)
106 SCons.Script.SConscript(os.path.join(root,
"SConscript"))
107 cls._initializing =
False
128 def finish(defaultTargets=(
"lib",
"python",
"tests",
"examples",
"doc"),
129 subDirList=
None, ignoreRegex=
None):
130 if ignoreRegex
is None:
131 ignoreRegex =
r"(~$|\.pyc$|^\.svn$|\.o|\.os$)"
132 if subDirList
is None:
134 for path
in os.listdir(
"."):
135 if os.path.isdir(path)
and not path.startswith(
"."):
136 subDirList.append(path)
137 install = state.env.InstallLSST(state.env[
"prefix"],
138 [subDir
for subDir
in subDirList],
139 ignoreRegex=ignoreRegex)
140 for name, target
in state.targets.iteritems():
141 state.env.Requires(install, target)
142 state.env.Alias(name, target)
143 state.env.Requires(state.targets[
"python"], state.targets[
"version"])
144 declarer = state.env.Declare()
145 state.env.Requires(declarer, install)
146 state.env.Default([t
for t
in defaultTargets
if os.path.exists(t)])
147 if "version" in state.targets:
148 state.env.Default(state.targets[
"version"])
149 state.env.Requires(state.targets[
"tests"], state.targets[
"version"])
150 state.env.Decider(
"MD5-timestamp")
157 if "tests" in [str(t)
for t
in BUILD_TARGETS]:
158 testsDir = os.path.join(os.getcwd(),
"tests",
".tests")
159 checkTestStatus_command = state.env.Command(
'checkTestStatus', [],
"""
160 @ if [ -d %s ]; then \
161 nfail=`find %s -name \*.failed | wc -l | sed -e 's/ //g'`; \
162 if [ $$nfail -gt 0 ]; then \
163 echo "$$nfail tests failed" >&2; exit 1; \
166 """ % (testsDir, testsDir))
168 state.env.Depends(checkTestStatus_command, BUILD_TARGETS)
169 BUILD_TARGETS.extend(checkTestStatus_command)
170 state.env.AlwaysBuild(checkTestStatus_command)
194 def lib(libName=None, src=None, libs="self"):
196 libName = state.env[
"packageName"]
198 src = Glob(
"#src/*.cc") + Glob(
"#src/*/*.cc") + Glob(
"#src/*/*/*.cc") + Glob(
"#src/*/*/*/*.cc")
199 src = state.env.SourcesForSharedLibrary(src)
200 if isinstance(libs, basestring):
201 libs = state.env.getLibs(libs)
204 result = state.env.SharedLibrary(libName, src, LIBS=libs)
205 state.targets[
"lib"].extend(result)
223 def python(swigNameList=None, libs="main python", swigSrc=None):
224 if swigNameList
is None:
225 swigNameList = [state.env[
"packageName"].split(
"_")[-1] +
"Lib"]
226 swigFileList = [File(name +
".i")
for name
in swigNameList]
229 for name, node
in zip(swigNameList, swigFileList):
230 swigSrc.setdefault(name, []).append(node)
231 if isinstance(libs, basestring):
232 libs = state.env.getLibs(libs)
236 for name, src
in swigSrc.iteritems():
237 result.extend(state.env.SwigLoadableModule(
"_" + name, src, LIBS=libs))
238 state.targets[
"python"].extend(result)
252 def doc(config="doxygen.conf.in", projectName=None, projectNumber=None, **kw):
253 if not state.env.ProductDir(
"doxygen"):
254 state.log.warn(
"Doxygen is not setup; skipping documentation build.")
256 if projectName
is None:
257 projectName =
".".join([
"lsst"] + state.env[
"packageName"].split(
"_"))
258 if projectNumber
is None:
259 projectNumber = state.env[
"version"]
260 result = state.env.Doxygen(
261 config, projectName=projectName, projectNumber=projectNumber,
262 includes=state.env.doxygen[
"includes"],
263 useTags=state.env.doxygen[
"tags"],
264 makeTag=(state.env[
"packageName"] +
".tag"),
267 state.targets[
"doc"].extend(result)
298 def tests(pyList=None, ccList=None, swigNameList=None, swigSrc=None,
299 ignoreList=
None, noBuildList=
None,
301 if noBuildList
is None:
303 if swigNameList
is None:
304 swigFileList = Glob(
"*.i")
305 swigNameList = [
_getFileBase(node)
for node
in swigFileList]
307 swigFileList = [File(name +
".i")
for name
in swigNameList]
311 for name, node
in zip(swigNameList, swigFileList):
312 src = swigSrc.setdefault(name, [])
313 allSwigSrc.update(str(element)
for element
in src)
316 pyList = [node
for node
in Glob(
"*.py")
318 and os.path.basename(str(node))
not in noBuildList]
320 ccList = [node
for node
in Glob(
"*.cc")
321 if (
not str(node).endswith(
"_wrap.cc"))
and str(node)
not in allSwigSrc
322 and os.path.basename(str(node))
not in noBuildList]
323 if ignoreList
is None:
325 s =
lambda l: [str(i)
for i
in l]
326 state.log.info(
"SWIG modules for tests: %s" % s(swigFileList))
327 state.log.info(
"Python tests: %s" % s(pyList))
328 state.log.info(
"C++ tests: %s" % s(ccList))
329 state.log.info(
"Files that will not be built: %s" % noBuildList)
330 state.log.info(
"Ignored tests: %s" % ignoreList)
331 control =
tests.Control(state.env, ignoreList=ignoreList, args=args, verbose=
True)
332 for ccTest
in ccList:
333 state.env.Program(ccTest, LIBS=state.env.getLibs(
"main test"))
335 for name, src
in swigSrc.iteritems():
337 state.env.SwigLoadableModule(
"_" + name, src, LIBS=state.env.getLibs(
"main python"))
339 ccList = [control.run(str(node))
for node
in ccList]
340 pyList = [control.run(str(node))
for node
in pyList]
341 for pyTest
in pyList:
342 state.env.Depends(pyTest, swigMods)
343 state.env.Depends(pyTest, state.targets[
"python"])
344 result = ccList + pyList
345 state.targets[
"tests"].extend(result)
360 def examples(ccList=None, swigNameList=None, swigSrc=None):
361 if swigNameList
is None:
362 swigFileList = Glob(
"*.i")
363 swigNameList = [
_getFileBase(node)
for node
in swigFileList]
365 swigFileList = [File(name)
for name
in swigNameList]
369 for name, node
in zip(swigNameList, swigFileList):
370 src = swigSrc.setdefault(name, [])
371 allSwigSrc.update(str(element)
for element
in src)
374 ccList = [node
for node
in Glob(
"*.cc")
375 if (
not str(node).endswith(
"_wrap.cc"))
and str(node)
not in allSwigSrc]
376 state.log.info(
"SWIG modules for examples: %s" % swigFileList)
377 state.log.info(
"C++ examples: %s" % ccList)
380 results.extend(state.env.Program(src, LIBS=state.env.getLibs(
"main")))
382 for name, src
in swigSrc.iteritems():
384 state.env.SwigLoadableModule(
"_" + name, src, LIBS=state.env.getLibs(
"main python"))
386 for result
in results:
387 state.env.Depends(result, state.targets[
"lib"])
388 state.targets[
"examples"].extend(results)
def lib
Convenience function to replace standard lib/SConscript boilerplate.
def initialize
Convenience function to replace standard SConstruct boilerplate (step 1).
def finish
Convenience function to replace standard SConstruct boilerplate (step 2).
def doc
Convenience function to replace standard doc/SConscript boilerplate.
A scope-only class for SConstruct-replacement convenience functions.
A scope-only class for SConscript-replacement convenience functions.
def examples
Convenience function to replace standard examples/SConscript boilerplate.
def __new__
Convenience function to replace standard SConstruct boilerplate.
A class to control unit tests.
def tests
Convenience function to replace standard tests/SConscript boilerplate.
def python
Convenience function to replace standard python/*/SConscript boilerplate.