/[escript]/branches/postrelease-csirofixes/site_scons/site_init.py
ViewVC logotype

Annotation of /branches/postrelease-csirofixes/site_scons/site_init.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1387 - (hide annotations)
Fri Jan 11 07:45:26 2008 UTC (11 years, 5 months ago) by trankine
Original Path: temp/scons/scons_extensions.py
File MIME type: text/x-python
File size: 14668 byte(s)
Restore the trunk that existed before the windows changes were committed to the (now moved to branches) old trunk.
1 elspeth 645
2    
3 jgs 268 # Extensions to Scons
4    
5     import py_compile
6     import sys
7 jgs 297 import os
8 ksteube 1312 import time
9 phornby 1233 import glob
10     import fnmatch
11     import types
12 jgs 268
13 phornby 1233 from SCons.Script.SConscript import SConsEnvironment
14    
15     ###############################################################################
16     def matchingFiles(env,directory,includes='*',excludes=None) :
17    
18     # Pre-process for more convenient arguments
19    
20     if isinstance(includes,str) :
21     includes = env.Split(includes)
22    
23     if isinstance(excludes,str) :
24     excludes = env.Split(excludes)
25    
26     def fn_filter(node):
27     fn = os.path.basename(str(node))
28     match = False
29     for include in includes:
30     if fnmatch.fnmatchcase( fn, include ):
31     match = True
32     break
33    
34     if match and not excludes is None:
35     for exclude in excludes:
36     if fnmatch.fnmatchcase( fn, exclude ):
37     match = False
38     break
39    
40     return match
41    
42     def filter_nodes(where):
43     contents = glob.glob( os.path.join(str(where),"*") )
44     children = [ x for x in contents if fn_filter(x) ]
45     nodes = []
46     for f in children:
47     nodes.append(gen_node(f))
48     return nodes
49    
50     def gen_node(n):
51     """Checks first to see if the node is a file or a dir, then
52     creates the appropriate node. [code seems redundant, if the node
53     is a node, then shouldn't it just be left as is?
54     """
55     if type(n) in (type(''), type(u'')):
56     path = n
57     else:
58     path = n.abspath
59    
60     if os.path.isdir(path):
61     return env.Dir(n)
62    
63     return env.File(n)
64    
65     here = env.Dir(directory)
66     nodes = filter_nodes(here)
67    
68     node_srcs = [n.srcnode() for n in nodes]
69    
70     src = here.srcnode()
71     if src is not here:
72     for s in filter_nodes(src):
73     if s not in node_srcs:
74     # Probably need to check if this node is a directory
75     nodes.append(
76     gen_node(os.path.join(str(directory),
77     os.path.basename(str(s)))))
78    
79     return nodes
80     #==============================================================================
81     SConsEnvironment.matchingFiles = matchingFiles
82     ###############################################################################
83    
84    
85    
86     ###############################################################################
87     def InstallPyModule(env,target_dir,source,shlib=None,excludes=None) :
88    
89     # put the .so/.dll over in <target_dir>
90     if shlib :
91     shtarg = env.Install(target_dir, shlib)
92    
93     # Gather the python sources
94     python_src = env.matchingFiles(source, "*.py",excludes=excludes)
95    
96     # Here is a hack to deal with the (possibly not yet generated)
97     # __init__.py. The problem is that the python_src list is built before
98     # __init__.py is updated from __init__.in. The AlwaysBuild call
99     # ensures that this does not cause a problem, except on the first
100     # build after a clean checkout, in which case there is no old
101     # __init__.py in src, and hence it does not make it into python_src!
102    
103     init_input = env.matchingFiles(source, "__init__.in")
104     if init_input :
105     if python_src :
106     names = [x.name for x in python_src]
107     if "__init__.py" not in names :
108     python_src.append(env.File(os.path.join(str(source),
109     "__init__.py")))
110     else:
111     python_src = [env.File(os.path.join(str(source),"__init__.py"))]
112    
113     # decide if we're doing py or pyc distribn and install.
114    
115     if env['distrib_py_src'] :
116     pytarg = env.Install(target_dir, python_src)
117     else:
118     pyc = env.PyCompile(python_src)
119     pytarg = env.Install(target_dir, pyc)
120    
121     if shlib :
122     targ_ret = env.Flatten([pytarg] + [shtarg])
123     else:
124     targ_ret = pytarg
125    
126     return targ_ret
127     #==============================================================================
128     SConsEnvironment.InstallPyModule = InstallPyModule
129     ###############################################################################
130    
131     ###############################################################################
132     def installDirectory(env,target,source,includes="*", excludes=None,
133     recursive=False):
134    
135    
136     if os.path.isfile(str(target)) :
137     raise UserError("target must be a directory")
138    
139     if os.path.isfile(str(source)) :
140     raise UserError("source must be a directory")
141    
142     source_files = env.matchingFiles(source,includes,excludes)
143    
144     ret_targ = []
145    
146     for f in source_files :
147     if f.isfile() :
148     targ = env.Install(target,f)
149     ret_targ.append(targ)
150    
151     if f.isdir() and recursive :
152     x = os.path.basename(str(f))
153     t = env.Dir(os.path.join(str(target),x))
154     targ = env.installDirectory(t,f,includes,excludes,recursive)
155     ret_targ += targ
156    
157     return ret_targ
158     #==============================================================================
159     SConsEnvironment.installDirectory = installDirectory
160     ###############################################################################
161    
162     ###############################################################################
163 jgs 268 # Code to build .pyc from .py
164     def build_py(target, source, env):
165 phornby 1233 py_compile.compile(str(source[0]), str(target[0]))
166     return 0
167 jgs 297
168 phornby 1233 def doSubstitution(target,source,env) :
169     import product_info as PI
170     data = source[0].get_contents()
171     data = data.replace('$ProductName$',PI.PRODUCT_NAME)
172     data = data.replace('$LowerProductName$',PI.product_name)
173     data = data.replace('$ProductVersion$',PI.product_version)
174     data = data.replace('$VersionString$',PI.pkg_version_string)
175     data = data.replace('$SVNRevision$',PI.svn_revision)
176     open(str(target[0]),'w').write(data)
177     return 0
178    
179 jgs 297 # Code to run unit_test executables
180     def runUnitTest(target, source, env):
181 ksteube 1312 time_start = time.time()
182     app = str(source[0].abspath)
183     if env['useMPI']: app = env['mpi_run'] + ' ' + app
184     print "Executing test: " + app
185     if not env.Execute(app):
186 jgs 297 open(str(target[0]),'w').write("PASSED\n")
187 ksteube 1312 else:
188     return 1
189     print "Test execution time: ", round(time.time() - time_start, 1), " seconds wall time for " + str(source[0].abspath)
190     return None
191 cochrane 370
192 robwdcock 682 def runPyUnitTest(target, source, env):
193 ksteube 1312 time_start = time.time()
194     app = str(source[0].abspath)
195     if env['useMPI']:
196     app = env['mpi_run'] +' lib/pythonMPI ' + app
197     else:
198 gross 1374 app = sys.executable + " " + app
199 ksteube 1312 print "Executing test: " + app
200 gross 1374 if env.Execute(app) == 0:
201 ksteube 1312 open(str(target[0]),'w').write("PASSED\n")
202     else:
203     return 1
204     print "Test execution time: ", round(time.time() - time_start, 1), " seconds wall time for " + str(source[0].abspath)
205     return None
206 phornby 1233
207     def addBuilders(env) :
208     py_builder = env.Builder(action = build_py,
209     suffix = '.pyc',
210     src_suffix = '.py',
211     single_source=True)
212    
213     env.Append(BUILDERS = {'PyCompile' : py_builder});
214    
215     substituter = env.Builder(action = doSubstitution,
216     suffix = '',
217     src_suffix = '.in',
218     single_source=True )
219    
220     env.Append(BUILDERS = {'VariableSubstitution' : substituter});
221    
222     runUnitTest_builder = env.Builder(action = runUnitTest,
223     suffix = '.passed',
224     src_suffix=env.get('PROGSUFFIX',''),
225     single_source=True)
226    
227     env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
228    
229     runPyUnitTest_builder = env.Builder(action = runPyUnitTest,
230     suffix = '.passed',
231     src_suffix='.py',
232     single_source=True)
233    
234     env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
235     return
236     #==============================================================================
237     SConsEnvironment.addBuilders = addBuilders
238     ###############################################################################
239    
240     ###############################################################################
241     def epydocAction(target, source, env):
242    
243     doc_dir = os.path.dirname(str(target[0].abspath))
244    
245     cmd = [
246     [env['epydoc_path'], "-qqqq", "-o", doc_dir, str(source[0].tpath)]
247     ]
248     print 'executing epydoc...'
249     return env.Execute(cmd,"Build epydoc documentation")
250    
251    
252     def epydocDepend(env, target, source,
253     src_pattern="*.py",
254     file_names=['index.html','epydoc.css'],
255     subdirs=['private','public']) :
256     """
257     \brief add a dependency between the directory containing the doco and that
258     containing the source
259     \param target - the directory containing index.html for the doco,
260     and the private and public sub-directories.
261     \param source - the python module source directory
262     """
263     the_subdirs = [os.path.join(target.abspath,sub) for sub in subdirs]
264     the_targets = [os.path.join(target.abspath,file) for file in file_names]
265    
266    
267     ret_target = target
268    
269     # if absolutely anything goes wrong, turn this on.
270     force_build = False
271    
272     dst_time = 0
273     src_time = 1
274    
275     try:
276    
277     # have a shot at digging out all the source file times.
278     src_time = max(
279     [os.path.getmtime(str(x))
280     for x in env.matchingFiles(source,src_pattern) +
281     [source.abspath]]
282     )
283    
284     # now try to find the target files and their mod time.
285     a = [os.path.getmtime(os.path.join(target.abspath,str(x)))
286     for x in file_names ]
287    
288     for directory in the_subdirs :
289     # include the mod time of the directory
290     a += [os.path.getmtime(str(directory))]
291    
292     # now go for the mod times of all files below the subdirs.
293     if os.path.isdir(str(directory)) :
294     a += [os.path.getmtime(str(x))
295     for x in env.matchingFiles(directory,"*")]
296    
297     else:
298     # if it is not a directory, and we expected it to be
299     # do something nasty.
300     # we're in a try anyway.
301     force_build = True
302     os.unlink(directory)
303    
304     dst_time = max(a)
305    
306     except:
307     # Force an unlink and re-build.
308     force_build = True
309    
310     if src_time > dst_time or force_build :
311     for x in the_targets :
312     try:
313     os.unlink(x)
314     except OSError:
315     pass
316    
317     ret_target = env.Command(the_targets,source,epydocAction)
318    
319    
320     env.Clean(target, the_subdirs + file_names)
321    
322     return ret_target
323     #==============================================================================
324     SConsEnvironment.epydocDepend = epydocDepend
325     ###############################################################################
326    
327    
328     ###############################################################################
329     def genSConscriptCalls(env,dir_list):
330    
331     for d in dir_list :
332     print 'calling SConscript in "./%s"' %(d)
333     env.SConscript(dirs = [d],
334     build_dir='build/$PLATFORM/' + str(d),
335     duplicate=0)
336    
337    
338     return
339     #==============================================================================
340     SConsEnvironment.genSConscriptCalls = genSConscriptCalls
341     ###############################################################################
342    
343    
344     ###############################################################################
345     def print_all_nodes(env,dirnode, level=0):
346     """Print all the scons nodes that are children of this node, recursively."""
347     if type(dirnode)==type(''):
348     dirnode=env.Dir(dirnode)
349     dt = type(env.Dir('.'))
350     for f in dirnode.all_children():
351     if type(f) == dt:
352     print "%s%s: .............."%(level * ' ', str(f))
353     env.print_all_nodes(f, level+2)
354     print "%s%s"%(level * ' ', str(f))
355    
356     #==============================================================================
357     SConsEnvironment.print_all_nodes = print_all_nodes
358     ###############################################################################
359    
360    
361    
362    
363    
364    
365    
366    
367    
368    
369    
370    
371    
372    
373    
374    
375    
376    
377    
378    
379    
380     ###############################################################################
381     def Glob(env,dir='.',includes="*",excludes=None, scan_dir=True):
382    
383     """Similar to glob.glob, except globs SCons nodes, and thus sees
384     generated files and files from build directories. Basically, it sees
385     anything SCons knows about. A key subtlety is that since this function
386     operates on generated nodes as well as source nodes on the filesystem,
387     it needs to be called after builders that generate files you want to
388     include.
389    
390     It will return both Dir entries and File entries
391     """
392    
393     # Pre-process for more convenient arguments
394    
395     if isinstance(includes,str) :
396     includes = env.Split(includes)
397    
398     if isinstance(excludes,str) :
399     excludes = env.Split(excludes)
400    
401     def fn_filter(node):
402     fn = os.path.basename(str(node))
403     match = 0
404     for include in includes:
405     if fnmatch.fnmatchcase( fn, include ):
406     match = 1
407     break
408    
409     if match == 1 and not excludes is None:
410     for exclude in excludes:
411     if fnmatch.fnmatchcase( fn, exclude ):
412     match = 0
413     break
414    
415     return match
416    
417     def filter_nodes(where):
418     contents = where.all_children(scan=scan_dir)
419     children = [ x for x in contents if fn_filter(x) ]
420     nodes = []
421     for f in children:
422     nodes.append(gen_node(f))
423     return nodes
424    
425     def gen_node(n):
426     """Checks first to see if the node is a file or a dir, then
427     creates the appropriate node. [code seems redundant, if the node
428     is a node, then shouldn't it just be left as is?
429     """
430     if type(n) in (type(''), type(u'')):
431     path = n
432     else:
433     path = n.abspath
434     if os.path.isdir(path):
435     return env.Dir(n)
436     else:
437     return env.File(n)
438    
439     here = env.Dir(dir)
440     nodes = filter_nodes(here)
441    
442     node_srcs = [n.srcnode() for n in nodes]
443    
444     src = here.srcnode()
445     if src is not here:
446     for s in filter_nodes(src):
447     if s not in node_srcs:
448     # Probably need to check if this node is a directory
449     nodes.append(
450     gen_node(os.path.join(dir,os.path.basename(str(s)))))
451    
452     return nodes

  ViewVC Help
Powered by ViewVC 1.1.26