]> git.lyx.org Git - lyx.git/blob - development/scons/scons_utils.py
scons_utils.py: fix mkdir test on mingw
[lyx.git] / development / scons / scons_utils.py
1 # vi:filetype=python:expandtab:tabstop=2:shiftwidth=2
2 #
3 # file scons_utils.py
4
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
7
8 # \author Bo Peng
9 # Full author contact details are available in file CREDITS.
10 #
11 # This file defines all the utility functions for the
12 # scons-based build system of lyx
13
14
15 import os, sys, re, shutil, glob
16
17 config_h = os.path.join('src', 'config.h')
18
19 def writeToFile(filename, lines, append = False):
20   " utility function: write or append lines to filename "
21   if append:
22     file = open(filename, 'a')
23   else:
24     file = open(filename, 'w')
25   file.write(lines)
26   file.close()
27
28
29 def addToConfig(lines, top_src_dir):
30   ''' utility function: shortcut for appending lines to outfile
31     add newline at the end of lines.
32   '''
33   if lines.strip() != '':
34     writeToFile(os.path.join(top_src_dir, config_h), lines + '\n\n', append = True)
35
36
37 def printEnvironment(env, keys=[]):
38   ''' used to check profile settings '''
39   dict = env.Dictionary()
40   if len(keys) == 0:
41     keys = dict.keys()
42   keys.sort()
43   for key in keys:
44     try:
45       # try to expand, but this is not always possible
46       print key, '=', env.subst('$'+key)
47     except:   
48       print '<<UNEXPANDED>>:', key, '=', dict[key]
49
50
51 def env_subst(target, source, env):
52   ''' subst variables in source by those in env, and output to target
53     source and target are scons File() objects
54
55     %key% (not key itself) is an indication of substitution
56   '''
57   assert len(target) == 1
58   assert len(source) == 1
59   target_file = file(str(target[0]), "w")
60   source_file = file(str(source[0]), "r")
61   
62   contents = source_file.read()
63   for k in env.get('SUBST_KEYS', []):
64     if not env.has_key(k):
65       print "Failed to subst key ", k, " from file", str(source[0])
66       raise
67     contents = re.sub('@'+k+'@', env.subst('$'+k).replace('\n',r'\\n\\\n'), contents)
68   target_file.write(contents + "\n")
69   target_file.close()
70   #st = os.stat(str(source[0]))
71   #os.chmod(str(target[0]), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
72
73
74 def env_filecopy(target, source, env):
75   ''' target can be a directory '''
76   shutil.copy(str(source[0]), str(target[0]))
77
78
79 #
80 # autoconf tests
81 #
82
83 def checkPkgConfig(conf, version):
84   ''' Return false if pkg_config does not exist, or is too old '''
85   conf.Message('Checking for pkg-config...')
86   ret = conf.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
87   conf.Result(ret)
88   return ret
89
90
91 def checkPackage(conf, pkg):
92   ''' check if pkg is under the control of conf '''
93   conf.Message('Checking for package %s...' % pkg)
94   ret = conf.TryAction("pkg-config --print-errors --exists %s" % pkg)[0]
95   conf.Result(ret)
96   return ret
97
98
99 def startConfigH(top_src_dir):
100   ''' Write the first part of config.h '''
101   writeToFile(os.path.join(top_src_dir, config_h), 
102 '''/* src/config.h.  Generated by scon.  */
103
104 /* -*- C++ -*- */
105 /*
106  * \file config.h
107  * This file is part of LyX, the document processor.
108  * Licence details can be found in the file COPYING.
109  *
110  * This is the compilation configuration file for LyX.
111  * It was generated by scon.
112  * You might want to change some of the defaults if something goes wrong
113  * during the compilation.
114  */
115
116 #ifndef _CONFIG_H
117 #define _CONFIG_H
118 ''')
119
120
121 def endConfigH(top_src_dir):
122   ''' Write the last part of config.h '''
123   writeToFile(os.path.join(top_src_dir, config_h), '''
124 /************************************************************
125  ** You should not need to change anything beyond this point */
126
127 #ifndef HAVE_STRERROR
128 #if defined(__cplusplus)
129 extern "C"
130 #endif
131 char * strerror(int n);
132 #endif
133
134 #ifdef HAVE_MKSTEMP
135 #ifndef HAVE_DECL_MKSTEMP
136 #if defined(__cplusplus)
137 extern "C"
138 #endif
139 int mkstemp(char*);
140 #endif
141 #endif
142
143 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
144 #  define USE_BOOST_FORMAT 1
145 #else
146 #  define USE_BOOST_FORMAT 0
147 #endif
148
149 #define BOOST_USER_CONFIG <config.h>
150
151 #if !defined(ENABLE_ASSERTIONS)
152 #  define BOOST_DISABLE_ASSERTS 1
153 #endif
154 #define BOOST_ENABLE_ASSERT_HANDLER 1
155
156 #define BOOST_DISABLE_THREADS 1
157 #define BOOST_NO_WREGEX 1
158 #define BOOST_NO_WSTRING 1
159
160 #ifdef __CYGWIN__
161 #  define BOOST_POSIX 1
162 #endif
163
164 #if defined(HAVE_NEWAPIS_H)
165 #  define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
166 #endif
167
168 #endif
169 ''', append=True)
170
171
172 #HAVE_PUTENV
173 def checkPutenv(conf):
174   check_putenv_source = """
175 #include <stdlib.h>
176 int main()
177 {
178   putenv("");
179   return(0);
180 }
181 """
182   conf.Message('Checking for putenv... ')
183   ret = conf.TryLink(check_putenv_source, '.c')
184   conf.Result(ret)
185   return ret
186
187
188 #HAVE_DECL_ISTREAMBUF_ITERATOR
189 def checkIstreambufIterator(conf):
190   check_istreambuf_iterator_source = """
191 #include <streambuf> 
192 #include <istream>
193 int main()
194 {
195   std::istreambuf_iterator<std::istream> iter;
196   return 0;
197 }
198 """
199   conf.Message('Checking for iostreambuf::iterator... ')
200   ret = conf.TryLink(check_istreambuf_iterator_source, '.cpp')
201   conf.Result(ret)
202   return ret
203
204
205 #MKDIR_TAKES_ONE_ARG
206 def checkMkdirOneArg(conf):
207   check_mkdir_one_arg_source = """
208 #include <sys/stat.h>
209 int main()
210 {
211   mkdir("somedir");
212 }
213 """
214
215   check_mkdir_one_arg_source2 = """
216 #include <unistd.h>
217 int main()
218 {
219   mkdir("somedir");
220 }
221 """
222
223   conf.Message('Checking for the number of args for mkdir... ')
224   ret = conf.TryLink(check_mkdir_one_arg_source, '.c')
225   if ret:
226     conf.Result('one')
227   else:
228     ret = conf.TryLink(check_mkdir_one_arg_source2, '.c')
229     if ret:
230       conf.Result('one')
231     else:     
232       conf.Result('two')
233   return ret
234
235
236 #HAVE_STD_COUNT
237 def checkStdCount(conf):
238   check_std_count_source = """
239 #include <algorithm>
240 using std::count;
241 int countChar(char * b, char * e, char const c)
242 {
243   return count(b, e, c);
244 }
245
246 int main()
247 {
248   char a[] = "hello";
249   int i = countChar(a, a + 5, 'l');
250 }
251 """
252   conf.Message('Checking for std::count... ')
253   ret = conf.TryLink(check_std_count_source, '.cpp')
254   conf.Result(ret)
255   return ret
256
257
258 # SELECT_TYPE_ARG1
259 # SELECT_TYPE_ARG234
260 # SELECT_TYPE_ARG5
261 def checkSelectArgType(conf):
262   ''' Adapted from autoconf '''
263   conf.Message('Checking for arg types for select... ')
264   for arg234 in ['fd_set *', 'int *', 'void *']:
265     for arg1 in ['int', 'size_t', 'unsigned long', 'unsigned']:
266       for arg5 in ['struct timeval *', 'const struct timeval *']:
267         check_select_source = '''
268 #if HAVE_SYS_SELECT_H
269 # include <sys/select.h>
270 #endif
271 #if HAVE_SYS_SOCKET_H
272 # include <sys/socket.h>
273 #endif
274 extern int select (%s, %s, %s, %s, %s);
275 int main()
276 {
277   return(0);
278 }
279 ''' % (arg1, arg234, arg234, arg234, arg5)
280         ret = conf.TryLink(check_select_source, '.c')
281         if ret:
282           conf.Result(ret)
283           return (arg1, arg234, arg5)
284   conf.Result('no (use default)')
285   return ('int', 'int *', 'struct timeval *')
286
287
288 def checkBoostLibraries(conf, lib, pathes):
289   ''' look for boost libraries '''
290   conf.Message('Checking for boost library %s... ' % lib)
291   for path in pathes:
292     # direct form: e.g. libboost_iostreams.a
293     if os.path.isfile(os.path.join(path, 'lib%s.a' % lib)):
294       conf.Result('yes')
295       return (path, lib)
296     # check things like libboost_iostreams-gcc.a
297     files = glob.glob(os.path.join(path, 'lib%s-*.a' % lib))
298     # if there are more than one, choose the first one
299     # FIXME: choose the best one.
300     if len(files) >= 1:
301       # get xxx-gcc from /usr/local/lib/libboost_xxx-gcc.a
302       conf.Result('yes')
303       return (path, files[0].split(os.sep)[-1][3:-2])
304   conf.Result('n')
305   return ('','')
306
307
308 def checkMsgFmt(conf):
309   ''' check the existence of command msgfmt '''
310   conf.Message('Checking for gettext command msgfmt...')
311   res = conf.TryAction('msgfmt --help')
312   conf.Result(res[0])
313   if res[0]:
314     return 'msgfmt'
315   else:
316     return None
317
318
319 def installCygwinLDScript(path):
320   ''' Install i386pe.x-no-rdata '''
321   ld_script = os.path.join(path, 'i386pe.x-no-rdata')
322   script = open(ld_script, 'w')
323   script.write('''/* specific linker script avoiding .rdata sections, for normal executables 
324 for a reference see 
325 http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
326 http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
327 */
328 OUTPUT_FORMAT(pei-i386)
329 SEARCH_DIR("/usr/i686-pc-cygwin/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api");
330 ENTRY(_mainCRTStartup)
331 SECTIONS
332 {
333   .text  __image_base__ + __section_alignment__  :
334   {
335      *(.init)
336     *(.text)
337     *(SORT(.text$*))
338     *(.glue_7t)
339     *(.glue_7)
340      ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
341                         LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*));  LONG (0);
342      ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
343                         LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*));  LONG (0);
344      *(.fini)
345     /* ??? Why is .gcc_exc here?  */
346      *(.gcc_exc)
347     PROVIDE (etext = .);
348     *(.gcc_except_table)
349   }
350   /* The Cygwin32 library uses a section to avoid copying certain data
351      on fork.  This used to be named ".data".  The linker used
352      to include this between __data_start__ and __data_end__, but that
353      breaks building the cygwin32 dll.  Instead, we name the section
354      ".data_cygwin_nocopy" and explictly include it after __data_end__. */
355   .data BLOCK(__section_alignment__) :
356   {
357     __data_start__ = . ;
358     *(.data)
359     *(.data2)
360     *(SORT(.data$*))
361     *(.rdata)
362     *(SORT(.rdata$*))
363     *(.eh_frame)
364     ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
365     __RUNTIME_PSEUDO_RELOC_LIST__ = .;
366     *(.rdata_runtime_pseudo_reloc)
367     ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
368     __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
369     __data_end__ = . ;
370     *(.data_cygwin_nocopy)
371   }
372   .rdata BLOCK(__section_alignment__) :
373   {
374   }
375   .pdata BLOCK(__section_alignment__) :
376   {
377     *(.pdata)
378   }
379   .bss BLOCK(__section_alignment__) :
380   {
381     __bss_start__ = . ;
382     *(.bss)
383     *(COMMON)
384     __bss_end__ = . ;
385   }
386   .edata BLOCK(__section_alignment__) :
387   {
388     *(.edata)
389   }
390   /DISCARD/ :
391   {
392     *(.debug$S)
393     *(.debug$T)
394     *(.debug$F)
395     *(.drectve)
396   }
397   .idata BLOCK(__section_alignment__) :
398   {
399     /* This cannot currently be handled with grouped sections.
400         See pe.em:sort_sections.  */
401     SORT(*)(.idata$2)
402     SORT(*)(.idata$3)
403     /* These zeroes mark the end of the import list.  */
404     LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
405     SORT(*)(.idata$4)
406     SORT(*)(.idata$5)
407     SORT(*)(.idata$6)
408     SORT(*)(.idata$7)
409   }
410   .CRT BLOCK(__section_alignment__) :
411   {
412     ___crt_xc_start__ = . ;
413     *(SORT(.CRT$XC*))  /* C initialization */
414     ___crt_xc_end__ = . ;
415     ___crt_xi_start__ = . ;
416     *(SORT(.CRT$XI*))  /* C++ initialization */
417     ___crt_xi_end__ = . ;
418     ___crt_xl_start__ = . ;
419     *(SORT(.CRT$XL*))  /* TLS callbacks */
420     /* ___crt_xl_end__ is defined in the TLS Directory support code */
421     ___crt_xp_start__ = . ;
422     *(SORT(.CRT$XP*))  /* Pre-termination */
423     ___crt_xp_end__ = . ;
424     ___crt_xt_start__ = . ;
425     *(SORT(.CRT$XT*))  /* Termination */
426     ___crt_xt_end__ = . ;
427   }
428   .tls BLOCK(__section_alignment__) :
429   {
430     ___tls_start__ = . ;
431     *(.tls)
432     *(.tls$)
433     *(SORT(.tls$*))
434     ___tls_end__ = . ;
435   }
436   .endjunk BLOCK(__section_alignment__) :
437   {
438     /* end is deprecated, don't use it */
439     PROVIDE (end = .);
440     PROVIDE ( _end = .);
441      __end__ = .;
442   }
443   .rsrc BLOCK(__section_alignment__) :
444   {
445     *(.rsrc)
446     *(SORT(.rsrc$*))
447   }
448   .reloc BLOCK(__section_alignment__) :
449   {
450     *(.reloc)
451   }
452   .stab BLOCK(__section_alignment__) (NOLOAD) :
453   {
454     *(.stab)
455   }
456   .stabstr BLOCK(__section_alignment__) (NOLOAD) :
457   {
458     *(.stabstr)
459   }
460   /* DWARF debug sections.
461      Symbols in the DWARF debugging sections are relative to the beginning
462      of the section.  Unlike other targets that fake this by putting the
463      section VMA at 0, the PE format will not allow it.  */
464   /* DWARF 1.1 and DWARF 2.  */
465   .debug_aranges BLOCK(__section_alignment__) (NOLOAD) :
466   {
467     *(.debug_aranges)
468   }
469   .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
470   {
471     *(.debug_pubnames)
472   }
473   /* DWARF 2.  */
474   .debug_info BLOCK(__section_alignment__) (NOLOAD) :
475   {
476     *(.debug_info) *(.gnu.linkonce.wi.*)
477   }
478   .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
479   {
480     *(.debug_abbrev)
481   }
482   .debug_line BLOCK(__section_alignment__) (NOLOAD) :
483   {
484     *(.debug_line)
485   }
486   .debug_frame BLOCK(__section_alignment__) (NOLOAD) :
487   {
488     *(.debug_frame)
489   }
490   .debug_str BLOCK(__section_alignment__) (NOLOAD) :
491   {
492     *(.debug_str)
493   }
494   .debug_loc BLOCK(__section_alignment__) (NOLOAD) :
495   {
496     *(.debug_loc)
497   }
498   .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
499   {
500     *(.debug_macinfo)
501   }
502   /* SGI/MIPS DWARF 2 extensions.  */
503   .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
504   {
505     *(.debug_weaknames)
506   }
507   .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
508   {
509     *(.debug_funcnames)
510   }
511   .debug_typenames BLOCK(__section_alignment__) (NOLOAD) :
512   {
513     *(.debug_typenames)
514   }
515   .debug_varnames BLOCK(__section_alignment__) (NOLOAD) :
516   {
517     *(.debug_varnames)
518   }
519   /* DWARF 3.  */
520   .debug_ranges BLOCK(__section_alignment__) (NOLOAD) :
521   {
522     *(.debug_ranges)
523   }
524 }
525 ''')
526   script.close()
527   return(ld_script)
528
529
530 try:
531   # these will be used under win32
532   import win32file
533   import win32event
534   import win32process
535   import win32security
536 except:
537   # does not matter if it fails on other systems
538   pass
539
540
541 class loggedSpawn:
542   def __init__(self, env, logfile, longarg, info):
543     # save the spawn system
544     self.env = env
545     self.logfile = logfile
546     # clear the logfile (it may not exist)
547     if logfile != '':
548       # this will overwrite existing content.
549       writeToFile(logfile, info, append=False)
550     # 
551     self.longarg = longarg
552     # get hold of the old spawn? (necessary?)
553     self._spawn = env['SPAWN']
554
555   # define new SPAWN
556   def spawn(self, sh, escape, cmd, args, spawnenv):
557     # get command line
558     newargs = ' '.join(map(escape, args[1:]))
559     cmdline = cmd + " " + newargs
560     #
561     # if log is not empty, write to it
562     if self.logfile != '':
563       # this tend to be slow (?) but ensure correct output
564       # Note that cmdline may be long so I do not escape it
565       try:
566         # since this is not an essential operation, proceed if things go wrong here.
567         writeToFile(self.logfile, cmd + " " + ' '.join(args[1:]) + '\n', append=True)
568       except:
569         print "Warning: can not write to log file ", self.logfile
570     #
571     # if the command is not too long, use the old
572     if not self.longarg or len(cmdline) < 8000:
573       exit_code = self._spawn(sh, escape, cmd, args, spawnenv)
574     else:  
575       sAttrs = win32security.SECURITY_ATTRIBUTES()
576       StartupInfo = win32process.STARTUPINFO()
577       for var in spawnenv:
578         spawnenv[var] = spawnenv[var].encode('ascii', 'replace')
579       # check for any special operating system commands
580       if cmd == 'del':
581         for arg in args[1:]:
582           win32file.DeleteFile(arg)
583         exit_code = 0
584       else:
585         # otherwise execute the command.
586         hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(None, cmdline, None, None, 1, 0, spawnenv, None, StartupInfo)
587         win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
588         exit_code = win32process.GetExitCodeProcess(hProcess)
589         win32file.CloseHandle(hProcess);
590         win32file.CloseHandle(hThread);
591     return exit_code
592
593
594 def setLoggedSpawn(env, logfile = '', longarg=False, info=''):
595   ''' This function modify env and allow logging of
596     commands to a logfile. If the argument is too long
597     a win32 spawn will be used instead of the system one
598   '''
599   #
600   # create a new spwn object
601   ls = loggedSpawn(env, logfile, longarg, info)
602   # replace the old SPAWN by the new function
603   env['SPAWN'] = ls.spawn
604
605
606 ## def DistSources(env, node):
607 ##     env.DistFiles(_get_sources(env, node))
608 ## 
609 ## def DistFiles(env, files):
610 ##     assert isinstance(files, (list, tuple))
611 ##     DISTFILES = [env.File(fname) for fname in files]
612 ##     env.AppendUnique(DISTFILES=DISTFILES)
613 ## 
614 ## 
615 ## def make_distdir(target=None, source=None, env=None):
616 ##     distdir = env.subst('$DISTDIR')
617 ##     Execute(Delete(distdir))
618 ##     Execute(Mkdir(distdir))
619 ##     for fnode in env["DISTFILES"]:
620 ##         dirname, fname = os.path.split(str(fnode))
621 ##         if dirname:
622 ##             distdirname = os.path.join(distdir, dirname)
623 ##             if not os.path.exists(distdirname):
624 ##                 Execute(Mkdir(distdirname))
625 ##         Execute(Copy(os.path.join(distdir, dirname, fname), str(fnode)))
626 ##     
627 ## def make_dist(target=None, source=None, env=None):
628 ##     return Popen([env['TAR'], "-zcf",
629 ##                   env.subst("${PACKAGE}-${VERSION}.tar.gz"),
630 ##                   env.subst('$DISTDIR')]).wait()
631 ## 
632 ## def make_distcheck(target=None, source=None, env=None):
633 ##     distdir = env.subst('$DISTDIR')
634 ##     distcheckinstdir = tempfile.mkdtemp('', env.subst('${PACKAGE}-${VERSION}-instdir-'))
635 ##     distcheckdestdir = tempfile.mkdtemp('', env.subst('${PACKAGE}-${VERSION}-destdir-'))
636 ##     instdirs = [os.path.join(distcheckinstdir, d) for d in
637 ##                 'lib', 'share', 'bin', 'include']
638 ##     for dir_ in instdirs:
639 ##         Execute(Mkdir(dir_))
640 ## 
641 ##     cmd = env.subst("cd $DISTDIR && scons DESTDIR=%s prefix=%s"
642 ##                     " && scons check && scons install") %\
643 ##             (os.path.join(distcheckdestdir, ''), distcheckinstdir)
644 ##     status = Popen(cmd, shell=True).wait()
645 ##     if status:
646 ##         return status
647 ##     ## Check that inst dirs are empty (to catch cases of $DESTDIR not being honored
648 ##     for dir_ in instdirs:
649 ##         if os.listdir(dir_):
650 ##             raise SCons.Errors.BuildError(target, "%s not empy" % dir_)
651 ##     ## Check that something inside $DESTDIR was installed
652 ##     dir_ = os.path.join(distcheckdestdir, distcheckinstdir)
653 ##     if not os.path.exists(dir_):
654 ##         raise SCons.Errors.BuildError(target, "%s does not exist" % dir_)
655 ##     Execute(Delete(distcheckinstdir))
656 ##     Execute(Delete(distcheckdestdir))
657 ##     Execute(Delete(distdir))
658 ## 
659 ## def InstallWithDestDir(self, dir_, source):
660 ##     dir_ = '${DESTDIR}' + str(dir_)
661 ##     return SConsEnvironment.Install(self, dir_, source)
662 ## 
663 ## 
664 ## def InstallAsWithDestDir(self, target, source):
665 ##     target = '${DESTDIR}' + str(target)
666 ##     return SConsEnvironment.InstallAs(self, target, source)
667 ## 
668 ## def generate(env):
669 ##     env.EnsureSConsVersion(0, 96, 91)
670 ## 
671 ##     opts = Options(['options.cache'], ARGUMENTS)
672 ##     opts.Add(PathOption('prefix', 'Installation prefix', '/usr/local'))
673 ##     opts.Add(PathOption('exec_prefix', 'Installation prefix blah blah',
674 ##                         '$prefix'))
675 ##     opts.Add(PathOption('libdir',
676 ##         'Installation prefix for architecture dependent files', '$prefix/lib'))
677 ##     opts.Add(PathOption('includedir',
678 ##         'Installation prefix for C header files', '$prefix/include'))
679 ##     opts.Add(PathOption('datadir',
680 ##         'Installation prefix for architecture independent files', '$prefix/share'))
681 ##     opts.Add(PathOption('bindir', 'Installation prefix for programs', '$prefix/bin'))
682 ##     opts.Add(PathOption('DESTDIR', 'blah blah', None))
683 ##     opts.Update(env)
684 ##     opts.Save('options.cache', env)
685 ##     SConsEnvironment.Help(env, opts.GenerateHelpText(env))
686 ##     
687 ##     env.Append(CPPFLAGS=r' -DVERSION=\"$VERSION\"')
688 ##     env.Append(CCFLAGS=ARGUMENTS.get('CCFLAGS', '-g -O2'))
689 ## 
690 ##     env['GNOME_TESTS'] = dict(CheckPython=CheckPython,
691 ##                               CheckPythonHeaders=CheckPythonHeaders,
692 ##                               PkgCheckModules=PkgCheckModules)
693 ## 
694 ##     SConsEnvironment.DistSources = DistSources
695 ##     SConsEnvironment.DistFiles = DistFiles
696 ##     env['DISTDIR'] = "${PACKAGE}-${VERSION}"
697 ## 
698 ##     #env.Command(env.Dir("$DISTDIR"), None, make_distdir)
699 ##     
700 ##     distdir_alias = env.Alias("distdir", None, make_distdir)
701 ##     dist_alias = env.Alias("dist", None, make_dist)
702 ##     env.Depends(dist_alias, distdir_alias)
703 ##     distcheck_alias = env.Alias("distcheck", None, make_distcheck)
704 ##     env.Depends(distcheck_alias, distdir_alias)
705 ##     env.AlwaysBuild(env.Alias('check'))
706 ## 
707 ##     #env['TARFLAGS'] ='-c -z'
708 ##     #env['TARSUFFIX'] = '.tar.gz'
709 ##     #tar = env.Tar('${PACKAGE}-${VERSION}.tar.gz', "${DISTDIR}")
710 ##     #env.Depends(tar, distdir_alias)
711 ##     #print env['DEFAULT_TARGETS']
712 ## 
713 ##     #env.Depends(distdir_alias, "${DISTFILES}")
714 ##     #env.Alias('dist', tar)
715 ##     env.AlwaysBuild('dist')
716 ##     env.AlwaysBuild('distdir')
717 ##     env.AlwaysBuild('distcheck')
718 ##     env.DistFiles(['SConstruct', 'scons/gnome.py'])
719 ## 
720 ##     env['BUILDERS']['EnvSubstFile'] = SCons.Builder.Builder(action=env_subst)
721 ## 
722 ##     SConsEnvironment.PythonByteCompile = env.Action(byte_compile_python)
723 ##     
724 ##     env.Install = new.instancemethod(InstallWithDestDir, env, env.__class__)
725 ##     env.InstallAs = new.instancemethod(InstallAsWithDestDir, env, env.__class__)
726 ## 
727 ## 
728 ##  
729