From 8687dd795d1f87ea149a7007860a87439af23b26 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Tue, 6 Jan 2009 10:52:43 +0000 Subject: [PATCH] + Scons updated to latest stable version 1.2 --- SConstruct | 48 +- scons/scons-LICENSE | 2 +- scons/scons-README | 2 +- .../SCons/Errors.py | 71 -- .../SCons/Scanner/LaTeX.py | 126 ---- .../SCons/Tool/f77.py | 135 ---- .../SCons/Tool/f90.py | 132 ---- .../SCons/Tool/f95.py | 135 ---- .../SCons/Tool/fortran.py | 186 ----- .../SCons/Tool/tex.py | 268 ------- .../scons-0.97.0d20071212.egg-info | 13 - .../SCons/Action.py | 634 ++++++++++++----- .../SCons/Builder.py | 27 +- .../SCons/CacheDir.py | 48 +- .../SCons/Conftest.py | 206 +++++- .../SCons/Debug.py | 68 +- .../SCons/Defaults.py | 141 ++-- .../SCons/Environment.py | 387 +++++++--- scons/scons-local-1.2.0/SCons/Errors.py | 198 ++++++ .../SCons/Executor.py | 128 ++-- .../SCons/Job.py | 225 ++++-- .../SCons/Memoize.py | 46 +- .../SCons/Node/Alias.py | 7 +- .../SCons/Node/FS.py | 529 ++++++++------ .../SCons/Node/Python.py | 9 +- .../SCons/Node/__init__.py | 257 ++++--- .../SCons/Options/BoolOption.py | 44 ++ .../SCons/Options/EnumOption.py | 44 ++ .../SCons/Options/ListOption.py | 44 ++ .../SCons/Options/PackageOption.py | 44 ++ .../SCons/Options/PathOption.py | 70 ++ .../SCons/Options/__init__.py | 68 ++ .../SCons/PathList.py | 13 +- .../SCons/Platform/__init__.py | 4 +- .../SCons/Platform/aix.py | 4 +- .../SCons/Platform/cygwin.py | 4 +- .../SCons/Platform/darwin.py | 4 +- .../SCons/Platform/hpux.py | 4 +- .../SCons/Platform/irix.py | 4 +- .../SCons/Platform/os2.py | 4 +- .../SCons/Platform/posix.py | 53 +- .../SCons/Platform/sunos.py | 4 +- .../SCons/Platform/win32.py | 4 +- .../SCons/SConf.py | 78 ++- .../SCons/SConsign.py | 6 +- scons/scons-local-1.2.0/SCons/Scanner/C.py | 126 ++++ .../SCons/Scanner/D.py | 27 +- .../SCons/Scanner/Dir.py | 4 +- .../SCons/Scanner/Fortran.py | 4 +- .../SCons/Scanner/IDL.py | 4 +- .../scons-local-1.2.0/SCons/Scanner/LaTeX.py | 334 +++++++++ .../SCons/Scanner/Prog.py | 8 +- .../SCons/Scanner/RC.py} | 31 +- .../SCons/Scanner/__init__.py | 11 +- .../SCons/Script/Interactive.py | 376 ++++++++++ .../SCons/Script/Main.py | 378 ++++++---- .../SCons/Script/SConsOptions.py | 162 +++-- .../SCons/Script/SConscript.py | 42 +- .../SCons/Script/__init__.py | 28 +- .../SCons/Sig.py | 4 +- .../SCons/Subst.py | 87 ++- .../SCons/Taskmaster.py | 553 +++++++++++---- .../SCons/Tool/386asm.py | 4 +- .../SCons/Tool/BitKeeper.py | 4 +- .../SCons/Tool/CVS.py | 4 +- .../SCons/Tool/FortranCommon.py | 241 +++++++ .../SCons/Tool/JavaCommon.py | 34 +- .../SCons/Tool/Perforce.py | 4 +- .../SCons/Tool/PharLapCommon.py | 4 +- .../SCons/Tool/RCS.py | 4 +- .../SCons/Tool/SCCS.py | 4 +- .../SCons/Tool/Subversion.py | 4 +- .../SCons/Tool/__init__.py | 146 ++-- .../SCons/Tool/aixc++.py | 4 +- .../SCons/Tool/aixcc.py | 4 +- .../SCons/Tool/aixf77.py | 4 +- .../SCons/Tool/aixlink.py | 4 +- .../SCons/Tool/applelink.py | 17 +- .../SCons/Tool/ar.py | 4 +- .../SCons/Tool/as.py | 6 +- .../SCons/Tool/bcc32.py | 4 +- .../SCons/Tool/c++.py | 12 +- .../SCons/Tool/cc.py | 4 +- .../SCons/Tool/cvf.py | 4 +- .../SCons/Tool/default.py | 4 +- .../SCons/Tool/dmd.py | 38 +- .../SCons/Tool/dvi.py | 4 +- .../SCons/Tool/dvipdf.py | 50 +- .../SCons/Tool/dvips.py | 28 +- scons/scons-local-1.2.0/SCons/Tool/f77.py | 56 ++ .../SCons/Tool/f90.py} | 27 +- scons/scons-local-1.2.0/SCons/Tool/f95.py | 57 ++ .../SCons/Tool/filesystem.py | 4 +- scons/scons-local-1.2.0/SCons/Tool/fortran.py | 57 ++ .../SCons/Tool/g++.py | 37 +- scons/scons-local-1.2.0/SCons/Tool/g77.py | 67 ++ .../SCons/Tool/gas.py | 4 +- .../SCons/Tool/gcc.py | 23 +- .../scons-local-1.2.0/SCons/Tool/gfortran.py | 58 ++ .../SCons/Tool/gnulink.py | 4 +- .../SCons/Tool/gs.py | 4 +- .../SCons/Tool/hpc++.py | 4 +- .../SCons/Tool/hpcc.py | 4 +- .../SCons/Tool/hplink.py | 4 +- .../SCons/Tool/icc.py | 4 +- .../SCons/Tool/icl.py | 4 +- .../SCons/Tool/ifl.py | 27 +- .../SCons/Tool/ifort.py | 52 +- .../SCons/Tool/ilink.py | 4 +- .../SCons/Tool/ilink32.py | 6 +- .../SCons/Tool/install.py | 29 +- .../SCons/Tool/intelc.py | 87 ++- .../SCons/Tool/jar.py | 29 +- .../SCons/Tool/javac.py | 14 +- .../SCons/Tool/javah.py | 4 +- .../SCons/Tool/latex.py | 19 +- .../SCons/Tool/lex.py | 4 +- .../SCons/Tool/link.py | 34 +- .../SCons/Tool/linkloc.py | 4 +- .../SCons/Tool/m4.py | 4 +- .../SCons/Tool/masm.py | 6 +- .../SCons/Tool/midl.py | 4 +- .../SCons/Tool/mingw.py | 5 +- .../SCons/Tool/mslib.py | 4 +- .../SCons/Tool/mslink.py | 52 +- .../SCons/Tool/msvc.py | 65 +- .../SCons/Tool/msvs.py | 77 +- .../SCons/Tool/mwcc.py | 4 +- .../SCons/Tool/mwld.py | 4 +- .../SCons/Tool/nasm.py | 6 +- .../SCons/Tool/packaging/__init__.py | 16 +- .../SCons/Tool/packaging/ipk.py | 4 +- .../SCons/Tool/packaging/msi.py | 4 +- .../SCons/Tool/packaging/rpm.py | 4 +- .../SCons/Tool/packaging/src_tarbz2.py | 4 +- .../SCons/Tool/packaging/src_targz.py | 4 +- .../SCons/Tool/packaging/src_zip.py | 4 +- .../SCons/Tool/packaging/tarbz2.py | 4 +- .../SCons/Tool/packaging/targz.py | 4 +- .../SCons/Tool/packaging/zip.py | 4 +- .../SCons/Tool/pdf.py | 23 +- .../SCons/Tool/pdflatex.py | 15 +- .../SCons/Tool/pdftex.py | 25 +- .../SCons/Tool/qt.py | 6 +- .../SCons/Tool/rmic.py | 10 +- .../SCons/Tool/rpcgen.py | 4 +- .../SCons/Tool/rpm.py | 17 +- .../SCons/Tool/sgiar.py | 4 +- .../SCons/Tool/sgic++.py | 4 +- .../SCons/Tool/sgicc.py | 4 +- .../SCons/Tool/sgilink.py | 4 +- .../SCons/Tool/sunar.py | 4 +- .../SCons/Tool/sunc++.py | 40 +- .../SCons/Tool/suncc.py | 4 +- scons/scons-local-1.2.0/SCons/Tool/sunf77.py | 57 ++ scons/scons-local-1.2.0/SCons/Tool/sunf90.py | 58 ++ scons/scons-local-1.2.0/SCons/Tool/sunf95.py | 58 ++ .../SCons/Tool/sunlink.py | 4 +- .../SCons/Tool/swig.py | 10 +- .../SCons/Tool/tar.py | 4 +- scons/scons-local-1.2.0/SCons/Tool/tex.py | 661 ++++++++++++++++++ .../SCons/Tool/tlib.py | 4 +- .../SCons/Tool/wix.py | 4 +- .../SCons/Tool/yacc.py | 16 +- .../SCons/Tool/zip.py | 4 +- .../SCons/Util.py | 508 ++++++++++---- .../SCons/Variables/BoolVariable.py} | 19 +- .../SCons/Variables/EnumVariable.py} | 18 +- .../SCons/Variables/ListVariable.py} | 20 +- .../SCons/Variables/PackageVariable.py} | 15 +- .../SCons/Variables/PathVariable.py} | 24 +- .../SCons/Variables}/__init__.py | 71 +- .../SCons/Warnings.py | 88 ++- .../SCons/__init__.py | 17 +- .../SCons/compat/__init__.py | 102 ++- .../SCons/compat/_scons_UserString.py | 4 +- .../SCons/compat/_scons_hashlib.py | 4 +- .../SCons/compat/_scons_itertools.py | 118 ++++ .../SCons/compat/_scons_optparse.py | 0 .../SCons/compat/_scons_sets.py | 0 .../SCons/compat/_scons_sets15.py | 13 +- .../SCons/compat/_scons_shlex.py | 319 +++++++++ .../SCons/compat/_scons_subprocess.py | 6 +- .../SCons/compat/_scons_textwrap.py | 17 +- .../SCons/compat/builtins.py | 10 +- .../SCons/cpp.py | 82 ++- .../SCons/dblite.py | 41 +- .../SCons/exitfuncs.py | 4 +- scons/scons-time.py | 74 +- scons/scons.py | 40 +- scons/sconsign.py | 37 +- 191 files changed, 7866 insertions(+), 3194 deletions(-) delete mode 100644 scons/scons-local-0.97.0d20071212/SCons/Errors.py delete mode 100644 scons/scons-local-0.97.0d20071212/SCons/Scanner/LaTeX.py delete mode 100644 scons/scons-local-0.97.0d20071212/SCons/Tool/f77.py delete mode 100644 scons/scons-local-0.97.0d20071212/SCons/Tool/f90.py delete mode 100644 scons/scons-local-0.97.0d20071212/SCons/Tool/f95.py delete mode 100644 scons/scons-local-0.97.0d20071212/SCons/Tool/fortran.py delete mode 100644 scons/scons-local-0.97.0d20071212/SCons/Tool/tex.py delete mode 100644 scons/scons-local-0.97.0d20071212/scons-0.97.0d20071212.egg-info rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Action.py (61%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Builder.py (98%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/CacheDir.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Conftest.py (78%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Debug.py (79%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Defaults.py (79%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Environment.py (86%) create mode 100644 scons/scons-local-1.2.0/SCons/Errors.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Executor.py (78%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Job.py (58%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Memoize.py (90%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Node/Alias.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Node/FS.py (87%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Node/Python.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Node/__init__.py (88%) create mode 100644 scons/scons-local-1.2.0/SCons/Options/BoolOption.py create mode 100644 scons/scons-local-1.2.0/SCons/Options/EnumOption.py create mode 100644 scons/scons-local-1.2.0/SCons/Options/ListOption.py create mode 100644 scons/scons-local-1.2.0/SCons/Options/PackageOption.py create mode 100644 scons/scons-local-1.2.0/SCons/Options/PathOption.py create mode 100644 scons/scons-local-1.2.0/SCons/Options/__init__.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/PathList.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/__init__.py (98%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/aix.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/cygwin.py (91%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/darwin.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/hpux.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/irix.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/os2.py (91%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/posix.py (85%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/sunos.py (90%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Platform/win32.py (98%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/SConf.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/SConsign.py (98%) create mode 100644 scons/scons-local-1.2.0/SCons/Scanner/C.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Scanner/D.py (66%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Scanner/Dir.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Scanner/Fortran.py (98%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Scanner/IDL.py (90%) create mode 100644 scons/scons-local-1.2.0/SCons/Scanner/LaTeX.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Scanner/Prog.py (93%) rename scons/{scons-local-0.97.0d20071212/SCons/Scanner/C.py => scons-local-1.2.0/SCons/Scanner/RC.py} (57%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Scanner/__init__.py (97%) create mode 100644 scons/scons-local-1.2.0/SCons/Script/Interactive.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Script/Main.py (80%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Script/SConsOptions.py (87%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Script/SConscript.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Script/__init__.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Sig.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Subst.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Taskmaster.py (50%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/386asm.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/BitKeeper.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/CVS.py (93%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/FortranCommon.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/JavaCommon.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/Perforce.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/PharLapCommon.py (96%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/RCS.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/SCCS.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/Subversion.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/__init__.py (84%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/aixc++.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/aixcc.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/aixf77.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/aixlink.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/applelink.py (84%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/ar.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/as.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/bcc32.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/c++.py (88%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/cc.py (96%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/cvf.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/default.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/dmd.py (87%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/dvi.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/dvipdf.py (62%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/dvips.py (71%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/f77.py rename scons/{scons-local-0.97.0d20071212/SCons/Tool/g77.py => scons-local-1.2.0/SCons/Tool/f90.py} (67%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/f95.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/filesystem.py (94%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/fortran.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/g++.py (67%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/g77.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/gas.py (90%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/gcc.py (69%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/gfortran.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/gnulink.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/gs.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/hpc++.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/hpcc.py (90%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/hplink.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/icc.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/icl.py (91%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/ifl.py (71%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/ifort.py (57%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/ilink.py (91%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/ilink32.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/install.py (88%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/intelc.py (83%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/jar.py (79%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/javac.py (96%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/javah.py (96%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/latex.py (76%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/lex.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/link.py (72%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/linkloc.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/m4.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/masm.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/midl.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/mingw.py (96%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/mslib.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/mslink.py (86%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/msvc.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/msvs.py (96%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/mwcc.py (97%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/mwld.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/nasm.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/__init__.py (96%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/ipk.py (97%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/msi.py (99%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/rpm.py (98%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/src_tarbz2.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/src_targz.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/src_zip.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/tarbz2.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/targz.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/packaging/zip.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/pdf.py (69%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/pdflatex.py (80%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/pdftex.py (77%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/qt.py (98%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/rmic.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/rpcgen.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/rpm.py (89%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/sgiar.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/sgic++.py (91%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/sgicc.py (90%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/sgilink.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/sunar.py (93%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/sunc++.py (70%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/suncc.py (91%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/sunf77.py create mode 100644 scons/scons-local-1.2.0/SCons/Tool/sunf90.py create mode 100644 scons/scons-local-1.2.0/SCons/Tool/sunf95.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/sunlink.py (92%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/swig.py (91%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/tar.py (93%) create mode 100644 scons/scons-local-1.2.0/SCons/Tool/tex.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/tlib.py (90%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/wix.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/yacc.py (85%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Tool/zip.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Util.py (71%) rename scons/{scons-local-0.97.0d20071212/SCons/Options/BoolOption.py => scons-local-1.2.0/SCons/Variables/BoolVariable.py} (83%) rename scons/{scons-local-0.97.0d20071212/SCons/Options/EnumOption.py => scons-local-1.2.0/SCons/Variables/EnumVariable.py} (86%) rename scons/{scons-local-0.97.0d20071212/SCons/Options/ListOption.py => scons-local-1.2.0/SCons/Variables/ListVariable.py} (89%) rename scons/{scons-local-0.97.0d20071212/SCons/Options/PackageOption.py => scons-local-1.2.0/SCons/Variables/PackageVariable.py} (89%) rename scons/{scons-local-0.97.0d20071212/SCons/Options/PathOption.py => scons-local-1.2.0/SCons/Variables/PathVariable.py} (91%) rename scons/{scons-local-0.97.0d20071212/SCons/Options => scons-local-1.2.0/SCons/Variables}/__init__.py (82%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/Warnings.py (55%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/__init__.py (76%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/__init__.py (70%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/_scons_UserString.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/_scons_hashlib.py (93%) create mode 100644 scons/scons-local-1.2.0/SCons/compat/_scons_itertools.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/_scons_optparse.py (100%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/_scons_sets.py (100%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/_scons_sets15.py (93%) create mode 100644 scons/scons-local-1.2.0/SCons/compat/_scons_shlex.py rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/_scons_subprocess.py (99%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/_scons_textwrap.py (95%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/compat/builtins.py (94%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/cpp.py (88%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/dblite.py (81%) rename scons/{scons-local-0.97.0d20071212 => scons-local-1.2.0}/SCons/exitfuncs.py (92%) diff --git a/SConstruct b/SConstruct index dc812d009..ce8838054 100644 --- a/SConstruct +++ b/SConstruct @@ -33,38 +33,38 @@ else: # All of the following options may be modified at the command-line, for example: # `python scons/scons PREFIX=/opt` -opts = Options('config.py') +opts = Variables('config.py') opts.Add('CXX', 'The C++ compiler to use (defaults to g++).', 'g++') opts.Add('PREFIX', 'The install path "prefix"', '/usr/local') -opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include')) -opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include')) +opts.Add(PathVariable('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA)) opts.Add('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False) opts.Add('BOOST_ABI', 'Specify boost ABI, e.g., d.','',False) opts.Add('BOOST_VERSION','Specify boost version, e.g., 1_35.','',False) opts.Add(('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config')) opts.Add(('XML2_CONFIG', 'The path to the xml2-config executable.', 'xml2-config')) -opts.Add(PathOption('ICU_INCLUDES', 'Search path for ICU include files', '/usr/include')) -opts.Add(PathOption('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA)) -opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include')) -opts.Add(PathOption('PNG_LIBS','Search path for libpng include files','/usr/' + LIBDIR_SCHEMA)) -opts.Add(PathOption('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include')) -opts.Add(PathOption('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/' + LIBDIR_SCHEMA)) -opts.Add(PathOption('TIFF_INCLUDES', 'Search path for libtiff include files', '/usr/include')) -opts.Add(PathOption('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA)) -opts.Add(PathOption('PGSQL_INCLUDES', 'Search path for PostgreSQL include files', '/usr/include')) -opts.Add(PathOption('PGSQL_LIBS', 'Search path for PostgreSQL library files', '/usr/' + LIBDIR_SCHEMA)) -opts.Add(PathOption('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/local/include')) -opts.Add(PathOption('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/local/' + LIBDIR_SCHEMA)) -opts.Add(PathOption('GDAL_INCLUDES', 'Search path for GDAL include files', '/usr/include')) -opts.Add(PathOption('GDAL_LIBS', 'Search path for GDAL library files', '/usr/' + LIBDIR_SCHEMA)) -opts.Add(PathOption('PYTHON','Python executable', sys.executable)) -opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal'])) -opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python'])) -opts.Add(BoolOption('DEBUG', 'Compile a debug version of mapnik', 'False')) +opts.Add(PathVariable('ICU_INCLUDES', 'Search path for ICU include files', '/usr/include')) +opts.Add(PathVariable('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include')) +opts.Add(PathVariable('PNG_LIBS','Search path for libpng include files','/usr/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include')) +opts.Add(PathVariable('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('TIFF_INCLUDES', 'Search path for libtiff include files', '/usr/include')) +opts.Add(PathVariable('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('PGSQL_INCLUDES', 'Search path for PostgreSQL include files', '/usr/include')) +opts.Add(PathVariable('PGSQL_LIBS', 'Search path for PostgreSQL library files', '/usr/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/local/include')) +opts.Add(PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/local/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('GDAL_INCLUDES', 'Search path for GDAL include files', '/usr/include')) +opts.Add(PathVariable('GDAL_LIBS', 'Search path for GDAL library files', '/usr/' + LIBDIR_SCHEMA)) +opts.Add(PathVariable('PYTHON','Python executable', sys.executable)) +opts.Add(ListVariable('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal'])) +opts.Add(ListVariable('BINDINGS','Language bindings to build','all',['python'])) +opts.Add(BoolVariable('DEBUG', 'Compile a debug version of mapnik', 'False')) opts.Add('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/') -opts.Add(EnumOption('THREADING','Set threading support','multi', ['multi','single'])) -opts.Add(EnumOption('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit','libxml2'])) -opts.Add(BoolOption('INTERNAL_LIBAGG', 'Use provided libagg', 'True')) +opts.Add(EnumVariable('THREADING','Set threading support','multi', ['multi','single'])) +opts.Add(EnumVariable('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit','libxml2'])) +opts.Add(BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True')) env = Environment(ENV=os.environ, options=opts) diff --git a/scons/scons-LICENSE b/scons/scons-LICENSE index 184b82e5d..804ed8682 100644 --- a/scons/scons-LICENSE +++ b/scons/scons-LICENSE @@ -3,7 +3,7 @@ This copyright and license do not apply to any other software with which this software may have been included. -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/scons/scons-README b/scons/scons-README index 97fc5f436..298a22168 100644 --- a/scons/scons-README +++ b/scons/scons-README @@ -1,4 +1,4 @@ -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation SCons - a software construction tool diff --git a/scons/scons-local-0.97.0d20071212/SCons/Errors.py b/scons/scons-local-0.97.0d20071212/SCons/Errors.py deleted file mode 100644 index 428213663..000000000 --- a/scons/scons-local-0.97.0d20071212/SCons/Errors.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -"""SCons.Errors - -This file contains the exception classes used to handle internal -and user errors in SCons. - -""" - -__revision__ = "src/engine/SCons/Errors.py 2523 2007/12/12 09:37:41 knight" - - - -class BuildError(Exception): - def __init__(self, node=None, errstr="Unknown error", status=0, - filename=None, executor=None, action=None, command=None, - *args): - self.node = node - self.errstr = errstr - self.status = status - self.filename = filename - self.executor = executor - self.action = action - self.command = command - apply(Exception.__init__, (self,) + args) - -class InternalError(Exception): - pass - -class UserError(Exception): - pass - -class StopError(Exception): - pass - -class EnvironmentError(Exception): - pass - -class ExplicitExit(Exception): - def __init__(self, node=None, status=None, *args): - self.node = node - self.status = status - apply(Exception.__init__, (self,) + args) - -class TaskmasterException(Exception): - def __init__(self, node=None, exc_info=(None, None, None), *args): - self.node = node - self.errstr = "Exception" - self.exc_info = exc_info - apply(Exception.__init__, (self,) + args) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/LaTeX.py b/scons/scons-local-0.97.0d20071212/SCons/Scanner/LaTeX.py deleted file mode 100644 index 59a88a27f..000000000 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/LaTeX.py +++ /dev/null @@ -1,126 +0,0 @@ -"""SCons.Scanner.LaTeX - -This module implements the dependency scanner for LaTeX code. - -""" - -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "src/engine/SCons/Scanner/LaTeX.py 2523 2007/12/12 09:37:41 knight" - -import os.path -import string - -import SCons.Scanner - -def LaTeXScanner(): - """Return a prototype Scanner instance for scanning LaTeX source files""" - ds = LaTeX(name = "LaTeXScanner", - suffixes = '$LATEXSUFFIXES', - path_variable = 'TEXINPUTS', - regex = '\\\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography|usepackage){([^}]*)}', - recursive = 0) - return ds - -class LaTeX(SCons.Scanner.Classic): - """Class for scanning LaTeX files for included files. - - Unlike most scanners, which use regular expressions that just - return the included file name, this returns a tuple consisting - of the keyword for the inclusion ("include", "includegraphics", - "input", or "bibliography"), and then the file name itself. - Based on a quick look at LaTeX documentation, it seems that we - need a should append .tex suffix for the "include" keywords, - append .tex if there is no extension for the "input" keyword, - but leave the file name untouched for "includegraphics." For - the "bibliography" keyword we need to add .bib if there is - no extension. (This need to be revisited since if there - is no extension for an :includegraphics" keyword latex will - append .ps or .eps to find the file; while pdftex will use - other extensions.) - """ - def latex_name(self, include): - filename = include[1] - if include[0] == 'input': - base, ext = os.path.splitext( filename ) - if ext == "": - filename = filename + '.tex' - if (include[0] == 'include'): - filename = filename + '.tex' - if include[0] == 'bibliography': - base, ext = os.path.splitext( filename ) - if ext == "": - filename = filename + '.bib' - if include[0] == 'usepackage': - base, ext = os.path.splitext( filename ) - if ext == "": - filename = filename + '.sty' - return filename - def sort_key(self, include): - return SCons.Node.FS._my_normcase(self.latex_name(include)) - def find_include(self, include, source_dir, path): - i = SCons.Node.FS.find_file(self.latex_name(include), - (source_dir,) + path) - return i, include - - def scan(self, node, path=()): - # - # Modify the default scan function to allow for the regular - # expression to return a comma separated list of file names - # as can be the case with the bibliography keyword. - # - # cache the includes list in node so we only scan it once: - if node.includes != None: - includes = node.includes - else: - includes = self.cre.findall(node.get_contents()) - node.includes = includes - - # This is a hand-coded DSU (decorate-sort-undecorate, or - # Schwartzian transform) pattern. The sort key is the raw name - # of the file as specifed on the #include line (including the - # " or <, since that may affect what file is found), which lets - # us keep the sort order constant regardless of whether the file - # is actually found in a Repository or locally. - nodes = [] - source_dir = node.get_dir() - for include in includes: - # - # Handle multiple filenames in include[1] - # - inc_list = string.split(include[1],',') - for j in range(len(inc_list)): - include_local = [include[0],inc_list[j]] - n, i = self.find_include(include_local, source_dir, path) - - if n is None: - SCons.Warnings.warn(SCons.Warnings.DependencyWarning, - "No dependency generated for file: %s (included from: %s) -- file not found" % (i, node)) - else: - sortkey = self.sort_key(include) - nodes.append((sortkey, n)) - - nodes.sort() - nodes = map(lambda pair: pair[1], nodes) - return nodes diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/f77.py b/scons/scons-local-0.97.0d20071212/SCons/Tool/f77.py deleted file mode 100644 index aff2681ff..000000000 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/f77.py +++ /dev/null @@ -1,135 +0,0 @@ -"""engine.SCons.Tool.f77 - -Tool-specific initialization for the generic Posix f77 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "src/engine/SCons/Tool/f77.py 2523 2007/12/12 09:37:41 knight" - -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util -import fortran - -compilers = ['f77'] - -# -F77Suffixes = ['.f77'] -F77PPSuffixes = [] -if SCons.Util.case_sensitive_suffixes('.f77', '.F77'): - F77PPSuffixes.append('.F77') -else: - F77Suffixes.append('.F77') - -# -F77Scan = SCons.Scanner.Fortran.FortranScan("F77PATH") - -for suffix in F77Suffixes + F77PPSuffixes: - SCons.Tool.SourceFileScanner.add_scanner(suffix, F77Scan) -del suffix - -# -fVLG = fortran.VariableListGenerator - -F77Generator = fVLG('F77', 'FORTRAN', '_FORTRAND') -F77FlagsGenerator = fVLG('F77FLAGS', 'FORTRANFLAGS') -F77CommandGenerator = fVLG('F77COM', 'FORTRANCOM', '_F77COMD') -F77CommandStrGenerator = fVLG('F77COMSTR', 'FORTRANCOMSTR', '_F77COMSTRD') -F77PPCommandGenerator = fVLG('F77PPCOM', 'FORTRANPPCOM', '_F77PPCOMD') -F77PPCommandStrGenerator = fVLG('F77PPCOMSTR', 'FORTRANPPCOMSTR', '_F77PPCOMSTRD') -ShF77Generator = fVLG('SHF77', 'SHFORTRAN', 'F77', 'FORTRAN', '_FORTRAND') -ShF77FlagsGenerator = fVLG('SHF77FLAGS', 'SHFORTRANFLAGS') -ShF77CommandGenerator = fVLG('SHF77COM', 'SHFORTRANCOM', '_SHF77COMD') -ShF77CommandStrGenerator = fVLG('SHF77COMSTR', 'SHFORTRANCOMSTR', '_SHF77COMSTRD') -ShF77PPCommandGenerator = fVLG('SHF77PPCOM', 'SHFORTRANPPCOM', '_SHF77PPCOMD') -ShF77PPCommandStrGenerator = fVLG('SHF77PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF77PPCOMSTRD') - -del fVLG - -# -F77Action = SCons.Action.Action('$_F77COMG ', '$_F77COMSTRG') -F77PPAction = SCons.Action.Action('$_F77PPCOMG ', '$_F77PPCOMSTRG') -ShF77Action = SCons.Action.Action('$_SHF77COMG ', '$_SHF77COMSTRG') -ShF77PPAction = SCons.Action.Action('$_SHF77PPCOMG ', '$_SHF77PPCOMSTRG') - -def add_to_env(env): - """Add Builders and construction variables for f77 to an Environment.""" - env.AppendUnique(FORTRANSUFFIXES = F77Suffixes + F77PPSuffixes) - - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in F77Suffixes: - static_obj.add_action(suffix, F77Action) - shared_obj.add_action(suffix, ShF77Action) - static_obj.add_emitter(suffix, fortran.FortranEmitter) - shared_obj.add_emitter(suffix, fortran.ShFortranEmitter) - - for suffix in F77PPSuffixes: - static_obj.add_action(suffix, F77PPAction) - shared_obj.add_action(suffix, ShF77PPAction) - static_obj.add_emitter(suffix, fortran.FortranEmitter) - shared_obj.add_emitter(suffix, fortran.ShFortranEmitter) - - env['_F77G'] = F77Generator - env['_F77FLAGSG'] = F77FlagsGenerator - env['_F77COMG'] = F77CommandGenerator - env['_F77PPCOMG'] = F77PPCommandGenerator - env['_F77COMSTRG'] = F77CommandStrGenerator - env['_F77PPCOMSTRG'] = F77PPCommandStrGenerator - - env['_SHF77G'] = ShF77Generator - env['_SHF77FLAGSG'] = ShF77FlagsGenerator - env['_SHF77COMG'] = ShF77CommandGenerator - env['_SHF77PPCOMG'] = ShF77PPCommandGenerator - env['_SHF77COMSTRG'] = ShF77CommandStrGenerator - env['_SHF77PPCOMSTRG'] = ShF77PPCommandStrGenerator - - env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - - env['_F77COMD'] = '$_F77G -o $TARGET -c $_F77FLAGSG $_F77INCFLAGS $SOURCES' - env['_F77PPCOMD'] = '$_F77G -o $TARGET -c $_F77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS $SOURCES' - env['_SHF77COMD'] = '$_SHF77G -o $TARGET -c $_SHF77FLAGSG $_F77INCFLAGS $SOURCES' - env['_SHF77PPCOMD'] = '$_SHF77G -o $TARGET -c $_SHF77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS $SOURCES' - -def generate(env): - fortran.add_to_env(env) - - import f90 - import f95 - f90.add_to_env(env) - f95.add_to_env(env) - - add_to_env(env) - - env['_FORTRAND'] = env.Detect(compilers) or 'f77' - -def exists(env): - return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/f90.py b/scons/scons-local-0.97.0d20071212/SCons/Tool/f90.py deleted file mode 100644 index d4a154c3d..000000000 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/f90.py +++ /dev/null @@ -1,132 +0,0 @@ -"""engine.SCons.Tool.f90 - -Tool-specific initialization for the generic Posix f90 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "src/engine/SCons/Tool/f90.py 2523 2007/12/12 09:37:41 knight" - -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util -import fortran - -compilers = ['f90'] - -# -F90Suffixes = ['.f90'] -F90PPSuffixes = [] -if SCons.Util.case_sensitive_suffixes('.f90', '.F90'): - F90PPSuffixes.append('.F90') -else: - F90Suffixes.append('.F90') - -# -F90Scan = SCons.Scanner.Fortran.FortranScan("F90PATH") - -for suffix in F90Suffixes + F90PPSuffixes: - SCons.Tool.SourceFileScanner.add_scanner(suffix, F90Scan) -del suffix - -# -fVLG = fortran.VariableListGenerator - -F90Generator = fVLG('F90', 'FORTRAN', '_FORTRAND') -F90FlagsGenerator = fVLG('F90FLAGS', 'FORTRANFLAGS') -F90CommandGenerator = fVLG('F90COM', 'FORTRANCOM', '_F90COMD') -F90CommandStrGenerator = fVLG('F90COMSTR', 'FORTRANCOMSTR', '_F90COMSTRD') -F90PPCommandGenerator = fVLG('F90PPCOM', 'FORTRANPPCOM', '_F90PPCOMD') -F90PPCommandStrGenerator = fVLG('F90PPCOMSTR', 'FORTRANPPCOMSTR', '_F90PPCOMSTRD') -ShF90Generator = fVLG('SHF90', 'SHFORTRAN', 'F90', 'FORTRAN', '_FORTRAND') -ShF90FlagsGenerator = fVLG('SHF90FLAGS', 'SHFORTRANFLAGS') -ShF90CommandGenerator = fVLG('SHF90COM', 'SHFORTRANCOM', '_SHF90COMD') -ShF90CommandStrGenerator = fVLG('SHF90COMSTR', 'SHFORTRANCOMSTR', '_SHF90COMSTRD') -ShF90PPCommandGenerator = fVLG('SHF90PPCOM', 'SHFORTRANPPCOM', '_SHF90PPCOMD') -ShF90PPCommandStrGenerator = fVLG('SHF90PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF90PPCOMSTRD') - -del fVLG - -# -F90Action = SCons.Action.Action('$_F90COMG ', '$_F90COMSTRG') -F90PPAction = SCons.Action.Action('$_F90PPCOMG ', '$_F90PPCOMSTRG') -ShF90Action = SCons.Action.Action('$_SHF90COMG ', '$_SHF90COMSTRG') -ShF90PPAction = SCons.Action.Action('$_SHF90PPCOMG ', '$_SHF90PPCOMSTRG') - -def add_to_env(env): - """Add Builders and construction variables for f90 to an Environment.""" - env.AppendUnique(FORTRANSUFFIXES = F90Suffixes + F90PPSuffixes) - - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in F90Suffixes: - static_obj.add_action(suffix, F90Action) - shared_obj.add_action(suffix, ShF90Action) - static_obj.add_emitter(suffix, fortran.FortranEmitter) - shared_obj.add_emitter(suffix, fortran.ShFortranEmitter) - - for suffix in F90PPSuffixes: - static_obj.add_action(suffix, F90PPAction) - shared_obj.add_action(suffix, ShF90PPAction) - static_obj.add_emitter(suffix, fortran.FortranEmitter) - shared_obj.add_emitter(suffix, fortran.ShFortranEmitter) - - env['_F90G'] = F90Generator - env['_F90FLAGSG'] = F90FlagsGenerator - env['_F90COMG'] = F90CommandGenerator - env['_F90COMSTRG'] = F90CommandStrGenerator - env['_F90PPCOMG'] = F90PPCommandGenerator - env['_F90PPCOMSTRG'] = F90PPCommandStrGenerator - - env['_SHF90G'] = ShF90Generator - env['_SHF90FLAGSG'] = ShF90FlagsGenerator - env['_SHF90COMG'] = ShF90CommandGenerator - env['_SHF90COMSTRG'] = ShF90CommandStrGenerator - env['_SHF90PPCOMG'] = ShF90PPCommandGenerator - env['_SHF90PPCOMSTRG'] = ShF90PPCommandStrGenerator - - env['_F90INCFLAGS'] = '$( ${_concat(INCPREFIX, F90PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - env['_F90COMD'] = '$_F90G -o $TARGET -c $_F90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_F90PPCOMD'] = '$_F90G -o $TARGET -c $_F90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_SHF90COMD'] = '$_SHF90G -o $TARGET -c $_SHF90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_SHF90PPCOMD'] = '$_SHF90G -o $TARGET -c $_SHF90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES' - -def generate(env): - fortran.add_to_env(env) - - import f77 - f77.add_to_env(env) - - add_to_env(env) - - env['_FORTRAND'] = env.Detect(compilers) or 'f90' - -def exists(env): - return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/f95.py b/scons/scons-local-0.97.0d20071212/SCons/Tool/f95.py deleted file mode 100644 index 3a3e3e472..000000000 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/f95.py +++ /dev/null @@ -1,135 +0,0 @@ -"""engine.SCons.Tool.f95 - -Tool-specific initialization for the generic Posix f95 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "src/engine/SCons/Tool/f95.py 2523 2007/12/12 09:37:41 knight" - -import SCons.Defaults -import SCons.Tool -import SCons.Util -import fortran - -compilers = ['f95'] - -# -F95Suffixes = ['.f95'] -F95PPSuffixes = [] -if SCons.Util.case_sensitive_suffixes('.f95', '.F95'): - F95PPSuffixes.append('.F95') -else: - F95Suffixes.append('.F95') - -# -F95Scan = SCons.Scanner.Fortran.FortranScan("F95PATH") - -for suffix in F95Suffixes + F95PPSuffixes: - SCons.Tool.SourceFileScanner.add_scanner(suffix, F95Scan) -del suffix - -# -fVLG = fortran.VariableListGenerator - -F95Generator = fVLG('F95', 'FORTRAN', '_FORTRAND') -F95FlagsGenerator = fVLG('F95FLAGS', 'FORTRANFLAGS') -F95CommandGenerator = fVLG('F95COM', 'FORTRANCOM', '_F95COMD') -F95CommandStrGenerator = fVLG('F95COMSTR', 'FORTRANCOMSTR', '_F95COMSTRD') -F95PPCommandGenerator = fVLG('F95PPCOM', 'FORTRANPPCOM', '_F95PPCOMD') -F95PPCommandStrGenerator = fVLG('F95PPCOMSTR', 'FORTRANPPCOMSTR', '_F95PPCOMSTRD') -ShF95Generator = fVLG('SHF95', 'SHFORTRAN', 'F95', 'FORTRAN', '_FORTRAND') -ShF95FlagsGenerator = fVLG('SHF95FLAGS', 'SHFORTRANFLAGS') -ShF95CommandGenerator = fVLG('SHF95COM', 'SHFORTRANCOM', '_SHF95COMD') -ShF95CommandStrGenerator = fVLG('SHF95COMSTR', 'SHFORTRANCOMSTR', '_SHF95COMSTRD') -ShF95PPCommandGenerator = fVLG('SHF95PPCOM', 'SHFORTRANPPCOM', '_SHF95PPCOMD') -ShF95PPCommandStrGenerator = fVLG('SHF95PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF95PPCOMSTRD') - -del fVLG - -# -F95Action = SCons.Action.Action('$_F95COMG ', '$_F95COMSTRG') -F95PPAction = SCons.Action.Action('$_F95PPCOMG ', '$_F95PPCOMSTRG') -ShF95Action = SCons.Action.Action('$_SHF95COMG ', '$_SHF95COMSTRG') -ShF95PPAction = SCons.Action.Action('$_SHF95PPCOMG ', '$_SHF95PPCOMSTRG') - -def add_to_env(env): - """Add Builders and construction variables for f95 to an Environment.""" - env.AppendUnique(FORTRANSUFFIXES = F95Suffixes + F95PPSuffixes) - - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in F95Suffixes: - static_obj.add_action(suffix, F95Action) - shared_obj.add_action(suffix, ShF95Action) - static_obj.add_emitter(suffix, fortran.FortranEmitter) - shared_obj.add_emitter(suffix, fortran.ShFortranEmitter) - - for suffix in F95PPSuffixes: - static_obj.add_action(suffix, F95PPAction) - shared_obj.add_action(suffix, ShF95PPAction) - static_obj.add_emitter(suffix, fortran.FortranEmitter) - shared_obj.add_emitter(suffix, fortran.ShFortranEmitter) - - env['_F95G'] = F95Generator - env['_F95FLAGSG'] = F95FlagsGenerator - env['_F95COMG'] = F95CommandGenerator - env['_F95COMSTRG'] = F95CommandStrGenerator - env['_F95PPCOMG'] = F95PPCommandGenerator - env['_F95PPCOMSTRG'] = F95PPCommandStrGenerator - - env['_SHF95G'] = ShF95Generator - env['_SHF95FLAGSG'] = ShF95FlagsGenerator - env['_SHF95COMG'] = ShF95CommandGenerator - env['_SHF95COMSTRG'] = ShF95CommandStrGenerator - env['_SHF95PPCOMG'] = ShF95PPCommandGenerator - env['_SHF95PPCOMSTRG'] = ShF95PPCommandStrGenerator - - env['_F95INCFLAGS'] = '$( ${_concat(INCPREFIX, F95PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - - env['_F95COMD'] = '$_F95G -o $TARGET -c $_F95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_F95PPCOMD'] = '$_F95G -o $TARGET -c $_F95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_SHF95COMD'] = '$_SHF95G -o $TARGET -c $_SHF95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_SHF95PPCOMD'] = '$_SHF95G -o $TARGET -c $_SHF95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES' - -def generate(env): - fortran.add_to_env(env) - - import f77 - f77.add_to_env(env) - - import f90 - f90.add_to_env(env) - - add_to_env(env) - - env['_FORTRAND'] = env.Detect(compilers) or 'f95' - -def exists(env): - return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/fortran.py b/scons/scons-local-0.97.0d20071212/SCons/Tool/fortran.py deleted file mode 100644 index 33c135df2..000000000 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/fortran.py +++ /dev/null @@ -1,186 +0,0 @@ -"""SCons.Tool.fortran - -Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "src/engine/SCons/Tool/fortran.py 2523 2007/12/12 09:37:41 knight" - -import re -import string - -import SCons.Action -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util - -compilers = ['f95', 'f90', 'f77'] - -# -# Not yet sure how to deal with fortran pre-processor functions. -# Different compilers do this differently in modern fortran. Some still -# rely on the c pre-processor, some (like cvf, ivf) have their own -# pre-processor technology and use intermediary suffixes (.i90) -# -FortranSuffixes = [".f", ".for", ".ftn", ] -FortranPPSuffixes = ['.fpp', '.FPP'] -upper_case = [".F", ".FOR", ".FTN"] -if SCons.Util.case_sensitive_suffixes('.f', '.F'): - FortranPPSuffixes.extend(upper_case) -else: - FortranSuffixes.extend(upper_case) - -# -FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH") - -for suffix in FortranSuffixes + FortranPPSuffixes: - SCons.Tool.SourceFileScanner.add_scanner(suffix, FortranScan) -del suffix - -# -def _fortranEmitter(target, source, env): - node = source[0].rfile() - if not node.exists() and not node.is_derived(): - print "Could not locate " + str(node.name) - return ([], []) - mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)""" - cre = re.compile(mod_regex,re.M) - # Retrieve all USE'd module names - modules = cre.findall(node.get_contents()) - # Remove unique items from the list - modules = SCons.Util.unique(modules) - # Convert module name to a .mod filename - suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source) - moddir = env.subst('$FORTRANMODDIR', target=target, source=source) - modules = map(lambda x, s=suffix: string.lower(x) + s, modules) - for m in modules: - target.append(env.fs.File(m, moddir)) - return (target, source) - -def FortranEmitter(target, source, env): - target, source = _fortranEmitter(target, source, env) - return SCons.Defaults.StaticObjectEmitter(target, source, env) - -def ShFortranEmitter(target, source, env): - target, source = _fortranEmitter(target, source, env) - return SCons.Defaults.SharedObjectEmitter(target, source, env) - -class VariableListGenerator: - def __init__(self, *variablelist): - self.variablelist = variablelist - def __call__(self, env, target, source, for_signature=0): - for v in self.variablelist: - try: return env[v] - except KeyError: pass - return '' - -# -FortranGenerator = VariableListGenerator('FORTRAN', 'F77', '_FORTRAND') -FortranFlagsGenerator = VariableListGenerator('FORTRANFLAGS', 'F77FLAGS') -FortranCommandGenerator = VariableListGenerator('FORTRANCOM', 'F77COM', '_FORTRANCOMD') -FortranCommandStrGenerator = VariableListGenerator('FORTRANCOMSTR', 'F77COMSTR', '_FORTRANCOMSTRD') -FortranPPCommandGenerator = VariableListGenerator('FORTRANPPCOM', 'F77PPCOM', '_FORTRANPPCOMD') -FortranPPCommandStrGenerator = VariableListGenerator('FORTRANPPCOMSTR', 'F77PPCOMSTR', '_FORTRANPPCOMSTRD') -ShFortranGenerator = VariableListGenerator('SHFORTRAN', 'SHF77', 'FORTRAN', 'F77', '_FORTRAND') -ShFortranFlagsGenerator = VariableListGenerator('SHFORTRANFLAGS', 'SHF77FLAGS') -ShFortranCommandGenerator = VariableListGenerator('SHFORTRANCOM', 'SHF77COM', '_SHFORTRANCOMD') -ShFortranCommandStrGenerator = VariableListGenerator('SHFORTRANCOMSTR', 'SHF77COMSTR', '_SHFORTRANCOMSTRD') -ShFortranPPCommandGenerator = VariableListGenerator('SHFORTRANPPCOM', 'SHF77PPCOM', '_SHFORTRANPPCOMD') -ShFortranPPCommandStrGenerator = VariableListGenerator('SHFORTRANPPCOMSTR', 'SHF77PPCOMSTR', '_SHFORTRANPPCOMSTRD') - -# -FortranAction = SCons.Action.Action('$_FORTRANCOMG ', '$_FORTRANCOMSTRG') -FortranPPAction = SCons.Action.Action('$_FORTRANPPCOMG ', '$_FORTRANPPCOMSTRG') -ShFortranAction = SCons.Action.Action('$_SHFORTRANCOMG ', '$_SHFORTRANCOMSTRG') -ShFortranPPAction = SCons.Action.Action('$_SHFORTRANPPCOMG ', '$_SHFORTRANPPCOMSTRG') - -def add_to_env(env): - """Add Builders and construction variables for Fortran to an Environment.""" - - env['_FORTRANG'] = FortranGenerator - env['_FORTRANFLAGSG'] = FortranFlagsGenerator - env['_FORTRANCOMG'] = FortranCommandGenerator - env['_FORTRANCOMSTRG'] = FortranCommandStrGenerator - env['_FORTRANPPCOMG'] = FortranPPCommandGenerator - env['_FORTRANPPCOMSTRG'] = FortranPPCommandStrGenerator - - env['_SHFORTRANG'] = ShFortranGenerator - env['_SHFORTRANFLAGSG'] = ShFortranFlagsGenerator - env['_SHFORTRANCOMG'] = ShFortranCommandGenerator - env['_SHFORTRANCOMSTRG'] = ShFortranCommandStrGenerator - env['_SHFORTRANPPCOMG'] = ShFortranPPCommandGenerator - env['_SHFORTRANPPCOMSTRG'] = ShFortranPPCommandStrGenerator - - env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - - env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX - env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX - - env['FORTRANMODDIR'] = '' # where the compiler should place .mod files - env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX - env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX - env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)' - - env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes) - - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in FortranSuffixes: - static_obj.add_action(suffix, FortranAction) - shared_obj.add_action(suffix, ShFortranAction) - static_obj.add_emitter(suffix, FortranEmitter) - shared_obj.add_emitter(suffix, ShFortranEmitter) - - for suffix in FortranPPSuffixes: - static_obj.add_action(suffix, FortranPPAction) - shared_obj.add_action(suffix, ShFortranPPAction) - static_obj.add_emitter(suffix, FortranEmitter) - shared_obj.add_emitter(suffix, ShFortranEmitter) - - env['_FORTRANCOMD'] = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_FORTRANPPCOMD'] = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_SHFORTRANCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES' - env['_SHFORTRANPPCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES' - -def generate(env): - import f77 - import f90 - import f95 - f77.add_to_env(env) - f90.add_to_env(env) - f95.add_to_env(env) - - add_to_env(env) - - env['_FORTRAND'] = env.Detect(compilers) or 'f77' - -def exists(env): - return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/tex.py b/scons/scons-local-0.97.0d20071212/SCons/Tool/tex.py deleted file mode 100644 index 79e9750a6..000000000 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/tex.py +++ /dev/null @@ -1,268 +0,0 @@ -"""SCons.Tool.tex - -Tool-specific initialization for TeX. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "src/engine/SCons/Tool/tex.py 2523 2007/12/12 09:37:41 knight" - -import os.path -import re -import string - -import SCons.Action -import SCons.Node -import SCons.Node.FS -import SCons.Util - -warning_rerun_re = re.compile("^LaTeX Warning:.*Rerun", re.MULTILINE) - -rerun_citations_str = "^LaTeX Warning:.*\n.*Rerun to get citations correct" -rerun_citations_re = re.compile(rerun_citations_str, re.MULTILINE) - -undefined_references_str = '(^LaTeX Warning:.*undefined references)|(^Package \w+ Warning:.*undefined citations)' -undefined_references_re = re.compile(undefined_references_str, re.MULTILINE) - -openout_aux_re = re.compile(r"\\openout.*`(.*\.aux)'") -openout_re = re.compile(r"\\openout.*`(.*)'") - -makeindex_re = re.compile(r"^[^%]*\\makeindex", re.MULTILINE) -tableofcontents_re = re.compile(r"^[^%]*\\tableofcontents", re.MULTILINE) -bibliography_re = re.compile(r"^[^%]*\\bibliography", re.MULTILINE) - -# An Action sufficient to build any generic tex file. -TeXAction = None - -# An action to build a latex file. This action might be needed more -# than once if we are dealing with labels and bibtex. -LaTeXAction = None - -# An action to run BibTeX on a file. -BibTeXAction = None - -# An action to run MakeIndex on a file. -MakeIndexAction = None - -def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None): - """A builder for LaTeX files that checks the output in the aux file - and decides how many times to use LaTeXAction, and BibTeXAction.""" - - basename = SCons.Util.splitext(str(source[0]))[0] - basedir = os.path.split(str(source[0]))[0] - - # Notice that all the filenames are not prefixed with the basedir. - # That's because the *COM variables have the cd command in the prolog. - - bblfilename = basename + '.bbl' - bblContents = "" - if os.path.exists(bblfilename): - bblContents = open(bblfilename, "rb").read() - - idxfilename = basename + '.idx' - idxContents = "" - if os.path.exists(idxfilename): - idxContents = open(idxfilename, "rb").read() - - tocfilename = basename + '.toc' - tocContents = "" - if os.path.exists(tocfilename): - tocContents = open(tocfilename, "rb").read() - - # Run LaTeX once to generate a new aux file. - XXXLaTeXAction(target, source, env) - - # Decide if various things need to be run, or run again. We check - # for the existence of files before opening them--even ones like the - # aux file that TeX always creates--to make it possible to write tests - # with stubs that don't necessarily generate all of the same files. - - # Read the log file to find all .aux files - logfilename = basename + '.log' - auxfiles = [] - if os.path.exists(logfilename): - content = open(logfilename, "rb").read() - auxfiles = openout_aux_re.findall(content) - - # Now decide if bibtex will need to be run. - for auxfilename in auxfiles: - if os.path.exists(os.path.join(basedir, auxfilename)): - content = open(os.path.join(basedir, auxfilename), "rb").read() - if string.find(content, "bibdata") != -1: - bibfile = env.fs.File(basename) - BibTeXAction(bibfile, bibfile, env) - break - - must_rerun_latex = 0 - # Now decide if latex will need to be run again due to table of contents. - if os.path.exists(tocfilename) and tocContents != open(tocfilename, "rb").read(): - must_rerun_latex = 1 - - # Now decide if latex will need to be run again due to bibliography. - if os.path.exists(bblfilename) and bblContents != open(bblfilename, "rb").read(): - must_rerun_latex = 1 - - # Now decide if latex will need to be run again due to index. - if os.path.exists(idxfilename) and idxContents != open(idxfilename, "rb").read(): - # We must run makeindex - idxfile = env.fs.File(basename) - MakeIndexAction(idxfile, idxfile, env) - must_rerun_latex = 1 - - if must_rerun_latex == 1: - XXXLaTeXAction(target, source, env) - - # Now decide if latex needs to be run yet again to resolve warnings. - logfilename = basename + '.log' - for _ in range(int(env.subst('$LATEXRETRIES'))): - if not os.path.exists(logfilename): - break - content = open(logfilename, "rb").read() - if not warning_rerun_re.search(content) and \ - not rerun_citations_re.search(content) and \ - not undefined_references_re.search(content): - break - XXXLaTeXAction(target, source, env) - return 0 - -def LaTeXAuxAction(target = None, source= None, env=None): - InternalLaTeXAuxAction( LaTeXAction, target, source, env ) - -LaTeX_re = re.compile("\\\\document(style|class)") - -def is_LaTeX(flist): - # Scan a file list to decide if it's TeX- or LaTeX-flavored. - for f in flist: - content = f.get_contents() - if LaTeX_re.search(content): - return 1 - return 0 - -def TeXLaTeXFunction(target = None, source= None, env=None): - """A builder for TeX and LaTeX that scans the source file to - decide the "flavor" of the source and then executes the appropriate - program.""" - if is_LaTeX(source): - LaTeXAuxAction(target,source,env) - else: - TeXAction(target,source,env) - return 0 - -def tex_emitter(target, source, env): - base = SCons.Util.splitext(str(source[0]))[0] - target.append(base + '.aux') - env.Precious(base + '.aux') - target.append(base + '.log') - for f in source: - content = f.get_contents() - if tableofcontents_re.search(content): - target.append(base + '.toc') - env.Precious(base + '.toc') - if makeindex_re.search(content): - target.append(base + '.ilg') - target.append(base + '.ind') - target.append(base + '.idx') - env.Precious(base + '.idx') - if bibliography_re.search(content): - target.append(base + '.bbl') - env.Precious(base + '.bbl') - target.append(base + '.blg') - - # read log file to get all output file (include .aux files) - logfilename = base + '.log' - dir, base_nodir = os.path.split(base) - if os.path.exists(logfilename): - content = open(logfilename, "rb").read() - out_files = openout_re.findall(content) - out_files = filter(lambda f, b=base_nodir+'.aux': f != b, out_files) - if dir != '': - out_files = map(lambda f, d=dir: d+os.sep+f, out_files) - target.extend(out_files) - for f in out_files: - env.Precious( f ) - - return (target, source) - -TeXLaTeXAction = None - -def generate(env): - """Add Builders and construction variables for TeX to an Environment.""" - - # A generic tex file Action, sufficient for all tex files. - global TeXAction - if TeXAction is None: - TeXAction = SCons.Action.Action("$TEXCOM", "$TEXCOMSTR") - - # An Action to build a latex file. This might be needed more - # than once if we are dealing with labels and bibtex. - global LaTeXAction - if LaTeXAction is None: - LaTeXAction = SCons.Action.Action("$LATEXCOM", "$LATEXCOMSTR") - - # Define an action to run BibTeX on a file. - global BibTeXAction - if BibTeXAction is None: - BibTeXAction = SCons.Action.Action("$BIBTEXCOM", "$BIBTEXCOMSTR") - - # Define an action to run MakeIndex on a file. - global MakeIndexAction - if MakeIndexAction is None: - MakeIndexAction = SCons.Action.Action("$MAKEINDEXCOM", "$MAKEINDEXCOMSTR") - - global TeXLaTeXAction - if TeXLaTeXAction is None: - TeXLaTeXAction = SCons.Action.Action(TeXLaTeXFunction, strfunction=None) - - import dvi - dvi.generate(env) - - bld = env['BUILDERS']['DVI'] - bld.add_action('.tex', TeXLaTeXAction) - bld.add_emitter('.tex', tex_emitter) - - env['TEX'] = 'tex' - env['TEXFLAGS'] = SCons.Util.CLVar('') - env['TEXCOM'] = 'cd ${TARGET.dir} && $TEX $TEXFLAGS ${SOURCE.file}' - - # Duplicate from latex.py. If latex.py goes away, then this is still OK. - env['LATEX'] = 'latex' - env['LATEXFLAGS'] = SCons.Util.CLVar('') - env['LATEXCOM'] = 'cd ${TARGET.dir} && $LATEX $LATEXFLAGS ${SOURCE.file}' - env['LATEXRETRIES'] = 3 - - env['BIBTEX'] = 'bibtex' - env['BIBTEXFLAGS'] = SCons.Util.CLVar('') - env['BIBTEXCOM'] = 'cd ${TARGET.dir} && $BIBTEX $BIBTEXFLAGS ${SOURCE.filebase}' - - env['MAKEINDEX'] = 'makeindex' - env['MAKEINDEXFLAGS'] = SCons.Util.CLVar('') - env['MAKEINDEXCOM'] = 'cd ${TARGET.dir} && $MAKEINDEX $MAKEINDEXFLAGS ${SOURCE.file}' - -def exists(env): - return env.Detect('tex') diff --git a/scons/scons-local-0.97.0d20071212/scons-0.97.0d20071212.egg-info b/scons/scons-local-0.97.0d20071212/scons-0.97.0d20071212.egg-info deleted file mode 100644 index 604062f4d..000000000 --- a/scons/scons-local-0.97.0d20071212/scons-0.97.0d20071212.egg-info +++ /dev/null @@ -1,13 +0,0 @@ -Metadata-Version: 1.0 -Name: scons -Version: 0.97.0d20071212 -Summary: Open Source next-generation build tool. -Improved, cross-platform substitute for the classic Make -utility. In short, SCons is an easier, more reliable -and faster way to build software. -Home-page: http://www.scons.org/ -Author: Steven Knight -Author-email: knight@baldmt.com -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN diff --git a/scons/scons-local-0.97.0d20071212/SCons/Action.py b/scons/scons-local-1.2.0/SCons/Action.py similarity index 61% rename from scons/scons-local-0.97.0d20071212/SCons/Action.py rename to scons/scons-local-1.2.0/SCons/Action.py index 5a7efccac..d740de66d 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Action.py +++ b/scons/scons-local-1.2.0/SCons/Action.py @@ -30,9 +30,9 @@ other modules: a pre-substitution command for debugging purposes. get_contents() - Fetches the "contents" of an Action for signature calculation. - This is what gets MD5 checksumm'ed to decide if a target needs - to be rebuilt because its action changed. + Fetches the "contents" of an Action for signature calculation + plus the varlist. This is what gets MD5 checksummed to decide + if a target needs to be rebuilt because its action changed. genstring() Returns a string representation of the Action *without* @@ -49,7 +49,7 @@ this module: __str__() Returns a string approximation of the Action; no variable substitution is performed. - + execute() The internal method that really, truly, actually handles the execution of a command or Python function. This is used so @@ -57,6 +57,10 @@ this module: pre-substitution representations, and *then* execute an action without worrying about the specific Actions involved. + get_presig() + Fetches the "contents" of a subclass for signature calculation. + The varlist is added to this to produce the Action's contents. + strfunction() Returns a substituted string representation of the Action. This is used by the _ActionAction.show() command to display the @@ -72,8 +76,7 @@ way for wrapping up the functions. """ -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -93,32 +96,33 @@ way for wrapping up the functions. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "src/engine/SCons/Action.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Action.py 3842 2008/12/20 22:59:52 scons" +import cPickle import dis import os -import os.path import string import sys +import subprocess from SCons.Debug import logInstanceCreation import SCons.Errors import SCons.Executor import SCons.Util +import SCons.Subst -class _Null: +# we use these a lot, so try to optimize them +is_String = SCons.Util.is_String +is_List = SCons.Util.is_List + +class _null: pass -_null = _Null - print_actions = 1 execute_actions = 1 print_actions_presub = 0 -default_ENV = None - def rfile(n): try: return n.rfile() @@ -150,6 +154,141 @@ else: i = i+1 return string.join(result, '') + +def _callable_contents(obj): + """Return the signature contents of a callable Python object. + """ + try: + # Test if obj is a method. + return _function_contents(obj.im_func) + + except AttributeError: + try: + # Test if obj is a callable object. + return _function_contents(obj.__call__.im_func) + + except AttributeError: + try: + # Test if obj is a code object. + return _code_contents(obj) + + except AttributeError: + # Test if obj is a function object. + return _function_contents(obj) + + +def _object_contents(obj): + """Return the signature contents of any Python object. + + We have to handle the case where object contains a code object + since it can be pickled directly. + """ + try: + # Test if obj is a method. + return _function_contents(obj.im_func) + + except AttributeError: + try: + # Test if obj is a callable object. + return _function_contents(obj.__call__.im_func) + + except AttributeError: + try: + # Test if obj is a code object. + return _code_contents(obj) + + except AttributeError: + try: + # Test if obj is a function object. + return _function_contents(obj) + + except AttributeError: + # Should be a pickable Python object. + try: + return cPickle.dumps(obj) + except (cPickle.PicklingError, TypeError): + # This is weird, but it seems that nested classes + # are unpickable. The Python docs say it should + # always be a PicklingError, but some Python + # versions seem to return TypeError. Just do + # the best we can. + return str(obj) + + +def _code_contents(code): + """Return the signature contents of a code object. + + By providing direct access to the code object of the + function, Python makes this extremely easy. Hooray! + + Unfortunately, older versions of Python include line + number indications in the compiled byte code. Boo! + So we remove the line number byte codes to prevent + recompilations from moving a Python function. + """ + + contents = [] + + # The code contents depends on the number of local variables + # but not their actual names. + contents.append("%s,%s" % (code.co_argcount, len(code.co_varnames))) + try: + contents.append(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars))) + except AttributeError: + # Older versions of Python do not support closures. + contents.append(",0,0") + + # The code contents depends on any constants accessed by the + # function. Note that we have to call _object_contents on each + # constants because the code object of nested functions can + # show-up among the constants. + # + # Note that we also always ignore the first entry of co_consts + # which contains the function doc string. We assume that the + # function does not access its doc string. + contents.append(',(' + string.join(map(_object_contents,code.co_consts[1:]),',') + ')') + + # The code contents depends on the variable names used to + # accessed global variable, as changing the variable name changes + # the variable actually accessed and therefore changes the + # function result. + contents.append(',(' + string.join(map(_object_contents,code.co_names),',') + ')') + + + # The code contents depends on its actual code!!! + contents.append(',(' + str(remove_set_lineno_codes(code.co_code)) + ')') + + return string.join(contents, '') + + +def _function_contents(func): + """Return the signature contents of a function.""" + + contents = [_code_contents(func.func_code)] + + # The function contents depends on the value of defaults arguments + if func.func_defaults: + contents.append(',(' + string.join(map(_object_contents,func.func_defaults),',') + ')') + else: + contents.append(',()') + + # The function contents depends on the closure captured cell values. + try: + closure = func.func_closure or [] + except AttributeError: + # Older versions of Python do not support closures. + closure = [] + + #xxx = [_object_contents(x.cell_contents) for x in closure] + try: + xxx = map(lambda x: _object_contents(x.cell_contents), closure) + except AttributeError: + xxx = [] + contents.append(',(' + string.join(xxx, ',') + ')') + + return string.join(contents, '') + + def _actionAppend(act1, act2): # This function knows how to slap two actions together. # Mainly, it handles ListActions by concatenating into @@ -169,7 +308,34 @@ def _actionAppend(act1, act2): else: return ListAction([ a1, a2 ]) -def _do_create_action(act, *args, **kw): +def _do_create_keywords(args, kw): + """This converts any arguments after the action argument into + their equivalent keywords and adds them to the kw argument. + """ + v = kw.get('varlist', ()) + # prevent varlist="FOO" from being interpreted as ['F', 'O', 'O'] + if is_String(v): v = (v,) + kw['varlist'] = tuple(v) + if args: + # turn positional args into equivalent keywords + cmdstrfunc = args[0] + if cmdstrfunc is None or is_String(cmdstrfunc): + kw['cmdstr'] = cmdstrfunc + elif callable(cmdstrfunc): + kw['strfunction'] = cmdstrfunc + else: + raise SCons.Errors.UserError( + 'Invalid command display variable type. ' + 'You must either pass a string or a callback which ' + 'accepts (target, source, env) as parameters.') + if len(args) > 1: + kw['varlist'] = args[1:] + kw['varlist'] + if kw.get('strfunction', _null) is not _null \ + and kw.get('cmdstr', _null) is not _null: + raise SCons.Errors.UserError( + 'Cannot have both strfunction and cmdstr args to Action()') + +def _do_create_action(act, kw): """This is the actual "implementation" for the Action factory method, below. This handles the fact that passing lists to Action() itself has @@ -182,8 +348,11 @@ def _do_create_action(act, *args, **kw): if isinstance(act, ActionBase): return act - if SCons.Util.is_List(act): - return apply(CommandAction, (act,)+args, kw) + + if is_List(act): + #TODO(1.5) return CommandAction(act, **kw) + return apply(CommandAction, (act,), kw) + if callable(act): try: gen = kw['generator'] @@ -194,8 +363,9 @@ def _do_create_action(act, *args, **kw): action_type = CommandGeneratorAction else: action_type = FunctionAction - return apply(action_type, (act,)+args, kw) - if SCons.Util.is_String(act): + return action_type(act, kw) + + if is_String(act): var=SCons.Util.get_environment_var(act) if var: # This looks like a string that is purely an Environment @@ -204,30 +374,37 @@ def _do_create_action(act, *args, **kw): # of that Environment variable, so a user could put something # like a function or a CommandGenerator in that variable # instead of a string. - return apply(LazyAction, (var,)+args, kw) + return LazyAction(var, kw) commands = string.split(str(act), '\n') if len(commands) == 1: - return apply(CommandAction, (commands[0],)+args, kw) - else: - listCmdActions = map(lambda x, args=args, kw=kw: - apply(CommandAction, (x,)+args, kw), - commands) - return ListAction(listCmdActions) + #TODO(1.5) return CommandAction(commands[0], **kw) + return apply(CommandAction, (commands[0],), kw) + # The list of string commands may include a LazyAction, so we + # reprocess them via _do_create_list_action. + return _do_create_list_action(commands, kw) return None +def _do_create_list_action(act, kw): + """A factory for list actions. Convert the input list into Actions + and then wrap them in a ListAction.""" + acts = [] + for a in act: + aa = _do_create_action(a, kw) + if aa is not None: acts.append(aa) + if not acts: + return None + elif len(acts) == 1: + return acts[0] + else: + return ListAction(acts) + def Action(act, *args, **kw): """A factory for action objects.""" - if SCons.Util.is_List(act): - acts = map(lambda a, args=args, kw=kw: - apply(_do_create_action, (a,)+args, kw), - act) - acts = filter(None, acts) - if len(acts) == 1: - return acts[0] - else: - return ListAction(acts) - else: - return apply(_do_create_action, (act,)+args, kw) + # Really simple: the _do_create_* routines do the heavy lifting. + _do_create_keywords(args, kw) + if is_List(act): + return _do_create_list_action(act, kw) + return _do_create_action(act, kw) class ActionBase: """Base class for all types of action objects that can be held by @@ -240,6 +417,17 @@ class ActionBase: def genstring(self, target, source, env): return str(self) + def get_contents(self, target, source, env): + result = [ self.get_presig(target, source, env) ] + # This should never happen, as the Action() factory should wrap + # the varlist, but just in case an action is created directly, + # we duplicate this check here. + vl = self.varlist + if is_String(vl): vl = (vl,) + for v in vl: + result.append(env.subst('${'+v+'}')) + return string.join(result, '') + def __add__(self, other): return _actionAppend(self, other) @@ -265,9 +453,16 @@ class ActionBase: class _ActionAction(ActionBase): """Base class for actions that create output objects.""" - def __init__(self, strfunction=_null, presub=_null, chdir=None, exitstatfunc=None, **kw): - if not strfunction is _null: - self.strfunction = strfunction + def __init__(self, cmdstr=_null, strfunction=_null, varlist=(), + presub=_null, chdir=None, exitstatfunc=None, + **kw): + self.cmdstr = cmdstr + if strfunction is not _null: + if strfunction is None: + self.cmdstr = None + else: + self.strfunction = strfunction + self.varlist = varlist self.presub = presub self.chdir = chdir if not exitstatfunc: @@ -283,16 +478,16 @@ class _ActionAction(ActionBase): show=_null, execute=_null, chdir=_null): - if not SCons.Util.is_List(target): + if not is_List(target): target = [target] - if not SCons.Util.is_List(source): + if not is_List(source): source = [source] - if exitstatfunc is _null: exitstatfunc = self.exitstatfunc if presub is _null: presub = self.presub - if presub is _null: - presub = print_actions_presub + if presub is _null: + presub = print_actions_presub + if exitstatfunc is _null: exitstatfunc = self.exitstatfunc if show is _null: show = print_actions if execute is _null: execute = execute_actions if chdir is _null: chdir = self.chdir @@ -302,19 +497,19 @@ class _ActionAction(ActionBase): try: chdir = str(chdir.abspath) except AttributeError: - if not SCons.Util.is_String(chdir): + if not is_String(chdir): chdir = str(target[0].dir) if presub: t = string.join(map(str, target), ' and ') l = string.join(self.presub_lines(env), '\n ') out = "Building %s with action:\n %s\n" % (t, l) sys.stdout.write(out) - s = None + cmd = None if show and self.strfunction: - s = self.strfunction(target, source, env) - if s: + cmd = self.strfunction(target, source, env) + if cmd: if chdir: - s = ('os.chdir(%s)\n' % repr(chdir)) + s + cmd = ('os.chdir(%s)\n' % repr(chdir)) + cmd try: get = env.get except AttributeError: @@ -323,7 +518,7 @@ class _ActionAction(ActionBase): print_func = get('PRINT_CMD_LINE_FUNC') if not print_func: print_func = self.print_cmd_line - print_func(s, target, source, env) + print_func(cmd, target, source, env) stat = 0 if execute: if chdir: @@ -341,7 +536,7 @@ class _ActionAction(ActionBase): finally: if save_cwd: os.chdir(save_cwd) - if s and save_cwd: + if cmd and save_cwd: print_func('os.chdir(%s)' % repr(save_cwd), target, source, env) return stat @@ -357,9 +552,87 @@ def _string_from_cmd_list(cmd_list): cl.append(arg) return string.join(cl) +# A fiddlin' little function that has an 'import SCons.Environment' which +# can't be moved to the top level without creating an import loop. Since +# this import creates a local variable named 'SCons', it blocks access to +# the global variable, so we move it here to prevent complaints about local +# variables being used uninitialized. +default_ENV = None +def get_default_ENV(env): + global default_ENV + try: + return env['ENV'] + except KeyError: + if not default_ENV: + import SCons.Environment + # This is a hideously expensive way to get a default shell + # environment. What it really should do is run the platform + # setup to get the default ENV. Fortunately, it's incredibly + # rare for an Environment not to have a shell environment, so + # we're not going to worry about it overmuch. + default_ENV = SCons.Environment.Environment()['ENV'] + return default_ENV + +# This function is still in draft mode. We're going to need something like +# it in the long run as more and more places use subprocess, but I'm sure +# it'll have to be tweaked to get the full desired functionality. +# one special arg (so far?), 'error', to tell what to do with exceptions. +def _subproc(env, cmd, error = 'ignore', **kw): + """Do common setup for a subprocess.Popen() call""" + # allow std{in,out,err} to be "'devnull'" + io = kw.get('stdin') + if is_String(io) and io == 'devnull': + kw['stdin'] = open(os.devnull) + io = kw.get('stdout') + if is_String(io) and io == 'devnull': + kw['stdout'] = open(os.devnull, 'w') + io = kw.get('stderr') + if is_String(io) and io == 'devnull': + kw['stderr'] = open(os.devnull, 'w') + + # Figure out what shell environment to use + ENV = kw.get('env', None) + if ENV is None: ENV = get_default_ENV(env) + + # Ensure that the ENV values are all strings: + new_env = {} + for key, value in ENV.items(): + if is_List(value): + # If the value is a list, then we assume it is a path list, + # because that's a pretty common list-like value to stick + # in an environment variable: + value = SCons.Util.flatten_sequence(value) + new_env[key] = string.join(map(str, value), os.pathsep) + else: + # It's either a string or something else. If it's a string, + # we still want to call str() because it might be a *Unicode* + # string, which makes subprocess.Popen() gag. If it isn't a + # string or a list, then we just coerce it to a string, which + # is the proper way to handle Dir and File instances and will + # produce something reasonable for just about everything else: + new_env[key] = str(value) + kw['env'] = new_env + + try: + #FUTURE return subprocess.Popen(cmd, **kw) + return apply(subprocess.Popen, (cmd,), kw) + except EnvironmentError, e: + if error == 'raise': raise + # return a dummy Popen instance that only returns error + class dummyPopen: + def __init__(self, e): self.exception = e + def communicate(self): return ('','') + def wait(self): return -self.exception.errno + stdin = None + class f: + def read(self): return '' + def readline(self): return '' + stdout = stderr = f() + return dummyPopen(e) + class CommandAction(_ActionAction): """Class for command-execution actions.""" - def __init__(self, cmd, cmdstr=None, *args, **kw): + def __init__(self, cmd, **kw): # Cmd can actually be a list or a single item; if it's a # single item it should be the command string to execute; if a # list then it should be the words of the command string to @@ -371,25 +644,16 @@ class CommandAction(_ActionAction): # variables. if __debug__: logInstanceCreation(self, 'Action.CommandAction') - if not cmdstr is None: - if callable(cmdstr): - args = (cmdstr,)+args - elif not SCons.Util.is_String(cmdstr): - raise SCons.Errors.UserError(\ - 'Invalid command display variable type. ' \ - 'You must either pass a string or a callback which ' \ - 'accepts (target, source, env) as parameters.') - - apply(_ActionAction.__init__, (self,)+args, kw) - if SCons.Util.is_List(cmd): - if filter(SCons.Util.is_List, cmd): + #TODO(1.5) _ActionAction.__init__(self, **kw) + apply(_ActionAction.__init__, (self,), kw) + if is_List(cmd): + if filter(is_List, cmd): raise TypeError, "CommandAction should be given only " \ "a single command" self.cmd_list = cmd - self.cmdstr = cmdstr def __str__(self): - if SCons.Util.is_List(self.cmd_list): + if is_List(self.cmd_list): return string.join(map(str, self.cmd_list), ' ') return str(self.cmd_list) @@ -412,7 +676,9 @@ class CommandAction(_ActionAction): return result, ignore, silent def strfunction(self, target, source, env): - if not self.cmdstr is None: + if self.cmdstr is None: + return None + if self.cmdstr is not _null: from SCons.Subst import SUBST_RAW c = env.subst(self.cmdstr, SUBST_RAW, target, source) if c: @@ -431,11 +697,8 @@ class CommandAction(_ActionAction): handle lists of commands, even though that's not how we use it externally. """ - from SCons.Subst import escape_list - import SCons.Util - flatten = SCons.Util.flatten - is_String = SCons.Util.is_String - is_List = SCons.Util.is_List + escape_list = SCons.Subst.escape_list + flatten_sequence = SCons.Util.flatten_sequence try: shell = env['SHELL'] @@ -452,14 +715,7 @@ class CommandAction(_ActionAction): escape = env.get('ESCAPE', lambda x: x) - try: - ENV = env['ENV'] - except KeyError: - global default_ENV - if not default_ENV: - import SCons.Environment - default_ENV = SCons.Environment.Environment()['ENV'] - ENV = default_ENV + ENV = get_default_ENV(env) # Ensure that the ENV values are all strings: for key, value in ENV.items(): @@ -468,7 +724,7 @@ class CommandAction(_ActionAction): # If the value is a list, then we assume it is a # path list, because that's a pretty common list-like # value to stick in an environment variable: - value = flatten(value) + value = flatten_sequence(value) ENV[key] = string.join(map(str, value), os.pathsep) else: # If it isn't a string or a list, then we just coerce @@ -492,7 +748,7 @@ class CommandAction(_ActionAction): command=cmd_line) return 0 - def get_contents(self, target, source, env): + def get_presig(self, target, source, env): """Return the signature contents of this action's command line. This strips $(-$) and everything in between the string, @@ -500,7 +756,7 @@ class CommandAction(_ActionAction): """ from SCons.Subst import SUBST_SIG cmd = self.cmd_list - if SCons.Util.is_List(cmd): + if is_List(cmd): cmd = string.join(map(str, cmd)) else: cmd = str(cmd) @@ -508,7 +764,7 @@ class CommandAction(_ActionAction): def get_implicit_deps(self, target, source, env): icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True) - if SCons.Util.is_String(icd) and icd[:1] == '$': + if is_String(icd) and icd[:1] == '$': icd = env.subst(icd) if not icd or icd in ('0', 'None'): return [] @@ -524,20 +780,21 @@ class CommandAction(_ActionAction): class CommandGeneratorAction(ActionBase): """Class for command-generator actions.""" - def __init__(self, generator, *args, **kw): + def __init__(self, generator, kw): if __debug__: logInstanceCreation(self, 'Action.CommandGeneratorAction') self.generator = generator - self.gen_args = args self.gen_kw = kw + self.varlist = kw.get('varlist', ()) def _generate(self, target, source, env, for_signature): # ensure that target is a list, to make it easier to write # generator functions: - if not SCons.Util.is_List(target): + if not is_List(target): target = [target] ret = self.generator(target=target, source=source, env=env, for_signature=for_signature) - gen_cmd = apply(Action, (ret,)+self.gen_args, self.gen_kw) + #TODO(1.5) gen_cmd = Action(ret, **self.gen_kw) + gen_cmd = apply(Action, (ret,), self.gen_kw) if not gen_cmd: raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret)) return gen_cmd @@ -561,13 +818,13 @@ class CommandGeneratorAction(ActionBase): return act(target, source, env, exitstatfunc, presub, show, execute, chdir) - def get_contents(self, target, source, env): + def get_presig(self, target, source, env): """Return the signature contents of this action's command line. This strips $(-$) and everything in between the string, since those parts don't affect signatures. """ - return self._generate(target, source, env, 1).get_contents(target, source, env) + return self._generate(target, source, env, 1).get_presig(target, source, env) def get_implicit_deps(self, target, source, env): return self._generate(target, source, env, 1).get_implicit_deps(target, source, env) @@ -593,22 +850,23 @@ class CommandGeneratorAction(ActionBase): class LazyAction(CommandGeneratorAction, CommandAction): - def __init__(self, var, *args, **kw): + def __init__(self, var, kw): if __debug__: logInstanceCreation(self, 'Action.LazyAction') - apply(CommandAction.__init__, (self, '$'+var)+args, kw) + #FUTURE CommandAction.__init__(self, '${'+var+'}', **kw) + apply(CommandAction.__init__, (self, '${'+var+'}'), kw) self.var = SCons.Util.to_String(var) - self.gen_args = args self.gen_kw = kw def get_parent_class(self, env): c = env.get(self.var) - if SCons.Util.is_String(c) and not '\n' in c: + if is_String(c) and not '\n' in c: return CommandAction return CommandGeneratorAction def _generate_cache(self, env): c = env.get(self.var, '') - gen_cmd = apply(Action, (c,)+self.gen_args, self.gen_kw) + #TODO(1.5) gen_cmd = Action(c, **self.gen_kw) + gen_cmd = apply(Action, (c,), self.gen_kw) if not gen_cmd: raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c))) return gen_cmd @@ -619,33 +877,34 @@ class LazyAction(CommandGeneratorAction, CommandAction): def __call__(self, target, source, env, *args, **kw): args = (self, target, source, env) + args c = self.get_parent_class(env) + #TODO(1.5) return c.__call__(*args, **kw) return apply(c.__call__, args, kw) - def get_contents(self, target, source, env): + def get_presig(self, target, source, env): c = self.get_parent_class(env) - return c.get_contents(self, target, source, env) + return c.get_presig(self, target, source, env) class FunctionAction(_ActionAction): """Class for Python function actions.""" - def __init__(self, execfunction, cmdstr=_null, *args, **kw): + def __init__(self, execfunction, kw): if __debug__: logInstanceCreation(self, 'Action.FunctionAction') - if not cmdstr is _null: - if callable(cmdstr): - args = (cmdstr,)+args - elif not (cmdstr is None or SCons.Util.is_String(cmdstr)): - raise SCons.Errors.UserError(\ - 'Invalid function display variable type. ' \ - 'You must either pass a string or a callback which ' \ - 'accepts (target, source, env) as parameters.') - self.execfunction = execfunction - apply(_ActionAction.__init__, (self,)+args, kw) - self.varlist = kw.get('varlist', []) - self.cmdstr = cmdstr + try: + self.funccontents = _callable_contents(execfunction) + except AttributeError: + try: + # See if execfunction will do the heavy lifting for us. + self.gc = execfunction.get_contents + except AttributeError: + # This is weird, just do the best we can. + self.funccontents = _object_contents(execfunction) + + #TODO(1.5) _ActionAction.__init__(self, **kw) + apply(_ActionAction.__init__, (self,), kw) def function_name(self): try: @@ -659,14 +918,20 @@ class FunctionAction(_ActionAction): def strfunction(self, target, source, env): if self.cmdstr is None: return None - if not self.cmdstr is _null: + if self.cmdstr is not _null: from SCons.Subst import SUBST_RAW c = env.subst(self.cmdstr, SUBST_RAW, target, source) if c: return c def array(a): def quote(s): - return '"' + str(s) + '"' + try: + str_for_display = s.str_for_display + except AttributeError: + s = repr(s) + else: + s = str_for_display() + return s return '[' + string.join(map(quote, a), ", ") + ']' try: strfunc = self.execfunction.strfunction @@ -689,73 +954,49 @@ class FunctionAction(_ActionAction): return "%s(target, source, env)" % name def execute(self, target, source, env): - rsources = map(rfile, source) + exc_info = (None,None,None) try: - result = self.execfunction(target=target, source=rsources, env=env) - except EnvironmentError, e: - # If an IOError/OSError happens, raise a BuildError. - # Report the name of the file or directory that caused the - # error, which might be different from the target being built - # (for example, failure to create the directory in which the - # target file will appear). - try: filename = e.filename - except AttributeError: filename = None - result = SCons.Errors.BuildError(node=target, - errstr=e.strerror, - status=1, - filename=filename, - action=self, - command=self.strfunction(target, source, env)) - else: - if result: - msg = "Error %s" % result - result = SCons.Errors.BuildError(errstr=msg, - status=result, - action=self, - command=self.strfunction(target, source, env)) - return result - - def get_contents(self, target, source, env): - """Return the signature contents of this callable action. - - By providing direct access to the code object of the - function, Python makes this extremely easy. Hooray! - - Unfortunately, older versions of Python include line - number indications in the compiled byte code. Boo! - So we remove the line number byte codes to prevent - recompilations from moving a Python function. - """ - execfunction = self.execfunction - try: - # Test if execfunction is a function. - code = execfunction.func_code.co_code - except AttributeError: + rsources = map(rfile, source) try: - # Test if execfunction is a method. - code = execfunction.im_func.func_code.co_code - except AttributeError: - try: - # Test if execfunction is a callable object. - code = execfunction.__call__.im_func.func_code.co_code - except AttributeError: - try: - # See if execfunction will do the heavy lifting for us. - gc = self.execfunction.get_contents - except AttributeError: - # This is weird, just do the best we can. - contents = str(self.execfunction) - else: - contents = gc(target, source, env) - else: - contents = str(code) - else: - contents = str(code) - else: - contents = str(code) - contents = remove_set_lineno_codes(contents) - return contents + env.subst(string.join(map(lambda v: '${'+v+'}', - self.varlist))) + result = self.execfunction(target=target, source=rsources, env=env) + except KeyboardInterrupt, e: + raise + except SystemExit, e: + raise + except Exception, e: + result = e + exc_info = sys.exc_info() + + if result: + result = SCons.Errors.convert_to_BuildError(result, exc_info) + result.node=target + result.action=self + result.command=self.strfunction(target, source, env) + + # FIXME: This maintains backward compatibility with respect to + # which type of exceptions were returned by raising an + # exception and which ones were returned by value. It would + # probably be best to always return them by value here, but + # some codes do not check the return value of Actions and I do + # not have the time to modify them at this point. + if (exc_info[1] and + not isinstance(exc_info[1],EnvironmentError)): + raise result + + return result + finally: + # Break the cycle between the traceback object and this + # function stack frame. See the sys.exc_info() doc info for + # more information about this issue. + del exc_info + + + def get_presig(self, target, source, env): + """Return the signature contents of this callable action.""" + try: + return self.gc(target, source, env) + except AttributeError: + return self.funccontents def get_implicit_deps(self, target, source, env): return [] @@ -769,6 +1010,9 @@ class ListAction(ActionBase): return x return Action(x) self.list = map(list_of_actions, list) + # our children will have had any varlist + # applied; we don't need to do it again + self.varlist = () def genstring(self, target, source, env): return string.join(map(lambda a, t=target, s=source, e=env: @@ -778,13 +1022,12 @@ class ListAction(ActionBase): def __str__(self): return string.join(map(str, self.list), '\n') - - def presub_lines(self, env): - return SCons.Util.flatten(map(lambda a, env=env: - a.presub_lines(env), - self.list)) - def get_contents(self, target, source, env): + def presub_lines(self, env): + return SCons.Util.flatten_sequence( + map(lambda a, env=env: a.presub_lines(env), self.list)) + + def get_presig(self, target, source, env): """Return the signature contents of this action list. Simple concatenation of the signatures of the elements. @@ -822,6 +1065,7 @@ class ActionCaller: self.parent = parent self.args = args self.kw = kw + def get_contents(self, target, source, env): actfunc = self.parent.actfunc try: @@ -837,33 +1081,50 @@ class ActionCaller: contents = str(actfunc) contents = remove_set_lineno_codes(contents) return contents + def subst(self, s, target, source, env): + # If s is a list, recursively apply subst() + # to every element in the list + if is_List(s): + result = [] + for elem in s: + result.append(self.subst(elem, target, source, env)) + return self.parent.convert(result) + # Special-case hack: Let a custom function wrapped in an # ActionCaller get at the environment through which the action # was called by using this hard-coded value as a special return. if s == '$__env__': return env - elif SCons.Util.is_String(s): - return env.subst(s, 0, target, source) + elif is_String(s): + return env.subst(s, 1, target, source) return self.parent.convert(s) + def subst_args(self, target, source, env): return map(lambda x, self=self, t=target, s=source, e=env: self.subst(x, t, s, e), self.args) + def subst_kw(self, target, source, env): kw = {} for key in self.kw.keys(): kw[key] = self.subst(self.kw[key], target, source, env) return kw + def __call__(self, target, source, env): args = self.subst_args(target, source, env) kw = self.subst_kw(target, source, env) + #TODO(1.5) return self.parent.actfunc(*args, **kw) return apply(self.parent.actfunc, args, kw) + def strfunction(self, target, source, env): args = self.subst_args(target, source, env) kw = self.subst_kw(target, source, env) + #TODO(1.5) return self.parent.strfunc(*args, **kw) return apply(self.parent.strfunc, args, kw) + def __str__(self): + #TODO(1.5) return self.parent.strfunc(*self.args, **self.kw) return apply(self.parent.strfunc, self.args, self.kw) class ActionFactory: @@ -879,6 +1140,7 @@ class ActionFactory: self.actfunc = actfunc self.strfunc = strfunc self.convert = convert + def __call__(self, *args, **kw): ac = ActionCaller(self, args, kw) action = Action(ac, strfunction=ac.strfunction) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Builder.py b/scons/scons-local-1.2.0/SCons/Builder.py similarity index 98% rename from scons/scons-local-0.97.0d20071212/SCons/Builder.py rename to scons/scons-local-1.2.0/SCons/Builder.py index 5bd2098ac..97aabb483 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Builder.py +++ b/scons/scons-local-1.2.0/SCons/Builder.py @@ -76,7 +76,7 @@ There are the following methods for internal use within this module: """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -98,9 +98,7 @@ There are the following methods for internal use within this module: # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Builder.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/Builder.py 3842 2008/12/20 22:59:52 scons" import UserDict import UserList @@ -234,7 +232,7 @@ def Builder(**kw): if kw.has_key('generator'): if kw.has_key('action'): raise UserError, "You must not specify both an action and a generator." - kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator']) + kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator'], {}) del kw['generator'] elif kw.has_key('action'): source_ext_match = kw.get('source_ext_match', 1) @@ -242,7 +240,7 @@ def Builder(**kw): del kw['source_ext_match'] if SCons.Util.is_Dict(kw['action']): composite = DictCmdGenerator(kw['action'], source_ext_match) - kw['action'] = SCons.Action.CommandGeneratorAction(composite) + kw['action'] = SCons.Action.CommandGeneratorAction(composite, {}) kw['src_suffix'] = composite.src_suffixes() else: kw['action'] = SCons.Action.Action(kw['action']) @@ -363,7 +361,7 @@ class BuilderBase: name = None, chdir = _null, is_explicit = 1, - src_builder = [], + src_builder = None, ensure_suffix = False, **overrides): if __debug__: logInstanceCreation(self, 'Builder.BuilderBase') @@ -410,7 +408,9 @@ class BuilderBase: self.executor_kw['chdir'] = chdir self.is_explicit = is_explicit - if not SCons.Util.is_List(src_builder): + if src_builder is None: + src_builder = [] + elif not SCons.Util.is_List(src_builder): src_builder = [ src_builder ] self.src_builder = src_builder @@ -505,7 +505,7 @@ class BuilderBase: tlist = [ t_from_s(pre, suf, splitext) ] else: target = self._adjustixes(target, pre, suf, self.ensure_suffix) - tlist = env.arg2nodes(target, target_factory) + tlist = env.arg2nodes(target, target_factory, target=target, source=source) if self.emitter: # The emitter is going to do str(node), but because we're @@ -712,14 +712,9 @@ class BuilderBase: return None result = [] - - if SCons.Util.is_List(source): - source = SCons.Util.flatten(source) - else: - source = [source] - for s in source: + for s in SCons.Util.flatten(source): if SCons.Util.is_String(s): - match_suffix = match_src_suffix(s) + match_suffix = match_src_suffix(env.subst(s)) if not match_suffix and not '.' in s: src_suf = self.get_src_suffix(env) s = self._adjustixes(s, None, src_suf)[0] diff --git a/scons/scons-local-0.97.0d20071212/SCons/CacheDir.py b/scons/scons-local-1.2.0/SCons/CacheDir.py similarity index 89% rename from scons/scons-local-0.97.0d20071212/SCons/CacheDir.py rename to scons/scons-local-1.2.0/SCons/CacheDir.py index 871c62ec2..6eb6f173b 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/CacheDir.py +++ b/scons/scons-local-1.2.0/SCons/CacheDir.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/CacheDir.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/CacheDir.py 3842 2008/12/20 22:59:52 scons" __doc__ = """ CacheDir support @@ -34,6 +34,7 @@ import sys import SCons.Action +cache_enabled = True cache_debug = False cache_force = False cache_show = False @@ -129,31 +130,33 @@ class CacheDir: except ImportError: msg = "No hashlib or MD5 module available, CacheDir() not supported" SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg) + self.path = None else: self.path = path + self.current_cache_debug = None + self.debugFP = None - def CacheDebugWrite(self, fmt, target, cachefile): - self.debugFP.write(fmt % (target, os.path.split(cachefile)[1])) - - def CacheDebugQuiet(self, fmt, target, cachefile): - pass - - def CacheDebugInit(self, fmt, target, cachefile): - if cache_debug: + def CacheDebug(self, fmt, target, cachefile): + if cache_debug != self.current_cache_debug: if cache_debug == '-': self.debugFP = sys.stdout - else: + elif cache_debug: self.debugFP = open(cache_debug, 'w') - self.CacheDebug = self.CacheDebugWrite - self.CacheDebug(fmt, target, cachefile) - else: - self.CacheDebug = self.CacheDebugQuiet + else: + self.debugFP = None + self.current_cache_debug = cache_debug + if self.debugFP: + self.debugFP.write(fmt % (target, os.path.split(cachefile)[1])) - CacheDebug = CacheDebugInit + def is_enabled(self): + return (cache_enabled and not self.path is None) def cachepath(self, node): """ """ + if not self.is_enabled(): + return None, None + sig = node.get_cachedir_bsig() subdir = string.upper(sig[0]) dir = os.path.join(self.path, subdir) @@ -184,6 +187,9 @@ class CacheDir: execute the CacheRetrieveFunc and then have the latter explicitly check SCons.Action.execute_actions itself. """ + if not self.is_enabled(): + return False + retrieved = False if cache_show: @@ -202,16 +208,10 @@ class CacheDir: return retrieved def push(self, node): + if not self.is_enabled(): + return return CachePush(node, [], node.get_build_env()) def push_if_forced(self, node): if cache_force: return self.push(node) - -class Null(SCons.Util.Null): - def repr(self): - return 'CacheDir.Null()' - def cachepath(self, node): - return None, None - def retrieve(self, node): - return False diff --git a/scons/scons-local-0.97.0d20071212/SCons/Conftest.py b/scons/scons-local-1.2.0/SCons/Conftest.py similarity index 78% rename from scons/scons-local-0.97.0d20071212/SCons/Conftest.py rename to scons/scons-local-1.2.0/SCons/Conftest.py index fcf8c5a75..ba7dbf136 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Conftest.py +++ b/scons/scons-local-1.2.0/SCons/Conftest.py @@ -142,6 +142,101 @@ int main() { _YesNoResult(context, ret, None, text) return ret +def CheckCC(context): + """ + Configure check for a working C compiler. + + This checks whether the C compiler, as defined in the $CC construction + variable, can compile a C source file. It uses the current $CCCOM value + too, so that it can test against non working flags. + + """ + context.Display("Checking whether the C compiler works") + text = """ +int main() +{ + return 0; +} +""" + ret = _check_empty_program(context, 'CC', text, 'C') + _YesNoResult(context, ret, None, text) + return ret + +def CheckSHCC(context): + """ + Configure check for a working shared C compiler. + + This checks whether the C compiler, as defined in the $SHCC construction + variable, can compile a C source file. It uses the current $SHCCCOM value + too, so that it can test against non working flags. + + """ + context.Display("Checking whether the (shared) C compiler works") + text = """ +int foo() +{ + return 0; +} +""" + ret = _check_empty_program(context, 'SHCC', text, 'C', use_shared = True) + _YesNoResult(context, ret, None, text) + return ret + +def CheckCXX(context): + """ + Configure check for a working CXX compiler. + + This checks whether the CXX compiler, as defined in the $CXX construction + variable, can compile a CXX source file. It uses the current $CXXCOM value + too, so that it can test against non working flags. + + """ + context.Display("Checking whether the C++ compiler works") + text = """ +int main() +{ + return 0; +} +""" + ret = _check_empty_program(context, 'CXX', text, 'C++') + _YesNoResult(context, ret, None, text) + return ret + +def CheckSHCXX(context): + """ + Configure check for a working shared CXX compiler. + + This checks whether the CXX compiler, as defined in the $SHCXX construction + variable, can compile a CXX source file. It uses the current $SHCXXCOM value + too, so that it can test against non working flags. + + """ + context.Display("Checking whether the (shared) C++ compiler works") + text = """ +int main() +{ + return 0; +} +""" + ret = _check_empty_program(context, 'SHCXX', text, 'C++', use_shared = True) + _YesNoResult(context, ret, None, text) + return ret + +def _check_empty_program(context, comp, text, language, use_shared = False): + """Return 0 on success, 1 otherwise.""" + if not context.env.has_key(comp) or not context.env[comp]: + # The compiler construction variable is not set or empty + return 1 + + lang, suffix, msg = _lang2suffix(language) + if msg: + return 1 + + if use_shared: + return context.CompileSharedObject(text, suffix) + else: + return context.CompileProg(text, suffix) + def CheckFunc(context, function_name, header = None, language = None): """ @@ -206,7 +301,9 @@ int main() { context.Display("Checking for %s function %s()... " % (lang, function_name)) ret = context.BuildProg(text, suffix) - _YesNoResult(context, ret, "HAVE_" + function_name, text) + _YesNoResult(context, ret, "HAVE_" + function_name, text, + "Define to 1 if the system has the function `%s'." %\ + function_name) return ret @@ -253,7 +350,8 @@ def CheckHeader(context, header_name, header = None, language = None, context.Display("Checking for %s header file %s... " % (lang, header_name)) ret = context.CompileProg(text, suffix) - _YesNoResult(context, ret, "HAVE_" + header_name, text) + _YesNoResult(context, ret, "HAVE_" + header_name, text, + "Define to 1 if you have the <%s> header file." % header_name) return ret @@ -310,7 +408,8 @@ int main() { context.Display("Checking for %s type %s... " % (lang, type_name)) ret = context.BuildProg(text, suffix) - _YesNoResult(context, ret, "HAVE_" + type_name, text) + _YesNoResult(context, ret, "HAVE_" + type_name, text, + "Define to 1 if the system has the type `%s'." % type_name) if ret and fallback and context.headerfilename: f = open(context.headerfilename, "a") f.write("typedef %s %s;\n" % (fallback, type_name)) @@ -371,11 +470,11 @@ int main() } """ - # XXX: Try* vs CompileProg ? - st = context.TryCompile(src % (type_name, expect), suffix) - if st: - _Have(context, "SIZEOF_" + type_name, str(expect)) + st = context.CompileProg(src % (type_name, expect), suffix) + if not st: context.Display("yes\n") + _Have(context, "SIZEOF_%s" % type_name, expect, + "The size of `%s', as computed by sizeof." % type_name) return expect else: context.Display("no\n") @@ -400,21 +499,78 @@ int main() { return 0; } """ - ret = context.TryRun(src, suffix) - st = ret[0] + st, out = context.RunProg(src, suffix) try: - size = int(ret[1]) - _Have(context, "SIZEOF_" + type_name, str(size)) - context.Display("%d\n" % size) + size = int(out) except ValueError: + # If cannot convert output of test prog to an integer (the size), + # something went wront, so just fail + st = 1 size = 0 - _LogFailed(context, src, st) - context.Display(" Failed !\n") - if st: + + if not st: + context.Display("yes\n") + _Have(context, "SIZEOF_%s" % type_name, size, + "The size of `%s', as computed by sizeof." % type_name) return size else: + context.Display("no\n") + _LogFailed(context, src, st) return 0 + return 0 + +def CheckDeclaration(context, symbol, includes = None, language = None): + """Checks whether symbol is declared. + + Use the same test as autoconf, that is test whether the symbol is defined + as a macro or can be used as an r-value. + + Arguments: + symbol : str + the symbol to check + includes : str + Optional "header" can be defined to include a header file. + language : str + only C and C++ supported. + + Returns: + status : bool + True if the check failed, False if succeeded.""" + + # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. + if context.headerfilename: + includetext = '#include "%s"' % context.headerfilename + else: + includetext = '' + + if not includes: + includes = "" + + lang, suffix, msg = _lang2suffix(language) + if msg: + context.Display("Cannot check for declaration %s: %s\n" % (type_name, msg)) + return msg + + src = includetext + includes + context.Display('Checking whether %s is declared... ' % symbol) + + src = src + r""" +int main() +{ +#ifndef %s + (void) %s; +#endif + ; + return 0; +} +""" % (symbol, symbol) + + st = context.CompileProg(src, suffix) + _YesNoResult(context, st, "HAVE_DECL_" + symbol, src, + "Set to 1 if %s is defined." % symbol) + return st + def CheckLib(context, libs, func_name = None, header = None, extra_libs = None, call = None, language = None, autoadd = 1): """ @@ -509,7 +665,8 @@ return 0; ret = context.BuildProg(text, suffix) - _YesNoResult(context, ret, sym, text) + _YesNoResult(context, ret, sym, text, + "Define to 1 if you have the `%s' library." % lib_name) if oldLIBS != -1 and (ret or not autoadd): context.SetLIBS(oldLIBS) @@ -522,15 +679,17 @@ return 0; # END OF PUBLIC FUNCTIONS # -def _YesNoResult(context, ret, key, text): +def _YesNoResult(context, ret, key, text, comment = None): """ Handle the result of a test with a "yes" or "no" result. "ret" is the return value: empty if OK, error message when not. "key" is the name of the symbol to be defined (HAVE_foo). "text" is the source code of the program used for testing. + "comment" is the C comment to add above the line defining the symbol (the + comment is automatically put inside a /* */). If None, no comment is added. """ if key: - _Have(context, key, not ret) + _Have(context, key, not ret, comment) if ret: context.Display("no\n") _LogFailed(context, text, ret) @@ -538,7 +697,7 @@ def _YesNoResult(context, ret, key, text): context.Display("yes\n") -def _Have(context, key, have): +def _Have(context, key, have, comment = None): """ Store result of a test in context.havedict and context.headerfilename. "key" is a "HAVE_abc" name. It is turned into all CAPITALS and non- @@ -566,12 +725,17 @@ def _Have(context, key, have): else: line = "#define %s %s\n" % (key_up, str(have)) + if comment is not None: + lines = "\n/* %s */\n" % comment + line + else: + lines = "\n" + line + if context.headerfilename: f = open(context.headerfilename, "a") - f.write(line) + f.write(lines) f.close() elif hasattr(context,'config_h'): - context.config_h = context.config_h + line + context.config_h = context.config_h + lines def _LogFailed(context, text, msg): diff --git a/scons/scons-local-0.97.0d20071212/SCons/Debug.py b/scons/scons-local-1.2.0/SCons/Debug.py similarity index 79% rename from scons/scons-local-0.97.0d20071212/SCons/Debug.py rename to scons/scons-local-1.2.0/SCons/Debug.py index c2e552d71..c6485b6fa 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Debug.py +++ b/scons/scons-local-1.2.0/SCons/Debug.py @@ -7,7 +7,7 @@ needed by most users. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,7 +29,7 @@ needed by most users. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Debug.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Debug.py 3842 2008/12/20 22:59:52 scons" import os import string @@ -115,39 +115,57 @@ else: res = resource.getrusage(resource.RUSAGE_SELF) return res[4] - - -caller_dicts = {} - -def caller(*backlist): +# returns caller's stack +def caller_stack(*backlist): import traceback if not backlist: backlist = [0] result = [] for back in backlist: tb = traceback.extract_stack(limit=3+back) - key = tb[1][:3] - try: - entry = caller_dicts[key] - except KeyError: - entry = caller_dicts[key] = {} key = tb[0][:3] - entry[key] = entry.get(key, 0) + 1 result.append('%s:%d(%s)' % func_shorten(key)) return result +caller_bases = {} +caller_dicts = {} + +# trace a caller's stack +def caller_trace(back=0): + import traceback + tb = traceback.extract_stack(limit=3+back) + tb.reverse() + callee = tb[1][:3] + caller_bases[callee] = caller_bases.get(callee, 0) + 1 + for caller in tb[2:]: + caller = callee + caller[:3] + try: + entry = caller_dicts[callee] + except KeyError: + caller_dicts[callee] = entry = {} + entry[caller] = entry.get(caller, 0) + 1 + callee = caller + +# print a single caller and its callers, if any +def _dump_one_caller(key, file, level=0): + l = [] + for c,v in caller_dicts[key].items(): + l.append((-v,c)) + l.sort() + leader = ' '*level + for v,c in l: + file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:]))) + if caller_dicts.has_key(c): + _dump_one_caller(c, file, level+1) + +# print each call tree def dump_caller_counts(file=sys.stdout): - keys = caller_dicts.keys() + keys = caller_bases.keys() keys.sort() for k in keys: - file.write("Callers of %s:%d(%s):\n" % func_shorten(k)) - counts = caller_dicts[k] - callers = counts.keys() - callers.sort() - for c in callers: - #file.write(" counts[%s] = %s\n" % (c, counts[c])) - t = ((counts[c],) + func_shorten(c)) - file.write(" %6d %s:%d(%s)\n" % t) + file.write("Callers of %s:%d(%s), %d calls:\n" + % (func_shorten(k) + (caller_bases[k],))) + _dump_one_caller(k, file) shorten_list = [ ( '/scons/SCons/', 1), @@ -168,10 +186,8 @@ def func_shorten(func_tuple): if i >= 0: if t[1]: i = i + len(t[0]) - f = f[i:] - break - return (f,)+func_tuple[1:] - + return (f[i:],)+func_tuple[1:] + return func_tuple TraceFP = {} diff --git a/scons/scons-local-0.97.0d20071212/SCons/Defaults.py b/scons/scons-local-1.2.0/SCons/Defaults.py similarity index 79% rename from scons/scons-local-0.97.0d20071212/SCons/Defaults.py rename to scons/scons-local-1.2.0/SCons/Defaults.py index e4b0391c1..fc0ab26ba 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Defaults.py +++ b/scons/scons-local-1.2.0/SCons/Defaults.py @@ -10,7 +10,7 @@ from distutils.msvccompiler. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -32,7 +32,7 @@ from distutils.msvccompiler. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Defaults.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Defaults.py 3842 2008/12/20 22:59:52 scons" @@ -40,6 +40,7 @@ import os import os.path import shutil import stat +import string import time import types import sys @@ -93,7 +94,7 @@ def DefaultEnvironment(*args, **kw): _default_env.Decider('timestamp-match') global DefaultEnvironment DefaultEnvironment = _fetch_DefaultEnvironment - _default_env._CacheDir = SCons.CacheDir.Null() + _default_env._CacheDir_path = None return _default_env # Emitters for setting the shared attribute on object files, @@ -157,19 +158,36 @@ LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR") # ways by creating ActionFactory instances. ActionFactory = SCons.Action.ActionFactory -def chmod_func(path, mode): - return os.chmod(str(path), mode) +def get_paths_str(dest): + # If dest is a list, we need to manually call str() on each element + if SCons.Util.is_List(dest): + elem_strs = [] + for element in dest: + elem_strs.append('"' + str(element) + '"') + return '[' + string.join(elem_strs, ', ') + ']' + else: + return '"' + str(dest) + '"' -Chmod = ActionFactory(chmod_func, - lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode)) +def chmod_func(dest, mode): + SCons.Node.FS.invalidate_node_memos(dest) + if not SCons.Util.is_List(dest): + dest = [dest] + for element in dest: + os.chmod(str(element), mode) + +def chmod_strfunc(dest, mode): + return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode) + +Chmod = ActionFactory(chmod_func, chmod_strfunc) def copy_func(dest, src): + SCons.Node.FS.invalidate_node_memos(dest) if SCons.Util.is_List(src) and os.path.isdir(dest): for file in src: - shutil.copy(file, dest) + shutil.copy2(file, dest) return 0 elif os.path.isfile(src): - return shutil.copy(src, dest) + return shutil.copy2(src, dest) else: return shutil.copytree(src, dest, 1) @@ -177,40 +195,61 @@ Copy = ActionFactory(copy_func, lambda dest, src: 'Copy("%s", "%s")' % (dest, src), convert=str) -def delete_func(entry, must_exist=0): - entry = str(entry) - if not must_exist and not os.path.exists(entry): - return None - if not os.path.exists(entry) or os.path.isfile(entry): - return os.unlink(entry) - else: - return shutil.rmtree(entry, 1) +def delete_func(dest, must_exist=0): + SCons.Node.FS.invalidate_node_memos(dest) + if not SCons.Util.is_List(dest): + dest = [dest] + for entry in dest: + entry = str(entry) + if not must_exist and not os.path.exists(entry): + continue + if not os.path.exists(entry) or os.path.isfile(entry): + os.unlink(entry) + continue + else: + shutil.rmtree(entry, 1) + continue -def delete_strfunc(entry, must_exist=0): - return 'Delete("%s")' % entry +def delete_strfunc(dest, must_exist=0): + return 'Delete(%s)' % get_paths_str(dest) Delete = ActionFactory(delete_func, delete_strfunc) -Mkdir = ActionFactory(os.makedirs, - lambda dir: 'Mkdir("%s")' % dir, - convert=str) +def mkdir_func(dest): + SCons.Node.FS.invalidate_node_memos(dest) + if not SCons.Util.is_List(dest): + dest = [dest] + for entry in dest: + os.makedirs(str(entry)) -Move = ActionFactory(lambda dest, src: os.rename(src, dest), +Mkdir = ActionFactory(mkdir_func, + lambda dir: 'Mkdir(%s)' % get_paths_str(dir)) + +def move_func(dest, src): + SCons.Node.FS.invalidate_node_memos(dest) + SCons.Node.FS.invalidate_node_memos(src) + os.rename(src, dest) + +Move = ActionFactory(move_func, lambda dest, src: 'Move("%s", "%s")' % (dest, src), convert=str) -def touch_func(file): - file = str(file) - mtime = int(time.time()) - if os.path.exists(file): - atime = os.path.getatime(file) - else: - open(file, 'w') - atime = mtime - return os.utime(file, (atime, mtime)) +def touch_func(dest): + SCons.Node.FS.invalidate_node_memos(dest) + if not SCons.Util.is_List(dest): + dest = [dest] + for file in dest: + file = str(file) + mtime = int(time.time()) + if os.path.exists(file): + atime = os.path.getatime(file) + else: + open(file, 'w') + atime = mtime + os.utime(file, (atime, mtime)) Touch = ActionFactory(touch_func, - lambda file: 'Touch("%s")' % file) + lambda file: 'Touch(%s)' % get_paths_str(file)) # Internal utility functions @@ -224,9 +263,6 @@ def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None): if not list: return list - if SCons.Util.is_List(list): - list = SCons.Util.flatten(list) - l = f(SCons.PathList.PathList(list).subst_path(env, target, source)) if not l is None: list = l @@ -270,7 +306,7 @@ def _concat_ixes(prefix, list, suffix, env): return result -def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None): +def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None): """ This is a wrapper around _concat()/_concat_ixes() that checks for the existence of prefixes or suffixes on list elements and strips them @@ -292,22 +328,32 @@ def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None): else: c = _concat_ixes - if SCons.Util.is_List(list): - list = SCons.Util.flatten(list) + stripprefixes = map(env.subst, SCons.Util.flatten(stripprefixes)) + stripsuffixes = map(env.subst, SCons.Util.flatten(stripsuffixes)) - lsp = len(stripprefix) - lss = len(stripsuffix) stripped = [] for l in SCons.PathList.PathList(list).subst_path(env, None, None): if isinstance(l, SCons.Node.FS.File): stripped.append(l) continue + if not SCons.Util.is_String(l): l = str(l) - if l[:lsp] == stripprefix: - l = l[lsp:] - if l[-lss:] == stripsuffix: - l = l[:-lss] + + for stripprefix in stripprefixes: + lsp = len(stripprefix) + if l[:lsp] == stripprefix: + l = l[lsp:] + # Do not strip more than one prefix + break + + for stripsuffix in stripsuffixes: + lss = len(stripsuffix) + if l[-lss:] == stripsuffix: + l = l[:-lss] + # Do not strip more than one suffix + break + stripped.append(l) return c(prefix, stripped, suffix, env) @@ -378,7 +424,10 @@ class Variable_Method_Caller: self.method = method def __call__(self, *args, **kw): try: 1/0 - except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame + except ZeroDivisionError: + # Don't start iterating with the current stack-frame to + # prevent creating reference cycles (f_back is safe). + frame = sys.exc_info()[2].tb_frame.f_back variable = self.variable while frame: if frame.f_locals.has_key(variable): diff --git a/scons/scons-local-0.97.0d20071212/SCons/Environment.py b/scons/scons-local-1.2.0/SCons/Environment.py similarity index 86% rename from scons/scons-local-0.97.0d20071212/SCons/Environment.py rename to scons/scons-local-1.2.0/SCons/Environment.py index c3244795f..e1a8ec2c6 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Environment.py +++ b/scons/scons-local-1.2.0/SCons/Environment.py @@ -10,7 +10,7 @@ Environment """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -32,12 +32,13 @@ Environment # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Environment.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Environment.py 3842 2008/12/20 22:59:52 scons" import copy import os -import os.path +import sys +import re import shlex import string from UserDict import UserDict @@ -64,6 +65,10 @@ class _Null: _null = _Null +_warn_copy_deprecated = True +_warn_source_signatures_deprecated = True +_warn_target_signatures_deprecated = True + CleanTargets = {} CalculatorArgs = {} @@ -100,24 +105,40 @@ def apply_tools(env, tools, toolpath): else: env.Tool(tool) -# These names are controlled by SCons; users should never set or override -# them. This warning can optionally be turned off, but scons will still -# ignore the illegal variable names even if it's off. -reserved_construction_var_names = \ - ['TARGET', 'TARGETS', 'SOURCE', 'SOURCES'] +# These names are (or will be) controlled by SCons; users should never +# set or override them. This warning can optionally be turned off, +# but scons will still ignore the illegal variable names even if it's off. +reserved_construction_var_names = [ + 'SOURCE', + 'SOURCES', + 'TARGET', + 'TARGETS', +] + +future_reserved_construction_var_names = [ + 'CHANGED_SOURCES', + 'CHANGED_TARGETS', + 'UNCHANGED_SOURCES', + 'UNCHANGED_TARGETS', +] def copy_non_reserved_keywords(dict): result = semi_deepcopy(dict) for k in result.keys(): if k in reserved_construction_var_names: - SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, - "Ignoring attempt to set reserved variable `%s'" % k) + msg = "Ignoring attempt to set reserved variable `$%s'" + SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k) del result[k] return result def _set_reserved(env, key, value): - msg = "Ignoring attempt to set reserved variable `%s'" % key - SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg) + msg = "Ignoring attempt to set reserved variable `$%s'" + SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % key) + +def _set_future_reserved(env, key, value): + env._dict[key] = value + msg = "`$%s' will be reserved in a future release and setting it will become ignored" + SCons.Warnings.warn(SCons.Warnings.FutureReservedVariableWarning, msg % key) def _set_BUILDERS(env, key, value): try: @@ -137,6 +158,24 @@ def _set_SCANNERS(env, key, value): env._dict[key] = value env.scanner_map_delete() +def _delete_duplicates(l, keep_last): + """Delete duplicates from a sequence, keeping the first or last.""" + seen={} + result=[] + if keep_last: # reverse in & out, then keep first + l.reverse() + for i in l: + try: + if not seen.has_key(i): + result.append(i) + seen[i]=1 + except TypeError: + # probably unhashable. Just keep it. + result.append(i) + if keep_last: + result.reverse() + return result + # The following is partly based on code in a comment added by Peter @@ -225,7 +264,7 @@ class BuilderWrapper(MethodWrapper): elif name == 'builder': return self.method else: - return self.__dict__[name] + raise AttributeError, name def __setattr__(self, name, value): if name == 'env': @@ -279,6 +318,18 @@ class BuilderDict(UserDict): for i, v in dict.items(): self.__setitem__(i, v) + + +_is_valid_var = re.compile(r'[_a-zA-Z]\w*$') + +def is_valid_construction_var(varstr): + """Return if the specified string is a legitimate construction + variable. + """ + return _is_valid_var.match(varstr) + + + class SubstitutionEnvironment: """Base class for different flavors of construction environments. @@ -329,9 +380,16 @@ class SubstitutionEnvironment: self._special_set = {} for key in reserved_construction_var_names: self._special_set[key] = _set_reserved + for key in future_reserved_construction_var_names: + self._special_set[key] = _set_future_reserved self._special_set['BUILDERS'] = _set_BUILDERS self._special_set['SCANNERS'] = _set_SCANNERS + # Freeze the keys of self._special_set in a list for use by + # methods that need to check. (Empirically, list scanning has + # gotten better than dict.has_key() in Python 2.5.) + self._special_set_keys = self._special_set.keys() + def __cmp__(self, other): return cmp(self._dict, other._dict) @@ -346,12 +404,28 @@ class SubstitutionEnvironment: return self._dict[key] def __setitem__(self, key, value): - special = self._special_set.get(key) - if special: - special(self, key, value) + # This is heavily used. This implementation is the best we have + # according to the timings in bench/env.__setitem__.py. + # + # The "key in self._special_set_keys" test here seems to perform + # pretty well for the number of keys we have. A hard-coded + # list works a little better in Python 2.5, but that has the + # disadvantage of maybe getting out of sync if we ever add more + # variable names. Using self._special_set.has_key() works a + # little better in Python 2.4, but is worse then this test. + # So right now it seems like a good trade-off, but feel free to + # revisit this with bench/env.__setitem__.py as needed (and + # as newer versions of Python come out). + if key in self._special_set_keys: + self._special_set[key](self, key, value) else: - if not SCons.Util.is_valid_construction_var(key): - raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key + # If we already have the entry, then it's obviously a valid + # key and we don't need to check. If we do check, using a + # global, pre-compiled regular expression directly is more + # efficient than calling another function or a method. + if not self._dict.has_key(key) \ + and not _is_valid_var.match(key): + raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key self._dict[key] = value def get(self, key, default=None): @@ -361,6 +435,9 @@ class SubstitutionEnvironment: def has_key(self, key): return self._dict.has_key(key) + def __contains__(self, key): + return self._dict.__contains__(key) + def items(self): return self._dict.items() @@ -373,10 +450,7 @@ class SubstitutionEnvironment: if not args: return [] - if SCons.Util.is_List(args): - args = SCons.Util.flatten(args) - else: - args = [args] + args = SCons.Util.flatten(args) nodes = [] for v in args: @@ -465,7 +539,7 @@ class SubstitutionEnvironment: try: get = obj.get except AttributeError: - pass + obj = SCons.Util.to_String_for_subst(obj) else: obj = get() return obj @@ -481,7 +555,7 @@ class SubstitutionEnvironment: # We have an object plus a string, or multiple # objects that we need to smush together. No choice # but to make them into a string. - p = string.join(map(SCons.Util.to_String, p), '') + p = string.join(map(SCons.Util.to_String_for_subst, p), '') else: p = s(p) r.append(p) @@ -491,24 +565,21 @@ class SubstitutionEnvironment: def backtick(self, command): import subprocess - if SCons.Util.is_List(command): - p = subprocess.Popen(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) - else: - p = subprocess.Popen(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True, - shell=True) - out = p.stdout.read() - p.stdout.close() - err = p.stderr.read() - p.stderr.close() + # common arguments + kw = { 'stdin' : 'devnull', + 'stdout' : subprocess.PIPE, + 'stderr' : subprocess.PIPE, + 'universal_newlines' : True, + } + # if the command is a list, assume it's been quoted + # othewise force a shell + if not SCons.Util.is_List(command): kw['shell'] = True + # run constructed command + #TODO(1.5) p = SCons.Action._subproc(self, command, **kw) + p = apply(SCons.Action._subproc, (self, command), kw) + out,err = p.communicate() status = p.wait() if err: - import sys sys.stderr.write(err) if status: raise OSError("'%s' exited %d" % (command, status)) @@ -543,16 +614,19 @@ class SubstitutionEnvironment: environment, and doesn't even create a wrapper object if there are no overrides. """ - if overrides: - o = copy_non_reserved_keywords(overrides) - overrides = {} - for key, value in o.items(): + if not overrides: return self + o = copy_non_reserved_keywords(overrides) + if not o: return self + overrides = {} + merges = None + for key, value in o.items(): + if key == 'parse_flags': + merges = value + else: overrides[key] = SCons.Subst.scons_subst_once(value, self, key) - if overrides: - env = OverrideEnvironment(self, overrides) - return env - else: - return self + env = OverrideEnvironment(self, overrides) + if merges: env.MergeFlags(merges) + return env def ParseFlags(self, *flags): """ @@ -709,13 +783,16 @@ class SubstitutionEnvironment: do_parse(arg, do_parse) return dict - def MergeFlags(self, args, unique=1): + def MergeFlags(self, args, unique=1, dict=None): """ - Merge the dict in args into the construction variables. If args - is not a dict, it is converted into a dict using ParseFlags. - If unique is not set, the flags are appended rather than merged. + Merge the dict in args into the construction variables of this + env, or the passed-in dict. If args is not a dict, it is + converted into a dict using ParseFlags. If unique is not set, + the flags are appended rather than merged. """ + if dict is None: + dict = self if not SCons.Util.is_Dict(args): args = self.ParseFlags(args) if not unique: @@ -763,6 +840,26 @@ class SubstitutionEnvironment: self[key] = t return self +# def MergeShellPaths(self, args, prepend=1): +# """ +# Merge the dict in args into the shell environment in env['ENV']. +# Shell path elements are appended or prepended according to prepend. + +# Uses Pre/AppendENVPath, so it always appends or prepends uniquely. + +# Example: env.MergeShellPaths({'LIBPATH': '/usr/local/lib'}) +# prepends /usr/local/lib to env['ENV']['LIBPATH']. +# """ + +# for pathname, pathval in args.items(): +# if not pathval: +# continue +# if prepend: +# apply(self.PrependENVPath, (pathname, pathval)) +# else: +# apply(self.AppendENVPath, (pathname, pathval)) + + # Used by the FindSourceFiles() method, below. # Stuck here for support of pre-2.2 Python versions. def build_source(ss, result): @@ -819,7 +916,8 @@ class Base(SubstitutionEnvironment): platform=None, tools=None, toolpath=None, - options=None, + variables=None, + parse_flags = None, **kw): """ Initialization of a basic SCons construction environment, @@ -862,14 +960,19 @@ class Base(SubstitutionEnvironment): self._dict['PLATFORM'] = str(platform) platform(self) - # Apply the passed-in variables and customizable options to the + # Apply the passed-in and customizable variables to the # environment before calling the tools, because they may use # some of them during initialization. + if kw.has_key('options'): + # Backwards compatibility: they may stll be using the + # old "options" keyword. + variables = kw['options'] + del kw['options'] apply(self.Replace, (), kw) keys = kw.keys() - if options: - keys = keys + options.keys() - options.Update(self) + if variables: + keys = keys + variables.keys() + variables.Update(self) save = {} for k in keys: @@ -888,12 +991,15 @@ class Base(SubstitutionEnvironment): tools = ['default'] apply_tools(self, tools, toolpath) - # Now restore the passed-in variables and customized options + # Now restore the passed-in and customized variables # to the environment, since the values the user set explicitly # should override any values set by the tools. for key, val in save.items(): self._dict[key] = val + # Finally, apply any flags to be merged in + if parse_flags: self.MergeFlags(parse_flags) + ####################################################################### # Utility methods that are primarily for internal use by SCons. # These begin with lower-case letters. @@ -909,11 +1015,18 @@ class Base(SubstitutionEnvironment): def get_CacheDir(self): try: - return self._CacheDir + path = self._CacheDir_path except AttributeError: - cd = SCons.Defaults.DefaultEnvironment()._CacheDir - self._CacheDir = cd - return cd + path = SCons.Defaults.DefaultEnvironment()._CacheDir_path + try: + if path == self._last_CacheDir_path: + return self._last_CacheDir + except AttributeError: + pass + cd = SCons.CacheDir.CacheDir(path) + self._last_CacheDir_path = path + self._last_CacheDir = cd + return cd def get_factory(self, factory, default='File'): """Return a factory function for creating Nodes for this @@ -1085,31 +1198,39 @@ class Base(SubstitutionEnvironment): orig[val] = None self.scanner_map_delete(kw) - def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): + def AppendENVPath(self, name, newpath, envname = 'ENV', + sep = os.pathsep, delete_existing=1): """Append path elements to the path 'name' in the 'ENV' dictionary for this environment. Will only add any particular path once, and will normpath and normcase all paths to help assure this. This can also handle the case where the env variable is a list instead of a string. + + If delete_existing is 0, a newpath which is already in the path + will not be moved to the end (it will be left where it is). """ orig = '' if self._dict.has_key(envname) and self._dict[envname].has_key(name): orig = self._dict[envname][name] - nv = SCons.Util.AppendPath(orig, newpath, sep) + nv = SCons.Util.AppendPath(orig, newpath, sep, delete_existing) if not self._dict.has_key(envname): self._dict[envname] = {} self._dict[envname][name] = nv - def AppendUnique(self, **kw): + def AppendUnique(self, delete_existing=0, **kw): """Append values to existing construction variables in an Environment, if they're not already there. + If delete_existing is 1, removes existing values first, so + values move to end. """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): + if SCons.Util.is_List(val): + val = _delete_duplicates(val, delete_existing) if not self._dict.has_key(key) or self._dict[key] in ('', None): self._dict[key] = val elif SCons.Util.is_Dict(self._dict[key]) and \ @@ -1119,20 +1240,29 @@ class Base(SubstitutionEnvironment): dk = self._dict[key] if not SCons.Util.is_List(dk): dk = [dk] - val = filter(lambda x, dk=dk: x not in dk, val) + if delete_existing: + dk = filter(lambda x, val=val: x not in val, dk) + else: + val = filter(lambda x, dk=dk: x not in dk, val) self._dict[key] = dk + val else: dk = self._dict[key] if SCons.Util.is_List(dk): # By elimination, val is not a list. Since dk is a # list, wrap val in a list first. - if not val in dk: + if delete_existing: + dk = filter(lambda x, val=val: x not in val, dk) self._dict[key] = dk + [val] + else: + if not val in dk: + self._dict[key] = dk + [val] else: - self._dict[key] = self._dict[key] + val + if delete_existing: + dk = filter(lambda x, val=val: x not in val, dk) + self._dict[key] = dk + val self.scanner_map_delete(kw) - def Clone(self, tools=[], toolpath=None, **kw): + def Clone(self, tools=[], toolpath=None, parse_flags = None, **kw): """Return a copy of a construction Environment. The copy is like a Python "deep copy"--that is, independent copies are made recursively of each objects--except that @@ -1150,9 +1280,14 @@ class Base(SubstitutionEnvironment): else: clone._dict['BUILDERS'] = BuilderDict(cbd, clone) + # Check the methods added via AddMethod() and re-bind them to + # the cloned environment. Only do this if the attribute hasn't + # been overwritten by the user explicitly and still points to + # the added method. clone.added_methods = [] for mw in self.added_methods: - clone.added_methods.append(mw.clone(clone)) + if mw == getattr(self, mw.name): + clone.added_methods.append(mw.clone(clone)) clone._memo = {} @@ -1169,10 +1304,18 @@ class Base(SubstitutionEnvironment): # apply them again in case the tools overwrote them apply(clone.Replace, (), new) + # Finally, apply any flags to be merged in + if parse_flags: clone.MergeFlags(parse_flags) + if __debug__: logInstanceCreation(self, 'Environment.EnvironmentClone') return clone def Copy(self, *args, **kw): + global _warn_copy_deprecated + if _warn_copy_deprecated: + msg = "The env.Copy() method is deprecated; use the env.Clone() method instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedCopyWarning, msg) + _warn_copy_deprecated = False return apply(self.Clone, args, kw) def _changed_build(self, dependency, target, prev_ni): @@ -1410,31 +1553,39 @@ class Base(SubstitutionEnvironment): orig[val] = None self.scanner_map_delete(kw) - def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): + def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep, + delete_existing=1): """Prepend path elements to the path 'name' in the 'ENV' dictionary for this environment. Will only add any particular path once, and will normpath and normcase all paths to help assure this. This can also handle the case where the env variable is a list instead of a string. + + If delete_existing is 0, a newpath which is already in the path + will not be moved to the front (it will be left where it is). """ orig = '' if self._dict.has_key(envname) and self._dict[envname].has_key(name): orig = self._dict[envname][name] - nv = SCons.Util.PrependPath(orig, newpath, sep) + nv = SCons.Util.PrependPath(orig, newpath, sep, delete_existing) if not self._dict.has_key(envname): self._dict[envname] = {} self._dict[envname][name] = nv - def PrependUnique(self, **kw): - """Append values to existing construction variables + def PrependUnique(self, delete_existing=0, **kw): + """Prepend values to existing construction variables in an Environment, if they're not already there. + If delete_existing is 1, removes existing values first, so + values move to front. """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): + if SCons.Util.is_List(val): + val = _delete_duplicates(val, not delete_existing) if not self._dict.has_key(key) or self._dict[key] in ('', None): self._dict[key] = val elif SCons.Util.is_Dict(self._dict[key]) and \ @@ -1444,16 +1595,25 @@ class Base(SubstitutionEnvironment): dk = self._dict[key] if not SCons.Util.is_List(dk): dk = [dk] - val = filter(lambda x, dk=dk: x not in dk, val) + if delete_existing: + dk = filter(lambda x, val=val: x not in val, dk) + else: + val = filter(lambda x, dk=dk: x not in dk, val) self._dict[key] = val + dk else: dk = self._dict[key] if SCons.Util.is_List(dk): # By elimination, val is not a list. Since dk is a # list, wrap val in a list first. - if not val in dk: + if delete_existing: + dk = filter(lambda x, val=val: x not in val, dk) self._dict[key] = [val] + dk + else: + if not val in dk: + self._dict[key] = [val] + dk else: + if delete_existing: + dk = filter(lambda x, val=val: x not in val, dk) self._dict[key] = val + dk self.scanner_map_delete(kw) @@ -1532,6 +1692,7 @@ class Base(SubstitutionEnvironment): pass elif SCons.Util.is_String(pathext): pathext = self.subst(pathext) + prog = self.subst(prog) path = SCons.Util.WhereIs(prog, path, pathext, reject) if path: return path return None @@ -1634,10 +1795,11 @@ class Base(SubstitutionEnvironment): t.set_always_build() return tlist - def BuildDir(self, build_dir, src_dir, duplicate=1): - build_dir = self.arg2nodes(build_dir, self.fs.Dir)[0] - src_dir = self.arg2nodes(src_dir, self.fs.Dir)[0] - self.fs.BuildDir(build_dir, src_dir, duplicate) + def BuildDir(self, *args, **kw): + if kw.has_key('build_dir'): + kw['variant_dir'] = kw['build_dir'] + del kw['build_dir'] + return apply(self.VariantDir, args, kw) def Builder(self, **kw): nkw = self.subst_kw(kw) @@ -1645,10 +1807,9 @@ class Base(SubstitutionEnvironment): def CacheDir(self, path): import SCons.CacheDir - if path is None: - self._CacheDir = SCons.CacheDir.Null() - else: - self._CacheDir = SCons.CacheDir.CacheDir(self.subst(path)) + if not path is None: + path = self.subst(path) + self._CacheDir_path = path def Clean(self, targets, files): global CleanTargets @@ -1699,7 +1860,13 @@ class Base(SubstitutionEnvironment): def Dir(self, name, *args, **kw): """ """ - return apply(self.fs.Dir, (self.subst(name),) + args, kw) + s = self.subst(name) + if SCons.Util.is_Sequence(s): + result=[] + for e in s: + result.append(apply(self.fs.Dir, (e,) + args, kw)) + return result + return apply(self.fs.Dir, (s,) + args, kw) def NoClean(self, *targets): """Tags a target so that it will not be cleaned by -c""" @@ -1722,7 +1889,13 @@ class Base(SubstitutionEnvironment): def Entry(self, name, *args, **kw): """ """ - return apply(self.fs.Entry, (self.subst(name),) + args, kw) + s = self.subst(name) + if SCons.Util.is_Sequence(s): + result=[] + for e in s: + result.append(apply(self.fs.Entry, (e,) + args, kw)) + return result + return apply(self.fs.Entry, (s,) + args, kw) def Environment(self, **kw): return apply(SCons.Environment.Environment, [], self.subst_kw(kw)) @@ -1733,6 +1906,10 @@ class Base(SubstitutionEnvironment): action = apply(self.Action, (action,) + args, kw) result = action([], [], self) if isinstance(result, SCons.Errors.BuildError): + errstr = result.errstr + if result.filename: + errstr = result.filename + ': ' + errstr + sys.stderr.write("scons: *** %s\n" % errstr) return result.status else: return result @@ -1740,7 +1917,13 @@ class Base(SubstitutionEnvironment): def File(self, name, *args, **kw): """ """ - return apply(self.fs.File, (self.subst(name),) + args, kw) + s = self.subst(name) + if SCons.Util.is_Sequence(s): + result=[] + for e in s: + result.append(apply(self.fs.File, (e,) + args, kw)) + return result + return apply(self.fs.File, (s,) + args, kw) def FindFile(self, file, dirs): file = self.subst(file) @@ -1819,6 +2002,11 @@ class Base(SubstitutionEnvironment): name = self.subst(name) if not os.path.isabs(name): name = os.path.join(str(self.fs.SConstruct_dir), name) + if name: + name = os.path.normpath(name) + sconsign_dir = os.path.dirname(name) + if sconsign_dir and not os.path.exists(sconsign_dir): + self.Execute(SCons.Defaults.Mkdir(sconsign_dir)) SCons.SConsign.File(name, dbm_module) def SideEffect(self, side_effect, target): @@ -1845,6 +2033,12 @@ class Base(SubstitutionEnvironment): return entries def SourceSignatures(self, type): + global _warn_source_signatures_deprecated + if _warn_source_signatures_deprecated: + msg = "The env.SourceSignatures() method is deprecated;\n" + \ + "\tconvert your build to use the env.Decider() method instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedSourceSignaturesWarning, msg) + _warn_source_signatures_deprecated = False type = self.subst(type) self.src_sig_type = type if type == 'MD5': @@ -1875,6 +2069,12 @@ class Base(SubstitutionEnvironment): return [self.subst(arg)] def TargetSignatures(self, type): + global _warn_target_signatures_deprecated + if _warn_target_signatures_deprecated: + msg = "The env.TargetSignatures() method is deprecated;\n" + \ + "\tconvert your build to use the env.Decider() method instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedTargetSignaturesWarning, msg) + _warn_target_signatures_deprecated = False type = self.subst(type) self.tgt_sig_type = type if type in ('MD5', 'content'): @@ -1895,6 +2095,11 @@ class Base(SubstitutionEnvironment): """ return SCons.Node.Python.Value(value, built_value) + def VariantDir(self, variant_dir, src_dir, duplicate=1): + variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0] + src_dir = self.arg2nodes(src_dir, self.fs.Dir)[0] + self.fs.VariantDir(variant_dir, src_dir, duplicate) + def FindSourceFiles(self, node='.'): """ returns a list of all source files. """ @@ -1978,7 +2183,7 @@ class OverrideEnvironment(Base): except KeyError: return self.__dict__['__subject'].__getitem__(key) def __setitem__(self, key, value): - if not SCons.Util.is_valid_construction_var(key): + if not is_valid_construction_var(key): raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key self.__dict__['overrides'][key] = value def __delitem__(self, key): @@ -2007,6 +2212,10 @@ class OverrideEnvironment(Base): return 1 except KeyError: return self.__dict__['__subject'].has_key(key) + def __contains__(self, key): + if self.__dict__['overrides'].__contains__(key): + return 1 + return self.__dict__['__subject'].__contains__(key) def Dictionary(self): """Emulates the items() method of dictionaries.""" d = self.__dict__['__subject'].Dictionary().copy() diff --git a/scons/scons-local-1.2.0/SCons/Errors.py b/scons/scons-local-1.2.0/SCons/Errors.py new file mode 100644 index 000000000..8369873c7 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Errors.py @@ -0,0 +1,198 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +"""SCons.Errors + +This file contains the exception classes used to handle internal +and user errors in SCons. + +""" + +__revision__ = "src/engine/SCons/Errors.py 3842 2008/12/20 22:59:52 scons" + +import SCons.Util + +import exceptions + +class BuildError(Exception): + """ Errors occuring while building. + + BuildError have the following attributes: + + Information about the cause of the build error: + ----------------------------------------------- + + errstr : a description of the error message + + status : the return code of the action that caused the build + error. Must be set to a non-zero value even if the + build error is not due to an action returning a + non-zero returned code. + + exitstatus : SCons exit status due to this build error. + Must be nonzero unless due to an explicit Exit() + call. Not always the same as status, since + actions return a status code that should be + respected, but SCons typically exits with 2 + irrespective of the return value of the failed + action. + + filename : The name of the file or directory that caused the + build error. Set to None if no files are associated with + this error. This might be different from the target + being built. For example, failure to create the + directory in which the target file will appear. It + can be None if the error is not due to a particular + filename. + + exc_info : Info about exception that caused the build + error. Set to (None, None, None) if this build + error is not due to an exception. + + + Information about the cause of the location of the error: + --------------------------------------------------------- + + node : the error occured while building this target node(s) + + executor : the executor that caused the build to fail (might + be None if the build failures is not due to the + executor failing) + + action : the action that caused the build to fail (might be + None if the build failures is not due to the an + action failure) + + command : the command line for the action that caused the + build to fail (might be None if the build failures + is not due to the an action failure) + """ + + def __init__(self, + node=None, errstr="Unknown error", status=2, exitstatus=2, + filename=None, executor=None, action=None, command=None, + exc_info=(None, None, None)): + + self.errstr = errstr + self.status = status + self.exitstatus = exitstatus + self.filename = filename + self.exc_info = exc_info + + self.node = node + self.executor = executor + self.action = action + self.command = command + + Exception.__init__(self, node, errstr, status, exitstatus, filename, + executor, action, command, exc_info) + + def __str__(self): + if self.filename: + return self.filename + ': ' + self.errstr + else: + return self.errstr + +class InternalError(Exception): + pass + +class UserError(Exception): + pass + +class StopError(Exception): + pass + +class EnvironmentError(Exception): + pass + +class ExplicitExit(Exception): + def __init__(self, node=None, status=None, *args): + self.node = node + self.status = status + self.exitstatus = status + apply(Exception.__init__, (self,) + args) + +def convert_to_BuildError(status, exc_info=None): + """ + Convert any return code a BuildError Exception. + + `status' can either be a return code or an Exception. + The buildError.status we set here will normally be + used as the exit status of the "scons" process. + """ + if not exc_info and isinstance(status, Exception): + exc_info = (status.__class__, status, None) + + if isinstance(status, BuildError): + buildError = status + buildError.exitstatus = 2 # always exit with 2 on build errors + elif isinstance(status, ExplicitExit): + status = status.status + errstr = 'Explicit exit, status %s' % status + buildError = BuildError( + errstr=errstr, + status=status, # might be 0, OK here + exitstatus=status, # might be 0, OK here + exc_info=exc_info) + # TODO(1.5): + #elif isinstance(status, (StopError, UserError)): + elif isinstance(status, StopError) or isinstance(status, UserError): + buildError = BuildError( + errstr=str(status), + status=2, + exitstatus=2, + exc_info=exc_info) + elif isinstance(status, exceptions.EnvironmentError): + # If an IOError/OSError happens, raise a BuildError. + # Report the name of the file or directory that caused the + # error, which might be different from the target being built + # (for example, failure to create the directory in which the + # target file will appear). + try: filename = status.filename + except AttributeError: filename = None + buildError = BuildError( + errstr=status.strerror, + status=status.errno, + exitstatus=2, + filename=filename, + exc_info=exc_info) + elif isinstance(status, Exception): + buildError = BuildError( + errstr='%s : %s' % (status.__class__.__name__, status), + status=2, + exitstatus=2, + exc_info=exc_info) + elif SCons.Util.is_String(status): + buildError = BuildError( + errstr=status, + status=2, + exitstatus=2) + else: + buildError = BuildError( + errstr="Error %s" % status, + status=status, + exitstatus=2) + + #import sys + #sys.stderr.write("convert_to_BuildError: status %s => (errstr %s, status %s)"%(status,buildError.errstr, buildError.status)) + return buildError diff --git a/scons/scons-local-0.97.0d20071212/SCons/Executor.py b/scons/scons-local-1.2.0/SCons/Executor.py similarity index 78% rename from scons/scons-local-0.97.0d20071212/SCons/Executor.py rename to scons/scons-local-1.2.0/SCons/Executor.py index f7179768c..a37da0719 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Executor.py +++ b/scons/scons-local-1.2.0/SCons/Executor.py @@ -6,7 +6,7 @@ Nodes. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,7 +28,7 @@ Nodes. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Executor.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Executor.py 3842 2008/12/20 22:59:52 scons" import string @@ -134,7 +134,11 @@ class Executor: raise status elif status: msg = "Error %s" % status - raise SCons.Errors.BuildError(errstr=msg, executor=self, action=act) + raise SCons.Errors.BuildError( + errstr=msg, + node=self.targets, + executor=self, + action=act) return status # use extra indirection because with new-style objects (Python 2.2 @@ -160,6 +164,16 @@ class Executor: self.sources_need_sorting = False return self.sources + def prepare(self): + """ + Preparatory checks for whether this Executor can go ahead + and (try to) build its targets. + """ + for s in self.get_sources(): + if s.missing(): + msg = "Source `%s' not found, needed by target `%s'." + raise SCons.Errors.StopError, msg % (s, self.targets[0]) + def add_pre_action(self, action): self.pre_actions.append(action) @@ -221,40 +235,35 @@ class Executor: This essentially short-circuits an N*M scan of the sources for each individual target, which is a hell of a lot more efficient. """ - map(lambda N: N.disambiguate(), node_list) - env = self.get_build_env() - select_specific_scanner = lambda t: (t[0], t[1].select(t[0])) - remove_null_scanners = lambda t: not t[1] is None - add_scanner_path = lambda t, s=self: \ - (t[0], t[1], s.get_build_scanner_path(t[1])) - if scanner: - scanner_list = map(lambda n, s=scanner: (n, s), node_list) - else: - kw = self.get_kw() - get_initial_scanners = lambda n, e=env, kw=kw: \ - (n, n.get_env_scanner(e, kw)) - scanner_list = map(get_initial_scanners, node_list) - scanner_list = filter(remove_null_scanners, scanner_list) - - scanner_list = map(select_specific_scanner, scanner_list) - scanner_list = filter(remove_null_scanners, scanner_list) - scanner_path_list = map(add_scanner_path, scanner_list) deps = [] - for node, scanner, path in scanner_path_list: - deps.extend(node.get_implicit_deps(env, scanner, path)) + if scanner: + for node in node_list: + node.disambiguate() + s = scanner.select(node) + if not s: + continue + path = self.get_build_scanner_path(s) + deps.extend(node.get_implicit_deps(env, s, path)) + else: + kw = self.get_kw() + for node in node_list: + node.disambiguate() + scanner = node.get_env_scanner(env, kw) + if not scanner: + continue + scanner = scanner.select(node) + if not scanner: + continue + path = self.get_build_scanner_path(scanner) + deps.extend(node.get_implicit_deps(env, scanner, path)) deps.extend(self.get_implicit_deps()) for tgt in self.targets: tgt.add_to_implicit(deps) - def get_missing_sources(self): - """ - """ - return filter(lambda s: s.missing(), self.get_sources()) - def _get_unignored_sources_key(self, ignore=()): return tuple(ignore) @@ -317,10 +326,25 @@ class Executor: result.extend(act.get_implicit_deps(self.targets, self.get_sources(), build_env)) return result +nullenv = None -_Executor = Executor +def get_NullEnvironment(): + """Use singleton pattern for Null Environments.""" + global nullenv -class Null(_Executor): + import SCons.Util + class NullEnvironment(SCons.Util.Null): + import SCons.CacheDir + _CacheDir_path = None + _CacheDir = SCons.CacheDir.CacheDir(None) + def get_CacheDir(self): + return self._CacheDir + + if not nullenv: + nullenv = NullEnvironment() + return nullenv + +class Null: """A null Executor, with a null build Environment, that does nothing when the rest of the methods call it. @@ -330,20 +354,40 @@ class Null(_Executor): """ def __init__(self, *args, **kw): if __debug__: logInstanceCreation(self, 'Executor.Null') - kw['action'] = [] - apply(_Executor.__init__, (self,), kw) + self.targets = kw['targets'] def get_build_env(self): - import SCons.Util - class NullEnvironment(SCons.Util.Null): - #def get_scanner(self, key): - # return None - #def changed_since_last_build(self, dependency, target, prev_ni): - # return dependency.changed_since_last_buld(target, prev_ni) - def get_CacheDir(self): - import SCons.CacheDir - return SCons.CacheDir.Null() - return NullEnvironment() + return get_NullEnvironment() def get_build_scanner_path(self): return None def cleanup(self): pass + def prepare(self): + pass + def get_unignored_sources(self, *args, **kw): + return tuple(()) + def get_action_list(self): + return [] + def __call__(self, *args, **kw): + return 0 + def get_contents(self): + return '' + + def _morph(self): + """Morph this Null executor to a real Executor object.""" + self.__class__ = Executor + self.__init__([], targets=self.targets) + + # The following methods require morphing this Null Executor to a + # real Executor object. + + def add_pre_action(self, action): + self._morph() + self.add_pre_action(action) + def add_post_action(self, action): + self._morph() + self.add_post_action(action) + def set_action_list(self, action): + self._morph() + self.set_action_list(action) + + diff --git a/scons/scons-local-0.97.0d20071212/SCons/Job.py b/scons/scons-local-1.2.0/SCons/Job.py similarity index 58% rename from scons/scons-local-0.97.0d20071212/SCons/Job.py rename to scons/scons-local-1.2.0/SCons/Job.py index b0252c959..bcd39819a 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Job.py +++ b/scons/scons-local-1.2.0/SCons/Job.py @@ -7,7 +7,7 @@ stop, and wait on jobs. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +29,37 @@ stop, and wait on jobs. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Job.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Job.py 3842 2008/12/20 22:59:52 scons" + +import os +import signal + +import SCons.Errors + +# The default stack size (in kilobytes) of the threads used to execute +# jobs in parallel. +# +# We use a stack size of 256 kilobytes. The default on some platforms +# is too large and prevents us from creating enough threads to fully +# parallelized the build. For example, the default stack size on linux +# is 8 MBytes. + +explicit_stack_size = None +default_stack_size = 256 + +interrupt_msg = 'Build interrupted.' + + +class InterruptState: + def __init__(self): + self.interrupted = False + + def set(self): + self.interrupted = True + + def __call__(self): + return self.interrupted -import SCons.compat class Jobs: """An instance of this class initializes N jobs, and provides @@ -54,8 +82,12 @@ class Jobs: self.job = None if num > 1: + stack_size = explicit_stack_size + if stack_size is None: + stack_size = default_stack_size + try: - self.job = Parallel(taskmaster, num) + self.job = Parallel(taskmaster, num, stack_size) self.num_jobs = num except NameError: pass @@ -63,21 +95,71 @@ class Jobs: self.job = Serial(taskmaster) self.num_jobs = 1 - def run(self): - """run the job""" + def run(self, postfunc=lambda: None): + """Run the jobs. + + postfunc() will be invoked after the jobs has run. It will be + invoked even if the jobs are interrupted by a keyboard + interrupt (well, in fact by a signal such as either SIGINT, + SIGTERM or SIGHUP). The execution of postfunc() is protected + against keyboard interrupts and is guaranteed to run to + completion.""" + self._setup_sig_handler() try: self.job.start() - except KeyboardInterrupt: - # mask any further keyboard interrupts so that scons - # can shutdown cleanly: - # (this only masks the keyboard interrupt for Python, - # child processes can still get the keyboard interrupt) - import signal - signal.signal(signal.SIGINT, signal.SIG_IGN) - raise + finally: + postfunc() + self._reset_sig_handler() - def cleanup(self): - self.job.cleanup() + def were_interrupted(self): + """Returns whether the jobs were interrupted by a signal.""" + return self.job.interrupted() + + def _setup_sig_handler(self): + """Setup an interrupt handler so that SCons can shutdown cleanly in + various conditions: + + a) SIGINT: Keyboard interrupt + b) SIGTERM: kill or system shutdown + c) SIGHUP: Controlling shell exiting + + We handle all of these cases by stopping the taskmaster. It + turns out that it very difficult to stop the build process + by throwing asynchronously an exception such as + KeyboardInterrupt. For example, the python Condition + variables (threading.Condition) and Queue's do not seem to + asynchronous-exception-safe. It would require adding a whole + bunch of try/finally block and except KeyboardInterrupt all + over the place. + + Note also that we have to be careful to handle the case when + SCons forks before executing another process. In that case, we + want the child to exit immediately. + """ + def handler(signum, stack, self=self, parentpid=os.getpid()): + if os.getpid() == parentpid: + self.job.taskmaster.stop() + self.job.interrupted.set() + else: + os._exit(2) + + self.old_sigint = signal.signal(signal.SIGINT, handler) + self.old_sigterm = signal.signal(signal.SIGTERM, handler) + try: + self.old_sighup = signal.signal(signal.SIGHUP, handler) + except AttributeError: + pass + + def _reset_sig_handler(self): + """Restore the signal handlers to their previous state (before the + call to _setup_sig_handler().""" + + signal.signal(signal.SIGINT, self.old_sigint) + signal.signal(signal.SIGTERM, self.old_sigterm) + try: + signal.signal(signal.SIGHUP, self.old_sighup) + except AttributeError: + pass class Serial: """This class is used to execute tasks in series, and is more efficient @@ -97,6 +179,7 @@ class Serial: execute (e.g. execute() raised an exception).""" self.taskmaster = taskmaster + self.interrupted = InterruptState() def start(self): """Start the job. This will begin pulling tasks from the taskmaster @@ -112,11 +195,18 @@ class Serial: try: task.prepare() - task.execute() - except KeyboardInterrupt: - raise + if task.needs_execute(): + task.execute() except: - task.exception_set() + if self.interrupted(): + try: + raise SCons.Errors.BuildError( + task.targets[0], errstr=interrupt_msg) + except: + task.exception_set() + else: + task.exception_set() + # Let the failed() callback function arrange for the # build to stop if that's appropriate. task.failed() @@ -124,9 +214,8 @@ class Serial: task.executed() task.postprocess() + self.taskmaster.cleanup() - def cleanup(self): - pass # Trap import failure so that everything in the Job module but the # Parallel class (and its dependent classes) will work if the interpreter @@ -142,28 +231,29 @@ else: dequeues the task, executes it, and posts a tuple including the task and a boolean indicating whether the task executed successfully. """ - def __init__(self, requestQueue, resultsQueue): + def __init__(self, requestQueue, resultsQueue, interrupted): threading.Thread.__init__(self) self.setDaemon(1) self.requestQueue = requestQueue self.resultsQueue = resultsQueue + self.interrupted = interrupted self.start() def run(self): while 1: task = self.requestQueue.get() - if not task: + if task is None: # The "None" value is used as a sentinel by # ThreadPool.cleanup(). This indicates that there # are no more tasks, so we should quit. break try: + if self.interrupted(): + raise SCons.Errors.BuildError( + task.targets[0], errstr=interrupt_msg) task.execute() - except KeyboardInterrupt: - # be explicit here for test/interrupts.py - ok = False except: task.exception_set() ok = False @@ -175,27 +265,49 @@ else: class ThreadPool: """This class is responsible for spawning and managing worker threads.""" - def __init__(self, num): - """Create the request and reply queues, and 'num' worker threads.""" + def __init__(self, num, stack_size, interrupted): + """Create the request and reply queues, and 'num' worker threads. + + One must specify the stack size of the worker threads. The + stack size is specified in kilobytes. + """ self.requestQueue = Queue.Queue(0) self.resultsQueue = Queue.Queue(0) + try: + prev_size = threading.stack_size(stack_size*1024) + except AttributeError, e: + # Only print a warning if the stack size has been + # explicitly set. + if not explicit_stack_size is None: + msg = "Setting stack size is unsupported by this version of Python:\n " + \ + e.args[0] + SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg) + except ValueError, e: + msg = "Setting stack size failed:\n " + str(e) + SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg) + # Create worker threads self.workers = [] for _ in range(num): - worker = Worker(self.requestQueue, self.resultsQueue) + worker = Worker(self.requestQueue, self.resultsQueue, interrupted) self.workers.append(worker) - def put(self, obj): + # Once we drop Python 1.5 we can change the following to: + #if 'prev_size' in locals(): + if 'prev_size' in locals().keys(): + threading.stack_size(prev_size) + + def put(self, task): """Put task into request queue.""" - self.requestQueue.put(obj) + self.requestQueue.put(task) - def get(self, block = True): + def get(self): """Remove and return a result tuple from the results queue.""" - return self.resultsQueue.get(block) + return self.resultsQueue.get() - def preparation_failed(self, obj): - self.resultsQueue.put((obj, False)) + def preparation_failed(self, task): + self.resultsQueue.put((task, False)) def cleanup(self): """ @@ -233,7 +345,7 @@ else: This class is thread safe. """ - def __init__(self, taskmaster, num): + def __init__(self, taskmaster, num, stack_size): """Create a new parallel job given a taskmaster. The taskmaster's next_task() method should return the next @@ -249,7 +361,8 @@ else: multiple tasks simultaneously. """ self.taskmaster = taskmaster - self.tp = ThreadPool(num) + self.interrupted = InterruptState() + self.tp = ThreadPool(num, stack_size, self.interrupted) self.maxjobs = num @@ -269,22 +382,21 @@ else: if task is None: break - # prepare task for execution try: + # prepare task for execution task.prepare() - except KeyboardInterrupt: - raise except: - # Let the failed() callback function arrange - # for the build to stop if that's appropriate. task.exception_set() - self.tp.preparation_failed(task) - jobs = jobs + 1 - continue - - # dispatch task - self.tp.put(task) - jobs = jobs + 1 + task.failed() + task.postprocess() + else: + if task.needs_execute(): + # dispatch task + self.tp.put(task) + jobs = jobs + 1 + else: + task.executed() + task.postprocess() if not task and not jobs: break @@ -292,11 +404,20 @@ else: # back and put the next batch of tasks on the queue. while 1: task, ok = self.tp.get() - jobs = jobs - 1 + if ok: task.executed() else: + if self.interrupted(): + try: + raise SCons.Errors.BuildError( + task.targets[0], errstr=interrupt_msg) + except: + task.exception_set() + + # Let the failed() callback function arrange + # for the build to stop if that's appropriate. task.failed() task.postprocess() @@ -304,5 +425,5 @@ else: if self.tp.resultsQueue.empty(): break - def cleanup(self): self.tp.cleanup() + self.taskmaster.cleanup() diff --git a/scons/scons-local-0.97.0d20071212/SCons/Memoize.py b/scons/scons-local-1.2.0/SCons/Memoize.py similarity index 90% rename from scons/scons-local-0.97.0d20071212/SCons/Memoize.py rename to scons/scons-local-1.2.0/SCons/Memoize.py index ad3d99b5a..f79dd6b93 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Memoize.py +++ b/scons/scons-local-1.2.0/SCons/Memoize.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Memoize.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Memoize.py 3842 2008/12/20 22:59:52 scons" __doc__ = """Memoizer @@ -217,33 +217,47 @@ class Memoizer: class M: def __init__(cls, name, bases, cls_dict): - cls.has_metaclass = 1 - -class A: - __metaclass__ = M + cls.use_metaclass = 1 + def fake_method(self): + pass + new.instancemethod(fake_method, None, cls) try: - has_metaclass = A.has_metaclass + class A: + __metaclass__ = M + + use_metaclass = A.use_metaclass except AttributeError: - has_metaclass = None + use_metaclass = None + reason = 'no metaclasses' +except TypeError: + use_metaclass = None + reason = 'new.instancemethod() bug' +else: + del A del M -del A -if not has_metaclass: +if not use_metaclass: def Dump(title): pass - class Memoized_Metaclass: - # Just a place-holder so pre-metaclass Python versions don't - # have to have special code for the Memoized classes. - pass + try: + class Memoized_Metaclass(type): + # Just a place-holder so pre-metaclass Python versions don't + # have to have special code for the Memoized classes. + pass + except TypeError: + class Memoized_Metaclass: + # A place-holder so pre-metaclass Python versions don't + # have to have special code for the Memoized classes. + pass def EnableMemoization(): import SCons.Warnings - msg = 'memoization is not supported in this version of Python (no metaclasses)' - raise SCons.Warnings.NoMetaclassSupportWarning, msg + msg = 'memoization is not supported in this version of Python (%s)' + raise SCons.Warnings.NoMetaclassSupportWarning, msg % reason else: diff --git a/scons/scons-local-0.97.0d20071212/SCons/Node/Alias.py b/scons/scons-local-1.2.0/SCons/Node/Alias.py similarity index 94% rename from scons/scons-local-0.97.0d20071212/SCons/Node/Alias.py rename to scons/scons-local-1.2.0/SCons/Node/Alias.py index ae2398f99..4ce9fff7d 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Node/Alias.py +++ b/scons/scons-local-1.2.0/SCons/Node/Alias.py @@ -8,7 +8,7 @@ This creates a hash of global Aliases (dummy targets). """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ This creates a hash of global Aliases (dummy targets). # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/Alias.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Node/Alias.py 3842 2008/12/20 22:59:52 scons" import string import UserDict @@ -74,6 +74,9 @@ class Alias(SCons.Node.Node): SCons.Node.Node.__init__(self) self.name = name + def str_for_display(self): + return '"' + self.__str__() + '"' + def __str__(self): return self.name diff --git a/scons/scons-local-0.97.0d20071212/SCons/Node/FS.py b/scons/scons-local-1.2.0/SCons/Node/FS.py similarity index 87% rename from scons/scons-local-0.97.0d20071212/SCons/Node/FS.py rename to scons/scons-local-1.2.0/SCons/Node/FS.py index 43ff0da9a..15368f029 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Node/FS.py +++ b/scons/scons-local-1.2.0/SCons/Node/FS.py @@ -11,7 +11,7 @@ that can be used by scripts or modules looking for the canonical default. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -33,9 +33,10 @@ that can be used by scripts or modules looking for the canonical default. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/FS.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Node/FS.py 3842 2008/12/20 22:59:52 scons" import fnmatch +from itertools import izip import os import os.path import re @@ -58,6 +59,25 @@ import SCons.Warnings from SCons.Debug import Trace +do_store_info = True + + +class EntryProxyAttributeError(AttributeError): + """ + An AttributeError subclass for recording and displaying the name + of the underlying Entry involved in an AttributeError exception. + """ + def __init__(self, entry_proxy, attribute): + AttributeError.__init__(self) + self.entry_proxy = entry_proxy + self.attribute = attribute + def __str__(self): + entry = self.entry_proxy.get() + fmt = "%s instance %s has no attribute %s" + return fmt % (entry.__class__.__name__, + repr(entry.name), + repr(self.attribute)) + # The max_drift value: by default, use a cached signature value for # any file that's been untouched for more than two days. default_max_drift = 2*24*60*60 @@ -73,10 +93,10 @@ default_max_drift = 2*24*60*60 # # A number of the above factors, however, can be set after we've already # been asked to return a string for a Node, because a Repository() or -# BuildDir() call or the like may not occur until later in SConscript +# VariantDir() call or the like may not occur until later in SConscript # files. So this variable controls whether we bother trying to save # string values for Nodes. The wrapper interface can set this whenever -# they're done mucking with Repository and BuildDir and the other stuff, +# they're done mucking with Repository and VariantDir and the other stuff, # to let this module know it can start returning saved string values # for Nodes. # @@ -222,8 +242,6 @@ def LinkFunc(target, source, env): if func == Link_Funcs[-1]: # exception of the last link method (copy) are fatal raise - else: - pass return 0 Link = SCons.Action.Action(LinkFunc, None) @@ -445,7 +463,7 @@ class EntryProxy(SCons.Util.Proxy): def __get_srcdir(self): """Returns the directory containing the source node linked to this - node via BuildDir(), or the directory of this node if not linked.""" + node via VariantDir(), or the directory of this node if not linked.""" return EntryProxy(self.get().srcnode().dir) def __get_rsrcnode(self): @@ -453,7 +471,7 @@ class EntryProxy(SCons.Util.Proxy): def __get_rsrcdir(self): """Returns the directory containing the source node linked to this - node via BuildDir(), or the directory of this node if not linked.""" + node via VariantDir(), or the directory of this node if not linked.""" return EntryProxy(self.get().srcnode().rfile().dir) def __get_dir(self): @@ -482,16 +500,11 @@ class EntryProxy(SCons.Util.Proxy): except KeyError: try: attr = SCons.Util.Proxy.__getattr__(self, name) - except AttributeError: - entry = self.get() - classname = string.split(str(entry.__class__), '.')[-1] - if classname[-2:] == "'>": - # new-style classes report their name as: - # "" - # instead of the classic classes: - # "something" - classname = classname[:-2] - raise AttributeError, "%s instance '%s' has no attribute '%s'" % (classname, entry.name, name) + except AttributeError, e: + # Raise our own AttributeError subclass with an + # overridden __str__() method that identifies the + # name of the entry that caused the exception. + raise EntryProxyAttributeError(self, name) return attr else: return attr_function(self) @@ -543,6 +556,9 @@ class Base(SCons.Node.Node): self.cwd = None # will hold the SConscript directory for target nodes self.duplicate = directory.duplicate + def str_for_display(self): + return '"' + self.__str__() + '"' + def must_be_same(self, klass): """ This node, which already existed, is being looked up as the @@ -586,7 +602,7 @@ class Base(SCons.Node.Node): if self.duplicate or self.is_derived(): return self.get_path() srcnode = self.srcnode() - if srcnode.stat() is None and not self.stat() is None: + if srcnode.stat() is None and self.stat() is not None: result = self.get_path() else: result = srcnode.get_path() @@ -601,7 +617,7 @@ class Base(SCons.Node.Node): # values that the underlying stat() method saved. try: del self._memo['stat'] except KeyError: pass - if not self is srcnode: + if self is not srcnode: try: del srcnode._memo['stat'] except KeyError: pass return result @@ -619,7 +635,7 @@ class Base(SCons.Node.Node): return result def exists(self): - return not self.stat() is None + return self.stat() is not None def rexists(self): return self.rfile().exists() @@ -636,11 +652,11 @@ class Base(SCons.Node.Node): def isdir(self): st = self.stat() - return not st is None and stat.S_ISDIR(st[stat.ST_MODE]) + return st is not None and stat.S_ISDIR(st[stat.ST_MODE]) def isfile(self): st = self.stat() - return not st is None and stat.S_ISREG(st[stat.ST_MODE]) + return st is not None and stat.S_ISREG(st[stat.ST_MODE]) if hasattr(os, 'symlink'): def islink(self): @@ -880,10 +896,10 @@ class Entry(Base): def must_be_same(self, klass): """Called to make sure a Node is a Dir. Since we're an Entry, we can morph into one.""" - if not self.__class__ is klass: + if self.__class__ is not klass: self.__class__ = klass self._morph() - self.clear + self.clear() # The following methods can get called before the Taskmaster has # had a chance to call disambiguate() directly to see if this Entry @@ -904,7 +920,7 @@ class Entry(Base): def rel_path(self, other): d = self.disambiguate() - if d.__class__ == Entry: + if d.__class__ is Entry: raise "rel_path() could not disambiguate File/Dir" return d.rel_path(other) @@ -1059,7 +1075,7 @@ class FS(LocalFS): """ curr=self._cwd try: - if not dir is None: + if dir is not None: self._cwd = dir if change_os_dir: os.chdir(dir.abspath) @@ -1165,7 +1181,7 @@ class FS(LocalFS): return root._lookup_abs(p, fsclass, create) def Entry(self, name, directory = None, create = 1): - """Lookup or create a generic Entry node with the specified name. + """Look up or create a generic Entry node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory node, or to the top level directory of the FS (supplied at @@ -1174,7 +1190,7 @@ class FS(LocalFS): return self._lookup(name, directory, Entry, create) def File(self, name, directory = None, create = 1): - """Lookup or create a File node with the specified name. If + """Look up or create a File node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory node, or to the top level directory of the FS (supplied at construction @@ -1186,7 +1202,7 @@ class FS(LocalFS): return self._lookup(name, directory, File, create) def Dir(self, name, directory = None, create = True): - """Lookup or create a Dir node with the specified name. If + """Look up or create a Dir node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory node, or to the top level directory of the FS (supplied at construction @@ -1197,21 +1213,21 @@ class FS(LocalFS): """ return self._lookup(name, directory, Dir, create) - def BuildDir(self, build_dir, src_dir, duplicate=1): - """Link the supplied build directory to the source directory + def VariantDir(self, variant_dir, src_dir, duplicate=1): + """Link the supplied variant directory to the source directory for purposes of building files.""" if not isinstance(src_dir, SCons.Node.Node): src_dir = self.Dir(src_dir) - if not isinstance(build_dir, SCons.Node.Node): - build_dir = self.Dir(build_dir) - if src_dir.is_under(build_dir): - raise SCons.Errors.UserError, "Source directory cannot be under build directory." - if build_dir.srcdir: - if build_dir.srcdir == src_dir: + if not isinstance(variant_dir, SCons.Node.Node): + variant_dir = self.Dir(variant_dir) + if src_dir.is_under(variant_dir): + raise SCons.Errors.UserError, "Source directory cannot be under variant directory." + if variant_dir.srcdir: + if variant_dir.srcdir == src_dir: return # We already did this. - raise SCons.Errors.UserError, "'%s' already has a source directory: '%s'."%(build_dir, build_dir.srcdir) - build_dir.link(src_dir, duplicate) + raise SCons.Errors.UserError, "'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir) + variant_dir.link(src_dir, duplicate) def Repository(self, *dirs): """Specify Repository directories to search.""" @@ -1220,11 +1236,11 @@ class FS(LocalFS): d = self.Dir(d) self.Top.addRepository(d) - def build_dir_target_climb(self, orig, dir, tail): - """Create targets in corresponding build directories + def variant_dir_target_climb(self, orig, dir, tail): + """Create targets in corresponding variant directories Climb the directory tree, and look up path names - relative to any linked build directories we find. + relative to any linked variant directories we find. Even though this loops and walks up the tree, we don't memoize the return value because this is really only used to process @@ -1232,10 +1248,10 @@ class FS(LocalFS): """ targets = [] message = None - fmt = "building associated BuildDir targets: %s" + fmt = "building associated VariantDir targets: %s" start_dir = dir while dir: - for bd in dir.build_dirs: + for bd in dir.variant_dirs: if start_dir.is_under(bd): # If already in the build-dir location, don't reflect return [orig], fmt % str(orig) @@ -1314,7 +1330,7 @@ class Dir(Base): self.cwd = self self.searched = 0 self._sconsign = None - self.build_dirs = [] + self.variant_dirs = [] self.root = self.dir.root # Don't just reset the executor, replace its action list, @@ -1342,7 +1358,7 @@ class Dir(Base): del node._srcreps except AttributeError: pass - if duplicate != None: + if duplicate is not None: node.duplicate=duplicate def __resetDuplicate(self, node): @@ -1361,8 +1377,7 @@ class Dir(Base): Looks up or creates a directory node named 'name' relative to this directory. """ - dir = self.fs.Dir(name, self, create) - return dir + return self.fs.Dir(name, self, create) def File(self, name): """ @@ -1385,16 +1400,16 @@ class Dir(Base): a path containing '..'), an absolute path name, a top-relative ('#foo') path name, or any kind of object. """ - name = self.labspath + '/' + name + name = self.entry_labspath(name) return self.root._lookup_abs(name, klass, create) def link(self, srcdir, duplicate): - """Set this directory as the build directory for the + """Set this directory as the variant directory for the supplied source directory.""" self.srcdir = srcdir self.duplicate = duplicate self.__clearRepositoryCache(duplicate) - srcdir.build_dirs.append(self) + srcdir.variant_dirs.append(self) def getRepositories(self): """Returns a list of repositories for this directory. @@ -1407,7 +1422,7 @@ class Dir(Base): def get_all_rdirs(self): try: - return self._memo['get_all_rdirs'] + return list(self._memo['get_all_rdirs']) except KeyError: pass @@ -1423,7 +1438,7 @@ class Dir(Base): fname = dir.name + os.sep + fname dir = dir.up() - self._memo['get_all_rdirs'] = result + self._memo['get_all_rdirs'] = list(result) return result @@ -1445,15 +1460,15 @@ class Dir(Base): """Return a path to "other" relative to this directory. """ - # This complicated and expensive method, which constructs relative - # paths between arbitrary Node.FS objects, is no longer used - # by SCons itself. It was introduced to store dependency paths - # in .sconsign files relative to the target, but that ended up - # being significantly inefficient. + # This complicated and expensive method, which constructs relative + # paths between arbitrary Node.FS objects, is no longer used + # by SCons itself. It was introduced to store dependency paths + # in .sconsign files relative to the target, but that ended up + # being significantly inefficient. # - # We're continuing to support the method because some SConstruct - # files out there started using it when it was available, and - # we're all about backwards compatibility.. + # We're continuing to support the method because some SConstruct + # files out there started using it when it was available, and + # we're all about backwards compatibility.. try: memo_dict = self._memo['rel_path'] @@ -1467,11 +1482,9 @@ class Dir(Base): pass if self is other: - result = '.' elif not other in self.path_elements: - try: other_dir = other.get_dir() except AttributeError: @@ -1485,9 +1498,7 @@ class Dir(Base): result = other.name else: result = dir_rel_path + os.sep + other.name - else: - i = self.path_elements.index(other) + 1 path_elems = ['..'] * (len(self.path_elements) - i) \ @@ -1538,7 +1549,7 @@ class Dir(Base): def build(self, **kw): """A null "builder" for directories.""" global MkdirBuilder - if not self.builder is MkdirBuilder: + if self.builder is not MkdirBuilder: apply(SCons.Node.Node.build, [self,], kw) # @@ -1554,10 +1565,9 @@ class Dir(Base): if parent.exists(): break listDirs.append(parent) - p = parent.up() - if p is None: - raise SCons.Errors.StopError, parent.path - parent = p + parent = parent.up() + else: + raise SCons.Errors.StopError, parent.path listDirs.reverse() for dirnode in listDirs: try: @@ -1577,21 +1587,36 @@ class Dir(Base): def multiple_side_effect_has_builder(self): global MkdirBuilder - return not self.builder is MkdirBuilder and self.has_builder() + return self.builder is not MkdirBuilder and self.has_builder() def alter_targets(self): - """Return any corresponding targets in a build directory. + """Return any corresponding targets in a variant directory. """ - return self.fs.build_dir_target_climb(self, self, []) + return self.fs.variant_dir_target_climb(self, self, []) def scanner_key(self): """A directory does not get scanned.""" return None def get_contents(self): - """Return aggregate contents of all our children.""" - contents = map(lambda n: n.get_contents(), self.children()) - return string.join(contents, '') + """Return content signatures and names of all our children + separated by new-lines. Ensure that the nodes are sorted.""" + contents = [] + name_cmp = lambda a, b: cmp(a.name, b.name) + sorted_children = self.children()[:] + sorted_children.sort(name_cmp) + for node in sorted_children: + contents.append('%s %s\n' % (node.get_csig(), node.name)) + return string.join(contents, '') + + def get_csig(self): + """Compute the content signature for Directory nodes. In + general, this is not needed and the content signature is not + stored in the DirNodeInfo. However, if get_contents on a Dir + node is called which has a child directory, the child + directory should return the hash of its contents.""" + contents = self.get_contents() + return SCons.Util.MD5signature(contents) def do_duplicate(self, src): pass @@ -1601,7 +1626,7 @@ class Dir(Base): def is_up_to_date(self): """If any child is not up-to-date, then this directory isn't, either.""" - if not self.builder is MkdirBuilder and not self.exists(): + if self.builder is not MkdirBuilder and not self.exists(): return 0 up_to_date = SCons.Node.up_to_date for kid in self.children(): @@ -1696,7 +1721,7 @@ class Dir(Base): for dir in self.srcdir_list(): if self.is_under(dir): # We shouldn't source from something in the build path; - # build_dir is probably under src_dir, in which case + # variant_dir is probably under src_dir, in which case # we are reflecting. break if dir.entry_exists_on_disk(name): @@ -1761,7 +1786,10 @@ class Dir(Base): if self.entry_exists_on_disk(name): try: return self.Dir(name) except TypeError: pass - return None + node = self.srcdir_duplicate(name) + if isinstance(node, File): + return None + return node def file_on_disk(self, name): if self.entry_exists_on_disk(name) or \ @@ -1771,7 +1799,7 @@ class Dir(Base): except TypeError: pass node = self.srcdir_duplicate(name) if isinstance(node, Dir): - node = None + return None return node def walk(self, func, arg): @@ -1823,8 +1851,8 @@ class Dir(Base): The "source" argument, when true, specifies that corresponding source Nodes must be returned if you're globbing in a build - directory (initialized with BuildDir()). The default behavior - is to return Nodes local to the BuildDir(). + directory (initialized with VariantDir()). The default behavior + is to return Nodes local to the VariantDir(). The "strings" argument, when true, returns the matches as strings, not Nodes. The strings are path names relative to this directory. @@ -1846,6 +1874,7 @@ class Dir(Base): if strings: r = map(lambda x, d=str(dir): os.path.join(d, x), r) result.extend(r) + result.sort(lambda a, b: cmp(str(a), str(b))) return result def _glob1(self, pattern, ondisk=True, source=False, strings=False): @@ -1863,6 +1892,7 @@ class Dir(Base): for srcdir in self.srcdir_list(): search_dir_list.extend(srcdir.get_all_rdirs()) + selfEntry = self.Entry names = [] for dir in search_dir_list: # We use the .name attribute from the Node because the keys of @@ -1872,34 +1902,39 @@ class Dir(Base): entry_names = filter(lambda n: n not in ('.', '..'), dir.entries.keys()) node_names = map(lambda n, e=dir.entries: e[n].name, entry_names) names.extend(node_names) + if not strings: + # Make sure the working directory (self) actually has + # entries for all Nodes in repositories or variant dirs. + map(selfEntry, node_names) if ondisk: try: disk_names = os.listdir(dir.abspath) except os.error: - pass - else: - names.extend(disk_names) - if not strings: - # We're going to return corresponding Nodes in - # the local directory, so we need to make sure - # those Nodes exist. We only want to create - # Nodes for the entries that will match the - # specified pattern, though, which means we - # need to filter the list here, even though - # the overall list will also be filtered later, - # after we exit this loop. - if pattern[0] != '.': - #disk_names = [ d for d in disk_names if d[0] != '.' ] - disk_names = filter(lambda x: x[0] != '.', disk_names) - disk_names = fnmatch.filter(disk_names, pattern) - rep_nodes = map(dir.Entry, disk_names) - #rep_nodes = [ n.disambiguate() for n in rep_nodes ] - rep_nodes = map(lambda n: n.disambiguate(), rep_nodes) - for node, name in zip(rep_nodes, disk_names): - n = self.Entry(name) - if n.__class__ != node.__class__: - n.__class__ = node.__class__ - n._morph() + continue + names.extend(disk_names) + if not strings: + # We're going to return corresponding Nodes in + # the local directory, so we need to make sure + # those Nodes exist. We only want to create + # Nodes for the entries that will match the + # specified pattern, though, which means we + # need to filter the list here, even though + # the overall list will also be filtered later, + # after we exit this loop. + if pattern[0] != '.': + #disk_names = [ d for d in disk_names if d[0] != '.' ] + disk_names = filter(lambda x: x[0] != '.', disk_names) + disk_names = fnmatch.filter(disk_names, pattern) + dirEntry = dir.Entry + for name in disk_names: + # Add './' before disk filename so that '#' at + # beginning of filename isn't interpreted. + name = './' + name + node = dirEntry(name).disambiguate() + n = selfEntry(name) + if n.__class__ != node.__class__: + n.__class__ = node.__class__ + n._morph() names = set(names) if pattern[0] != '.': @@ -1940,7 +1975,7 @@ class RootDir(Dir): # except for the "lookup abspath," which does not have the # drive letter. self.abspath = name + os.sep - self.labspath = '/' + self.labspath = '' self.path = name + os.sep self.tpath = name + os.sep self._morph() @@ -1951,6 +1986,7 @@ class RootDir(Dir): # os.path.normpath() seems to preserve double slashes at the # beginning of a path (presumably for UNC path names), but # collapses triple slashes to a single slash. + self._lookupDict[''] = self self._lookupDict['/'] = self self._lookupDict['//'] = self self._lookupDict[os.sep] = self @@ -1988,13 +2024,14 @@ class RootDir(Dir): dir_name, file_name = os.path.split(p) dir_node = self._lookup_abs(dir_name, Dir) result = klass(file_name, dir_node, self.fs) - self._lookupDict[k] = result - dir_node.entries[_my_normcase(file_name)] = result - dir_node.implicit = None # Double-check on disk (as configured) that the Node we # created matches whatever is out there in the real world. result.diskcheck_match() + + self._lookupDict[k] = result + dir_node.entries[_my_normcase(file_name)] = result + dir_node.implicit = None else: # There is already a Node for this path name. Allow it to # complain if we were looking for an inappropriate type. @@ -2008,7 +2045,7 @@ class RootDir(Dir): return self.abspath + name def entry_labspath(self, name): - return self.labspath + name + return '/' + name def entry_path(self, name): return self.path + name @@ -2106,19 +2143,18 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): strings = getattr(self, nattr) nodeinfos = getattr(self, sattr) except AttributeError: - pass - else: - nodes = [] - for s, ni in zip(strings, nodeinfos): - if not isinstance(s, SCons.Node.Node): - s = ni.str_to_node(s) - nodes.append(s) - setattr(self, nattr, nodes) + continue + nodes = [] + for s, ni in izip(strings, nodeinfos): + if not isinstance(s, SCons.Node.Node): + s = ni.str_to_node(s) + nodes.append(s) + setattr(self, nattr, nodes) def format(self, names=0): result = [] bkids = self.bsources + self.bdepends + self.bimplicit bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs - for bkid, bkidsig in zip(bkids, bkidsigs): + for bkid, bkidsig in izip(bkids, bkidsigs): result.append(str(bkid) + ': ' + string.join(bkidsig.format(names=names), ' ')) result.append('%s [%s]' % (self.bactsig, self.bact)) @@ -2133,6 +2169,8 @@ class File(Base): NodeInfo = FileNodeInfo BuildInfo = FileBuildInfo + md5_chunksize = 64 + def diskcheck_match(self): diskcheck_match(self, self.isdir, "Directory %s found where file expected.") @@ -2144,23 +2182,25 @@ class File(Base): def Entry(self, name): """Create an entry node named 'name' relative to - the SConscript directory of this file.""" - return self.cwd.Entry(name) + the directory of this file.""" + return self.dir.Entry(name) def Dir(self, name, create=True): """Create a directory node named 'name' relative to - the SConscript directory of this file.""" - return self.cwd.Dir(name, create) + the directory of this file.""" + return self.dir.Dir(name, create=create) def Dirs(self, pathlist): """Create a list of directories relative to the SConscript directory of this file.""" + # TODO(1.5) + # return [self.Dir(p) for p in pathlist] return map(lambda p, s=self: s.Dir(p), pathlist) def File(self, name): """Create a file node named 'name' relative to - the SConscript directory of this file.""" - return self.cwd.File(name) + the directory of this file.""" + return self.dir.File(name) #def generate_build_dict(self): # """Return an appropriate dictionary of values for building @@ -2203,6 +2243,23 @@ class File(Base): raise return r + def get_content_hash(self): + """ + Compute and return the MD5 hash for this file. + """ + if not self.rexists(): + return SCons.Util.MD5signature('') + fname = self.rfile().abspath + try: + cs = SCons.Util.MD5filesignature(fname, + chunksize=SCons.Node.FS.File.md5_chunksize*1024) + except EnvironmentError, e: + if not e.filename: + e.filename = fname + raise + return cs + + memoizer_counters.append(SCons.Memoize.CountValue('get_size')) def get_size(self): @@ -2242,7 +2299,8 @@ class File(Base): # This accomodates "chained builds" where a file that's a target # in one build (SConstruct file) is a source in a different build. # See test/chained-build.py for the use case. - self.dir.sconsign().store_info(self.name, self) + if do_store_info: + self.dir.sconsign().store_info(self.name, self) convert_copy_attrs = [ 'bsources', @@ -2336,26 +2394,24 @@ class File(Base): try: value = getattr(old_entry, attr) except AttributeError: - pass - else: - setattr(binfo, attr, value) - delattr(old_entry, attr) + continue + setattr(binfo, attr, value) + delattr(old_entry, attr) for attr in self.convert_sig_attrs: try: sig_list = getattr(old_entry, attr) except AttributeError: - pass - else: - value = [] - for sig in sig_list: - ninfo = self.new_ninfo() - if len(sig) == 32: - ninfo.csig = sig - else: - ninfo.timestamp = sig - value.append(ninfo) - setattr(binfo, attr, value) - delattr(old_entry, attr) + continue + value = [] + for sig in sig_list: + ninfo = self.new_ninfo() + if len(sig) == 32: + ninfo.csig = sig + else: + ninfo.timestamp = sig + value.append(ninfo) + setattr(binfo, attr, value) + delattr(old_entry, attr) return new_entry memoizer_counters.append(SCons.Memoize.CountValue('get_stored_info')) @@ -2368,7 +2424,7 @@ class File(Base): try: sconsign_entry = self.dir.sconsign().get_entry(self.name) - except (KeyError, OSError): + except (KeyError, EnvironmentError): import SCons.SConsign sconsign_entry = SCons.SConsign.SConsignEntry() sconsign_entry.binfo = self.new_binfo() @@ -2419,6 +2475,7 @@ class File(Base): pass if scanner: + # result = [n.disambiguate() for n in scanner(self, env, path)] result = scanner(self, env, path) result = map(lambda N: N.disambiguate(), result) else: @@ -2469,38 +2526,20 @@ class File(Base): self.get_build_env().get_CacheDir().push_if_forced(self) ninfo = self.get_ninfo() - old = self.get_stored_info() - - csig = None - mtime = self.get_timestamp() - size = self.get_size() - - max_drift = self.fs.max_drift - if max_drift > 0: - if (time.time() - mtime) > max_drift: - try: - n = old.ninfo - if n.timestamp and n.csig and n.timestamp == mtime: - csig = n.csig - except AttributeError: - pass - elif max_drift == 0: - try: - csig = old.ninfo.csig - except AttributeError: - pass + csig = self.get_max_drift_csig() if csig: ninfo.csig = csig - ninfo.timestamp = mtime - ninfo.size = size + ninfo.timestamp = self.get_timestamp() + ninfo.size = self.get_size() if not self.has_builder(): # This is a source file, but it might have been a target file # in another build that included more of the DAG. Copy # any build information that's stored in the .sconsign file # into our binfo object so it doesn't get lost. + old = self.get_stored_info() self.get_binfo().__dict__.update(old.binfo.__dict__) self.store_info() @@ -2540,14 +2579,14 @@ class File(Base): scb = self.sbuilder except AttributeError: scb = self.sbuilder = self.find_src_builder() - return not scb is None + return scb is not None def alter_targets(self): - """Return any corresponding targets in a build directory. + """Return any corresponding targets in a variant directory. """ if self.is_derived(): return [], None - return self.fs.build_dir_target_climb(self, self.dir, [self.name]) + return self.fs.variant_dir_target_climb(self, self.dir, [self.name]) def _rmv_existing(self): self.clear_memoized_values() @@ -2613,8 +2652,8 @@ class File(Base): # Duplicate from source path if we are set up to do this. if self.duplicate and not self.is_derived() and not self.linked: src = self.srcnode() - if not src is self: - # At this point, src is meant to be copied in a build directory. + if src is not self: + # At this point, src is meant to be copied in a variant directory. src = src.rfile() if src.abspath != self.abspath: if src.exists(): @@ -2623,7 +2662,7 @@ class File(Base): # not actually occur if the -n option is being used. else: # The source file does not exist. Make sure no old - # copy remains in the build directory. + # copy remains in the variant directory. if Base.exists(self) or self.islink(): self.fs.unlink(self.path) # Return None explicitly because the Base.exists() call @@ -2638,6 +2677,32 @@ class File(Base): # SIGNATURE SUBSYSTEM # + def get_max_drift_csig(self): + """ + Returns the content signature currently stored for this node + if it's been unmodified longer than the max_drift value, or the + max_drift value is 0. Returns None otherwise. + """ + old = self.get_stored_info() + mtime = self.get_timestamp() + + max_drift = self.fs.max_drift + if max_drift > 0: + if (time.time() - mtime) > max_drift: + try: + n = old.ninfo + if n.timestamp and n.csig and n.timestamp == mtime: + return n.csig + except AttributeError: + pass + elif max_drift == 0: + try: + return old.ninfo.csig + except AttributeError: + pass + + return None + def get_csig(self): """ Generate a node's content signature, the digested signature @@ -2653,16 +2718,23 @@ class File(Base): except AttributeError: pass - try: - contents = self.get_contents() - except IOError: - # This can happen if there's actually a directory on-disk, - # which can be the case if they've disabled disk checks, - # or if an action with a File target actually happens to - # create a same-named directory by mistake. - csig = '' - else: - csig = SCons.Util.MD5signature(contents) + csig = self.get_max_drift_csig() + if csig is None: + + try: + if self.get_size() < SCons.Node.FS.File.md5_chunksize: + contents = self.get_contents() + else: + csig = self.get_content_hash() + except IOError: + # This can happen if there's actually a directory on-disk, + # which can be the case if they've disabled disk checks, + # or if an action with a File target actually happens to + # create a same-named directory by mistake. + csig = '' + else: + if not csig: + csig = SCons.Util.MD5signature(contents) ninfo.csig = csig @@ -2684,7 +2756,7 @@ class File(Base): return 1 def changed_state(self, target, prev_ni): - return (self.state != SCons.Node.up_to_date) + return self.state != SCons.Node.up_to_date def changed_timestamp_then_content(self, target, prev_ni): if not self.changed_timestamp_match(target, prev_ni): @@ -2790,8 +2862,8 @@ class File(Base): cachedir, cachefile = self.get_build_env().get_CacheDir().cachepath(self) if not self.exists() and cachefile and os.path.exists(cachefile): - contents = open(cachefile, 'rb').read() - self.cachedir_csig = SCons.Util.MD5signature(contents) + self.cachedir_csig = SCons.Util.MD5filesignature(cachefile, \ + SCons.Node.FS.File.md5_chunksize * 1024) else: self.cachedir_csig = self.get_csig() return self.cachedir_csig @@ -2805,13 +2877,15 @@ class File(Base): # Add the path to the cache signature, because multiple # targets built by the same action will all have the same # build signature, and we have to differentiate them somehow. - children = self.children() - sigs = map(lambda n: n.get_cachedir_csig(), children) + children = self.children() executor = self.get_executor() + # sigs = [n.get_cachedir_csig() for n in children] + sigs = map(lambda n: n.get_cachedir_csig(), children) sigs.append(SCons.Util.MD5signature(executor.get_contents())) sigs.append(self.path) - self.cachesig = SCons.Util.MD5collect(sigs) - return self.cachesig + result = self.cachesig = SCons.Util.MD5collect(sigs) + return result + default_fs = None @@ -2842,14 +2916,14 @@ class FileFinder: It would be more compact to just use this as a nested function with a default keyword argument (see the commented-out version below), but that doesn't work unless you have nested scopes, - so we define it here just this works work under Python 1.5.2. + so we define it here just so this work under Python 1.5.2. """ if fd is None: fd = self.default_filedir dir, name = os.path.split(fd) drive, d = os.path.splitdrive(dir) if d in ('/', os.sep): - return p + return p.fs.get_root(drive).dir_on_disk(name) if dir: p = self.filedir_lookup(p, dir) if not p: @@ -2859,9 +2933,10 @@ class FileFinder: node = p.entries[norm_name] except KeyError: return p.dir_on_disk(name) - # Once we move to Python 2.2 we can do: - #if isinstance(node, (Dir, Entry)): - if isinstance(node, Dir) or isinstance(node, Entry): + if isinstance(node, Dir): + return node + if isinstance(node, Entry): + node.must_be_same(Dir) return node return None @@ -2899,14 +2974,11 @@ class FileFinder: except KeyError: pass - if verbose: + if verbose and not callable(verbose): if not SCons.Util.is_String(verbose): verbose = "find_file" - if not callable(verbose): - verbose = ' %s: ' % verbose - verbose = lambda s, v=verbose: sys.stdout.write(v + s) - else: - verbose = lambda x: x + verbose = ' %s: ' % verbose + verbose = lambda s, v=verbose: sys.stdout.write(v + s) filedir, filename = os.path.split(filename) if filedir: @@ -2930,8 +3002,11 @@ class FileFinder: # node = p.entries[norm_name] # except KeyError: # return p.dir_on_disk(name) - # # Once we move to Python 2.2 we can do: - # #if isinstance(node, (Dir, Entry)): + # if isinstance(node, Dir): + # return node + # if isinstance(node, Entry): + # node.must_be_same(Dir) + # return node # if isinstance(node, Dir) or isinstance(node, Entry): # return node # return None @@ -2942,10 +3017,12 @@ class FileFinder: result = None for dir in paths: - verbose("looking for '%s' in '%s' ...\n" % (filename, dir)) + if verbose: + verbose("looking for '%s' in '%s' ...\n" % (filename, dir)) node, d = dir.srcdir_find_file(filename) if node: - verbose("... FOUND '%s' in '%s'\n" % (filename, d)) + if verbose: + verbose("... FOUND '%s' in '%s'\n" % (filename, d)) result = node break @@ -2954,3 +3031,45 @@ class FileFinder: return result find_file = FileFinder().find_file + + +def invalidate_node_memos(targets): + """ + Invalidate the memoized values of all Nodes (files or directories) + that are associated with the given entries. Has been added to + clear the cache of nodes affected by a direct execution of an + action (e.g. Delete/Copy/Chmod). Existing Node caches become + inconsistent if the action is run through Execute(). The argument + `targets` can be a single Node object or filename, or a sequence + of Nodes/filenames. + """ + from traceback import extract_stack + + # First check if the cache really needs to be flushed. Only + # actions run in the SConscript with Execute() seem to be + # affected. XXX The way to check if Execute() is in the stacktrace + # is a very dirty hack and should be replaced by a more sensible + # solution. + for f in extract_stack(): + if f[2] == 'Execute' and f[0][-14:] == 'Environment.py': + break + else: + # Dont have to invalidate, so return + return + + if not SCons.Util.is_List(targets): + targets = [targets] + + for entry in targets: + # If the target is a Node object, clear the cache. If it is a + # filename, look up potentially existing Node object first. + try: + entry.clear_memoized_values() + except AttributeError: + # Not a Node object, try to look up Node by filename. XXX + # This creates Node objects even for those filenames which + # do not correspond to an existing Node object. + node = get_default_fs().Entry(entry) + if node: + node.clear_memoized_values() + diff --git a/scons/scons-local-0.97.0d20071212/SCons/Node/Python.py b/scons/scons-local-1.2.0/SCons/Node/Python.py similarity index 94% rename from scons/scons-local-0.97.0d20071212/SCons/Node/Python.py rename to scons/scons-local-1.2.0/SCons/Node/Python.py index 8b5774a91..21fbb157c 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Node/Python.py +++ b/scons/scons-local-1.2.0/SCons/Node/Python.py @@ -5,7 +5,7 @@ Python nodes. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ Python nodes. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/Python.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Node/Python.py 3842 2008/12/20 22:59:52 scons" import SCons.Node @@ -56,9 +56,12 @@ class Value(SCons.Node.Node): if not built_value is None: self.built_value = built_value - def __str__(self): + def str_for_display(self): return repr(self.value) + def __str__(self): + return str(self.value) + def make_ready(self): self.get_csig() diff --git a/scons/scons-local-0.97.0d20071212/SCons/Node/__init__.py b/scons/scons-local-1.2.0/SCons/Node/__init__.py similarity index 88% rename from scons/scons-local-0.97.0d20071212/SCons/Node/__init__.py rename to scons/scons-local-1.2.0/SCons/Node/__init__.py index 769cbe333..8ea6719e0 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Node/__init__.py +++ b/scons/scons-local-1.2.0/SCons/Node/__init__.py @@ -20,7 +20,7 @@ be able to depend on any other type of "thing." """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -42,11 +42,10 @@ be able to depend on any other type of "thing." # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Node/__init__.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/Node/__init__.py 3842 2008/12/20 22:59:52 scons" import copy +from itertools import chain, izip import string import UserList @@ -75,7 +74,7 @@ executed = 4 failed = 5 StateString = { - 0 : "0", + 0 : "no_state", 1 : "pending", 2 : "executing", 3 : "up_to_date", @@ -202,15 +201,16 @@ class Node: # a class. (Of course, we could always still do that in the # future if we had a good reason to...). self.sources = [] # source files used to build node - self.sources_dict = {} + self.sources_set = set() + self._specific_sources = False self.depends = [] # explicit dependencies (from Depends) - self.depends_dict = {} + self.depends_set = set() self.ignore = [] # dependencies to ignore - self.ignore_dict = {} + self.ignore_set = set() self.prerequisites = SCons.Util.UniqueList() self.implicit = None # implicit (scanned) dependencies (None means not scanned yet) - self.waiting_parents = {} - self.waiting_s_e = {} + self.waiting_parents = set() + self.waiting_s_e = set() self.ref_count = 0 self.wkids = None # Kids yet to walk, when it's an array @@ -220,12 +220,11 @@ class Node: self.noclean = 0 self.nocache = 0 self.always_build = None - self.found_includes = {} self.includes = None self.attributes = self.Attrs() # Generic place to stick information about the Node. self.side_effect = 0 # true iff this node is a side effect self.side_effects = [] # the side effects of building this target - self.linked = 0 # is this node linked to the build directory? + self.linked = 0 # is this node linked to the variant directory? self.clear_memoized_values() @@ -330,24 +329,29 @@ class Node: is out-of-date and must be rebuilt, but before actually calling the method to build the Node. - This default implemenation checks that all children either exist - or are derived, and initializes the BuildInfo structure that - will hold the information about how this node is, uh, built. + This default implementation checks that explicit or implicit + dependencies either exist or are derived, and initializes the + BuildInfo structure that will hold the information about how + this node is, uh, built. + + (The existence of source files is checked separately by the + Executor, which aggregates checks for all of the targets built + by a specific action.) Overriding this method allows for for a Node subclass to remove the underlying file from the file system. Note that subclass methods should call this base class method to get the child check and the BuildInfo structure. """ - l = self.depends + for d in self.depends: + if d.missing(): + msg = "Explicit dependency `%s' not found, needed by target `%s'." + raise SCons.Errors.StopError, msg % (d, self) if not self.implicit is None: - l = l + self.implicit - missing_sources = self.get_executor().get_missing_sources() \ - + filter(lambda c: c.missing(), l) - if missing_sources: - desc = "Source `%s' not found, needed by target `%s'." % (missing_sources[0], self) - raise SCons.Errors.StopError, desc - + for i in self.implicit: + if i.missing(): + msg = "Implicit dependency `%s' not found, needed by target `%s'." + raise SCons.Errors.StopError, msg % (i, self) self.binfo = self.get_binfo() def build(self, **kw): @@ -373,9 +377,8 @@ class Node: # Clear the implicit dependency caches of any Nodes # waiting for this Node to be built. - for parent in self.waiting_parents.keys(): + for parent in self.waiting_parents: parent.implicit = None - parent.del_binfo() self.clear() @@ -399,7 +402,7 @@ class Node: # def add_to_waiting_s_e(self, node): - self.waiting_s_e[node] = 1 + self.waiting_s_e.add(node) def add_to_waiting_parents(self, node): """ @@ -410,37 +413,26 @@ class Node: True and False instead...) """ wp = self.waiting_parents - if wp.has_key(node): - result = 0 - else: - result = 1 - wp[node] = 1 - return result - - def call_for_all_waiting_parents(self, func): - func(self) - for parent in self.waiting_parents.keys(): - parent.call_for_all_waiting_parents(func) + if node in wp: + return 0 + wp.add(node) + return 1 def postprocess(self): """Clean up anything we don't need to hang onto after we've been built.""" self.executor_cleanup() - self.waiting_parents = {} + self.waiting_parents = set() def clear(self): """Completely clear a Node of all its cached state (so that it can be re-evaluated by interfaces that do continuous integration builds). """ - # Note in case it's important in the future: We also used to clear - # the build information (the lists of dependencies) here like this: - # - # self.del_binfo() - # - # But we now rely on the fact that we're going to look at that - # once before the build, and then store the results in the - # .sconsign file after the build. + # The del_binfo() call here isn't necessary for normal execution, + # but is for interactive mode, where we might rebuild the same + # target and need to start from scratch. + self.del_binfo() self.clear_memoized_values() self.ninfo = self.new_ninfo() self.executor_cleanup() @@ -449,7 +441,6 @@ class Node: except AttributeError: pass self.includes = None - self.found_includes = {} def clear_memoized_values(self): self._memo = {} @@ -510,7 +501,7 @@ class Node: Returns true iff this node is derived (i.e. built). This should return true only for nodes whose path should be in - the build directory when duplicate=0 and should contribute their build + the variant directory when duplicate=0 and should contribute their build signatures when they are used as source files to other derived files. For example: source with source builders are not derived in this sense, and hence should not return true. @@ -597,9 +588,9 @@ class Node: def add_to_implicit(self, deps): if not hasattr(self, 'implicit') or self.implicit is None: self.implicit = [] - self.implicit_dict = {} + self.implicit_set = set() self._children_reset() - self._add_child(self.implicit, self.implicit_dict, deps) + self._add_child(self.implicit, self.implicit_set, deps) def scan(self): """Scan this node's dependents for implicit dependencies.""" @@ -609,7 +600,7 @@ class Node: if not self.implicit is None: return self.implicit = [] - self.implicit_dict = {} + self.implicit_set = set() self._children_reset() if not self.has_builder(): return @@ -638,9 +629,7 @@ class Node: # one of this node's sources has changed, # so we must recalculate the implicit deps: self.implicit = [] - self.implicit_dict = {} - self._children_reset() - self.del_binfo() + self.implicit_set = set() # Have the executor scan the sources. executor.scan_sources(self.builder.source_scanner) @@ -713,33 +702,44 @@ class Node: self.binfo = binfo executor = self.get_executor() - - sources = executor.get_unignored_sources(self.ignore) - - depends = self.depends - implicit = self.implicit or [] - - if self.ignore: - depends = filter(self.do_not_ignore, depends) - implicit = filter(self.do_not_ignore, implicit) - - def get_ninfo(node): - return node.get_ninfo() - - sourcesigs = map(get_ninfo, sources) - dependsigs = map(get_ninfo, depends) - implicitsigs = map(get_ninfo, implicit) + ignore_set = self.ignore_set if self.has_builder(): binfo.bact = str(executor) binfo.bactsig = SCons.Util.MD5signature(executor.get_contents()) - binfo.bsources = sources - binfo.bdepends = depends - binfo.bimplicit = implicit + if self._specific_sources: + sources = [] + for s in self.sources: + if s not in ignore_set: + sources.append(s) + else: + sources = executor.get_unignored_sources(self.ignore) + seen = set() + bsources = [] + bsourcesigs = [] + for s in sources: + if not s in seen: + seen.add(s) + bsources.append(s) + bsourcesigs.append(s.get_ninfo()) + binfo.bsources = bsources + binfo.bsourcesigs = bsourcesigs - binfo.bsourcesigs = sourcesigs + depends = self.depends + dependsigs = [] + for d in depends: + if d not in ignore_set: + dependsigs.append(d.get_ninfo()) + binfo.bdepends = depends binfo.bdependsigs = dependsigs + + implicit = self.implicit or [] + implicitsigs = [] + for i in implicit: + if i not in ignore_set: + implicitsigs.append(i.get_ninfo()) + binfo.bimplicit = implicit binfo.bimplicitsigs = implicitsigs return binfo @@ -823,7 +823,7 @@ class Node: def add_dependency(self, depend): """Adds dependencies.""" try: - self._add_child(self.depends, self.depends_dict, depend) + self._add_child(self.depends, self.depends_set, depend) except TypeError, e: e = e.args[0] if SCons.Util.is_List(e): @@ -840,7 +840,7 @@ class Node: def add_ignore(self, depend): """Adds dependencies to ignore.""" try: - self._add_child(self.ignore, self.ignore_dict, depend) + self._add_child(self.ignore, self.ignore_set, depend) except TypeError, e: e = e.args[0] if SCons.Util.is_List(e): @@ -851,8 +851,10 @@ class Node: def add_source(self, source): """Adds sources.""" + if self._specific_sources: + return try: - self._add_child(self.sources, self.sources_dict, source) + self._add_child(self.sources, self.sources_set, source) except TypeError, e: e = e.args[0] if SCons.Util.is_List(e): @@ -861,9 +863,9 @@ class Node: s = str(e) raise SCons.Errors.UserError("attempted to add a non-Node as source of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) - def _add_child(self, collection, dict, child): - """Adds 'child' to 'collection', first checking 'dict' to see - if it's already present.""" + def _add_child(self, collection, set, child): + """Adds 'child' to 'collection', first checking 'set' to see if it's + already present.""" #if type(child) is not type([]): # child = [child] #for c in child: @@ -871,13 +873,17 @@ class Node: # raise TypeError, c added = None for c in child: - if not dict.has_key(c): + if c not in set: + set.add(c) collection.append(c) - dict[c] = 1 added = 1 if added: self._children_reset() + def set_specific_source(self, source): + self.add_source(source) + self._specific_sources = True + def add_wkid(self, wkid): """Add a node to the list of kids waiting to be evaluated""" if self.wkids != None: @@ -889,10 +895,55 @@ class Node: # build info that it's cached so we can re-calculate it. self.executor_cleanup() - def do_not_ignore(self, node): - return node not in self.ignore + memoizer_counters.append(SCons.Memoize.CountValue('_children_get')) + + def _children_get(self): + try: + return self._memo['children_get'] + except KeyError: + pass + + # The return list may contain duplicate Nodes, especially in + # source trees where there are a lot of repeated #includes + # of a tangle of .h files. Profiling shows, however, that + # eliminating the duplicates with a brute-force approach that + # preserves the order (that is, something like: + # + # u = [] + # for n in list: + # if n not in u: + # u.append(n)" + # + # takes more cycles than just letting the underlying methods + # hand back cached values if a Node's information is requested + # multiple times. (Other methods of removing duplicates, like + # using dictionary keys, lose the order, and the only ordered + # dictionary patterns I found all ended up using "not in" + # internally anyway...) + if self.ignore_set: + if self.implicit is None: + iter = chain(self.sources,self.depends) + else: + iter = chain(self.sources, self.depends, self.implicit) + + children = [] + for i in iter: + if i not in self.ignore_set: + children.append(i) + else: + if self.implicit is None: + children = self.sources + self.depends + else: + children = self.sources + self.depends + self.implicit + + self._memo['children_get'] = children + return children + + def all_children(self, scan=1): + """Return a list of all the node's direct children.""" + if scan: + self.scan() - def _all_children_get(self): # The return list may contain duplicate Nodes, especially in # source trees where there are a lot of repeated #includes # of a tangle of .h files. Profiling shows, however, that @@ -915,25 +966,6 @@ class Node: else: return self.sources + self.depends + self.implicit - memoizer_counters.append(SCons.Memoize.CountValue('_children_get')) - - def _children_get(self): - try: - return self._memo['children_get'] - except KeyError: - pass - children = self._all_children_get() - if self.ignore: - children = filter(self.do_not_ignore, children) - self._memo['children_get'] = children - return children - - def all_children(self, scan=1): - """Return a list of all the node's direct children.""" - if scan: - self.scan() - return self._all_children_get() - def children(self, scan=1): """Return a list of the node's direct children, minus those that are ignored by this node.""" @@ -1013,9 +1045,10 @@ class Node: # entries to equal the new dependency list, for the benefit # of the loop below that updates node information. then.extend([None] * diff) + if t: Trace(': old %s new %s' % (len(then), len(children))) result = True - for child, prev_ni in zip(children, then): + for child, prev_ni in izip(children, then): if child.changed_since_last_build(self, prev_ni): if t: Trace(': %s changed' % child) result = True @@ -1071,7 +1104,10 @@ class Node: env = self.get_build_env() for s in self.sources: scanner = self.get_source_scanner(s) - path = self.get_build_scanner_path(scanner) + if scanner: + path = self.get_build_scanner_path(scanner) + else: + path = None def f(node, env=env, scanner=scanner, path=path): return node.get_found_includes(env, scanner, path) return SCons.Util.render_tree(s, f, 1) @@ -1158,8 +1194,8 @@ class Node: new_bkids = new.bsources + new.bdepends + new.bimplicit new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs - osig = dict(zip(old_bkids, old_bkidsigs)) - nsig = dict(zip(new_bkids, new_bkidsigs)) + osig = dict(izip(old_bkids, old_bkidsigs)) + nsig = dict(izip(new_bkids, new_bkidsigs)) # The sources and dependencies we'll want to report are all stored # as relative paths to this target's directory, but we want to @@ -1167,7 +1203,10 @@ class Node: # so we only print them after running them through this lambda # to turn them into the right relative Node and then return # its string. - stringify = lambda s, E=self.dir.Entry: str(E(s)) + def stringify( s, E=self.dir.Entry ) : + if hasattr( s, 'dir' ) : + return str(E(s)) + return str(s) lines = [] diff --git a/scons/scons-local-1.2.0/SCons/Options/BoolOption.py b/scons/scons-local-1.2.0/SCons/Options/BoolOption.py new file mode 100644 index 000000000..c5fed0a14 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Options/BoolOption.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Options/BoolOption.py 3842 2008/12/20 22:59:52 scons" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables +import SCons.Warnings + +warned = False + +def BoolOption(*args, **kw): + global warned + if not warned: + msg = "The BoolOption() function is deprecated; use the BoolVariable() function instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg) + warned = True + return apply(SCons.Variables.BoolVariable, args, kw) diff --git a/scons/scons-local-1.2.0/SCons/Options/EnumOption.py b/scons/scons-local-1.2.0/SCons/Options/EnumOption.py new file mode 100644 index 000000000..4f50d01b8 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Options/EnumOption.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Options/EnumOption.py 3842 2008/12/20 22:59:52 scons" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables +import SCons.Warnings + +warned = False + +def EnumOption(*args, **kw): + global warned + if not warned: + msg = "The EnumOption() function is deprecated; use the EnumVariable() function instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg) + warned = True + return apply(SCons.Variables.EnumVariable, args, kw) diff --git a/scons/scons-local-1.2.0/SCons/Options/ListOption.py b/scons/scons-local-1.2.0/SCons/Options/ListOption.py new file mode 100644 index 000000000..b4cd923ad --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Options/ListOption.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Options/ListOption.py 3842 2008/12/20 22:59:52 scons" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables +import SCons.Warnings + +warned = False + +def ListOption(*args, **kw): + global warned + if not warned: + msg = "The ListOption() function is deprecated; use the ListVariable() function instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg) + warned = True + return apply(SCons.Variables.ListVariable, args, kw) diff --git a/scons/scons-local-1.2.0/SCons/Options/PackageOption.py b/scons/scons-local-1.2.0/SCons/Options/PackageOption.py new file mode 100644 index 000000000..7fcbe5f1d --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Options/PackageOption.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Options/PackageOption.py 3842 2008/12/20 22:59:52 scons" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables +import SCons.Warnings + +warned = False + +def PackageOption(*args, **kw): + global warned + if not warned: + msg = "The PackageOption() function is deprecated; use the PackageVariable() function instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg) + warned = True + return apply(SCons.Variables.PackageVariable, args, kw) diff --git a/scons/scons-local-1.2.0/SCons/Options/PathOption.py b/scons/scons-local-1.2.0/SCons/Options/PathOption.py new file mode 100644 index 000000000..649fc45ea --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Options/PathOption.py @@ -0,0 +1,70 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Options/PathOption.py 3842 2008/12/20 22:59:52 scons" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables +import SCons.Warnings + +warned = False + +class _PathOptionClass: + def warn(self): + global warned + if not warned: + msg = "The PathOption() function is deprecated; use the PathVariable() function instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg) + warned = True + + def __call__(self, *args, **kw): + self.warn() + return apply(SCons.Variables.PathVariable, args, kw) + + def PathAccept(self, *args, **kw): + self.warn() + return apply(SCons.Variables.PathVariable.PathAccept, args, kw) + + def PathIsDir(self, *args, **kw): + self.warn() + return apply(SCons.Variables.PathVariable.PathIsDir, args, kw) + + def PathIsDirCreate(self, *args, **kw): + self.warn() + return apply(SCons.Variables.PathVariable.PathIsDirCreate, args, kw) + + def PathIsFile(self, *args, **kw): + self.warn() + return apply(SCons.Variables.PathVariable.PathIsFile, args, kw) + + def PathExists(self, *args, **kw): + self.warn() + return apply(SCons.Variables.PathVariable.PathExists, args, kw) + +PathOption = _PathOptionClass() diff --git a/scons/scons-local-1.2.0/SCons/Options/__init__.py b/scons/scons-local-1.2.0/SCons/Options/__init__.py new file mode 100644 index 000000000..3e41b8d63 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Options/__init__.py @@ -0,0 +1,68 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Options/__init__.py 3842 2008/12/20 22:59:52 scons" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables +import SCons.Warnings + +from BoolOption import BoolOption # okay +from EnumOption import EnumOption # okay +from ListOption import ListOption # naja +from PackageOption import PackageOption # naja +from PathOption import PathOption # okay + +warned = False + +class Options(SCons.Variables.Variables): + def __init__(self, *args, **kw): + global warned + if not warned: + msg = "The Options class is deprecated; use the Variables class instead." + SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg) + warned = True + apply(SCons.Variables.Variables.__init__, + (self,) + args, + kw) + + def AddOptions(self, *args, **kw): + return apply(SCons.Variables.Variables.AddVariables, + (self,) + args, + kw) + + def UnknownOptions(self, *args, **kw): + return apply(SCons.Variables.Variables.UnknownVariables, + (self,) + args, + kw) + + def FormatOptionHelpText(self, *args, **kw): + return apply(SCons.Variables.Variables.FormatVariableHelpText, + (self,) + args, + kw) diff --git a/scons/scons-local-0.97.0d20071212/SCons/PathList.py b/scons/scons-local-1.2.0/SCons/PathList.py similarity index 94% rename from scons/scons-local-0.97.0d20071212/SCons/PathList.py rename to scons/scons-local-1.2.0/SCons/PathList.py index 355d06c94..8b877fa4f 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/PathList.py +++ b/scons/scons-local-1.2.0/SCons/PathList.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/PathList.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/PathList.py 3842 2008/12/20 22:59:52 scons" __doc__ = """SCons.PathList @@ -59,7 +59,7 @@ def node_conv(obj): try: get = obj.get except AttributeError: - if isinstance(obj, SCons.Node.Node): + if isinstance(obj, SCons.Node.Node) or SCons.Util.is_Sequence( obj ): result = obj else: result = str(obj) @@ -132,10 +132,9 @@ class _PathList: value = env.subst(value, target=target, source=source, conv=node_conv) if SCons.Util.is_Sequence(value): - # It came back as a string or tuple, which in this - # case usually means some variable expanded to an - # actually Dir node. Concatenate the values. - value = string.join(map(str, value), '') + result.extend(value) + continue + elif type == TYPE_OBJECT: value = node_conv(value) if value: diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/__init__.py b/scons/scons-local-1.2.0/SCons/Platform/__init__.py similarity index 98% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/__init__.py rename to scons/scons-local-1.2.0/SCons/Platform/__init__.py index 61e529931..12158650b 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/__init__.py +++ b/scons/scons-local-1.2.0/SCons/Platform/__init__.py @@ -20,7 +20,7 @@ their own platform definition. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -42,7 +42,7 @@ their own platform definition. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/__init__.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/__init__.py 3842 2008/12/20 22:59:52 scons" import imp import os diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/aix.py b/scons/scons-local-1.2.0/SCons/Platform/aix.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/aix.py rename to scons/scons-local-1.2.0/SCons/Platform/aix.py index e054abee2..c8cb7e89f 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/aix.py +++ b/scons/scons-local-1.2.0/SCons/Platform/aix.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/aix.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/aix.py 3842 2008/12/20 22:59:52 scons" import os import string diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/cygwin.py b/scons/scons-local-1.2.0/SCons/Platform/cygwin.py similarity index 91% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/cygwin.py rename to scons/scons-local-1.2.0/SCons/Platform/cygwin.py index 0e32e7a5a..f51eeb16e 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/cygwin.py +++ b/scons/scons-local-1.2.0/SCons/Platform/cygwin.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/cygwin.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/cygwin.py 3842 2008/12/20 22:59:52 scons" import posix from SCons.Platform import TempFileMunge diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/darwin.py b/scons/scons-local-1.2.0/SCons/Platform/darwin.py similarity index 89% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/darwin.py rename to scons/scons-local-1.2.0/SCons/Platform/darwin.py index bcd57b223..94365465c 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/darwin.py +++ b/scons/scons-local-1.2.0/SCons/Platform/darwin.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/darwin.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/darwin.py 3842 2008/12/20 22:59:52 scons" import posix diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/hpux.py b/scons/scons-local-1.2.0/SCons/Platform/hpux.py similarity index 89% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/hpux.py rename to scons/scons-local-1.2.0/SCons/Platform/hpux.py index e69403fe4..2bd468b71 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/hpux.py +++ b/scons/scons-local-1.2.0/SCons/Platform/hpux.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/hpux.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/hpux.py 3842 2008/12/20 22:59:52 scons" import posix diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/irix.py b/scons/scons-local-1.2.0/SCons/Platform/irix.py similarity index 89% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/irix.py rename to scons/scons-local-1.2.0/SCons/Platform/irix.py index ca09b62a3..b70481db2 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/irix.py +++ b/scons/scons-local-1.2.0/SCons/Platform/irix.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/irix.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/irix.py 3842 2008/12/20 22:59:52 scons" import posix diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/os2.py b/scons/scons-local-1.2.0/SCons/Platform/os2.py similarity index 91% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/os2.py rename to scons/scons-local-1.2.0/SCons/Platform/os2.py index 0e9597c24..803d890d9 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/os2.py +++ b/scons/scons-local-1.2.0/SCons/Platform/os2.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/os2.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/os2.py 3842 2008/12/20 22:59:52 scons" def generate(env): if not env.has_key('ENV'): diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/posix.py b/scons/scons-local-1.2.0/SCons/Platform/posix.py similarity index 85% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/posix.py rename to scons/scons-local-1.2.0/SCons/Platform/posix.py index ab6c7d9bc..6d0b0747e 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/posix.py +++ b/scons/scons-local-1.2.0/SCons/Platform/posix.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,12 +30,13 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/posix.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/posix.py 3842 2008/12/20 22:59:52 scons" +import errno import os import os.path -import popen2 import string +import subprocess import sys import select @@ -50,7 +51,7 @@ exitvalmap = { def escape(arg): "escape shell special characters" slash = '\\' - special = '"$' + special = '"$()' arg = string.replace(arg, slash, slash+slash) for c in special: @@ -92,7 +93,7 @@ def _get_env_command(sh, escape, cmd, args, env): s = string.join(args) if env: l = ['env', '-'] + \ - map(lambda t, e=escape: t[0]+'='+e(t[1]), env.items()) + \ + map(lambda t, e=escape: e(t[0])+'='+e(t[1]), env.items()) + \ [sh, '-c', escape(s)] s = string.join(l) return s @@ -109,25 +110,31 @@ def fork_spawn(sh, escape, cmd, args, env): def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr): stdout_eof = stderr_eof = 0 while not (stdout_eof and stderr_eof): - (i,o,e) = select.select([cmd_stdout, cmd_stderr], [], []) - if cmd_stdout in i: - str = cmd_stdout.read() - if len(str) == 0: - stdout_eof = 1 - elif stdout != None: - stdout.write(str) - if cmd_stderr in i: - str = cmd_stderr.read() - if len(str) == 0: - #sys.__stderr__.write( "stderr_eof=1\n" ) - stderr_eof = 1 - else: - #sys.__stderr__.write( "str(stderr) = %s\n" % str ) - stderr.write(str) + try: + (i,o,e) = select.select([cmd_stdout, cmd_stderr], [], []) + if cmd_stdout in i: + str = cmd_stdout.read() + if len(str) == 0: + stdout_eof = 1 + elif stdout != None: + stdout.write(str) + if cmd_stderr in i: + str = cmd_stderr.read() + if len(str) == 0: + #sys.__stderr__.write( "stderr_eof=1\n" ) + stderr_eof = 1 + else: + #sys.__stderr__.write( "str(stderr) = %s\n" % str ) + stderr.write(str) + except select.error, (_errno, _strerror): + if _errno != errno.EINTR: + raise def exec_popen3(l, env, stdout, stderr): - proc = popen2.Popen3(string.join(l), 1) - process_cmd_output(proc.fromchild, proc.childerr, stdout, stderr) + proc = subprocess.Popen(string.join(l), + stdout=stdout, + stderr=stderr, + shell=True) stat = proc.wait() if stat & 0xff: return stat | 0x80 @@ -235,7 +242,7 @@ def generate(env): env['LIBSUFFIX'] = '.a' env['SHLIBPREFIX'] = '$LIBPREFIX' env['SHLIBSUFFIX'] = '.so' - env['LIBPREFIXES'] = '$LIBPREFIX' + env['LIBPREFIXES'] = [ '$LIBPREFIX' ] env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ] env['PSPAWN'] = pspawn env['SPAWN'] = spawn diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/sunos.py b/scons/scons-local-1.2.0/SCons/Platform/sunos.py similarity index 90% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/sunos.py rename to scons/scons-local-1.2.0/SCons/Platform/sunos.py index cfa638466..03435c691 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/sunos.py +++ b/scons/scons-local-1.2.0/SCons/Platform/sunos.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/sunos.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/sunos.py 3842 2008/12/20 22:59:52 scons" import posix diff --git a/scons/scons-local-0.97.0d20071212/SCons/Platform/win32.py b/scons/scons-local-1.2.0/SCons/Platform/win32.py similarity index 98% rename from scons/scons-local-0.97.0d20071212/SCons/Platform/win32.py rename to scons/scons-local-1.2.0/SCons/Platform/win32.py index 2e10ca3ea..3ec0a526d 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Platform/win32.py +++ b/scons/scons-local-1.2.0/SCons/Platform/win32.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Platform/win32.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Platform/win32.py 3842 2008/12/20 22:59:52 scons" import os import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/SConf.py b/scons/scons-local-1.2.0/SCons/SConf.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/SConf.py rename to scons/scons-local-1.2.0/SCons/SConf.py index e0c16080e..ec80fe97a 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/SConf.py +++ b/scons/scons-local-1.2.0/SCons/SConf.py @@ -4,7 +4,7 @@ Autoconf-like configuration support. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -26,9 +26,7 @@ Autoconf-like configuration support. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/SConf.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/SConf.py 3842 2008/12/20 22:59:52 scons" import os import re @@ -235,7 +233,9 @@ class SConfBuildTask(SCons.Taskmaster.Task): raise elif issubclass(exc_type, SCons.Errors.BuildError): # we ignore Build Errors (occurs, when a test doesn't pass) - pass + # Clear the exception to prevent the contained traceback + # to build a reference cycle. + self.exc_clear() else: self.display('Caught exception while building "%s":\n' % self.targets[0]) @@ -381,7 +381,7 @@ class SConfBase: e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest defines a custom test. Note also the conf_dir and log_file arguments (you may want to - build tests in the BuildDir, not in the SourceDir) + build tests in the VariantDir, not in the SourceDir) """ global SConfFS if not SConfFS: @@ -401,14 +401,19 @@ class SConfBase: # add default tests default_tests = { + 'CheckCC' : CheckCC, + 'CheckCXX' : CheckCXX, + 'CheckSHCC' : CheckSHCC, + 'CheckSHCXX' : CheckSHCXX, 'CheckFunc' : CheckFunc, 'CheckType' : CheckType, 'CheckTypeSize' : CheckTypeSize, + 'CheckDeclaration' : CheckDeclaration, 'CheckHeader' : CheckHeader, 'CheckCHeader' : CheckCHeader, 'CheckCXXHeader' : CheckCXXHeader, 'CheckLib' : CheckLib, - 'CheckLibWithHeader' : CheckLibWithHeader + 'CheckLibWithHeader' : CheckLibWithHeader, } self.AddTests(default_tests) self.AddTests(custom_tests) @@ -425,6 +430,31 @@ class SConfBase: self._shutdown() return self.env + def Define(self, name, value = None, comment = None): + """ + Define a pre processor symbol name, with the optional given value in the + current config header. + + If value is None (default), then #define name is written. If value is not + none, then #define name value is written. + + comment is a string which will be put as a C comment in the + header, to explain the meaning of the value (appropriate C comments /* and + */ will be put automatically.""" + lines = [] + if comment: + comment_str = "/* %s */" % comment + lines.append(comment_str) + + if value is not None: + define_str = "#define %s %s" % (name, value) + else: + define_str = "#define %s" % name + lines.append(define_str) + lines.append('') + + self.config_h_text = self.config_h_text + string.join(lines, '\n') + def BuildNodes(self, nodes): """ Tries to build the given nodes immediately. Returns 1 on success, @@ -797,6 +827,17 @@ class CheckContext: # TODO: should use self.vardict for $CC, $CPPFLAGS, etc. return not self.TryBuild(self.env.Object, text, ext) + def CompileSharedObject(self, text, ext): + self.sconf.cached = 1 + # TODO: should use self.vardict for $SHCC, $CPPFLAGS, etc. + return not self.TryBuild(self.env.SharedObject, text, ext) + + def RunProg(self, text, ext): + self.sconf.cached = 1 + # TODO: should use self.vardict for $CC, $CPPFLAGS, etc. + st, out = self.TryRun(text, ext) + return not st, out + def AppendLIBS(self, lib_name_list): oldLIBS = self.env.get( 'LIBS', [] ) self.env.Append(LIBS = lib_name_list) @@ -855,6 +896,13 @@ def CheckTypeSize(context, type_name, includes = "", language = None, expect = N context.did_show_result = 1 return res +def CheckDeclaration(context, declaration, includes = "", language = None): + res = SCons.Conftest.CheckDeclaration(context, declaration, + includes = includes, + language = language) + context.did_show_result = 1 + return not res + def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'): # used by CheckHeader and CheckLibWithHeader to produce C - #include # statements from the specified header (list) @@ -883,6 +931,22 @@ def CheckHeader(context, header, include_quotes = '<>', language = None): context.did_show_result = 1 return not res +def CheckCC(context): + res = SCons.Conftest.CheckCC(context) + return not res + +def CheckCXX(context): + res = SCons.Conftest.CheckCXX(context) + return not res + +def CheckSHCC(context): + res = SCons.Conftest.CheckSHCC(context) + return not res + +def CheckSHCXX(context): + res = SCons.Conftest.CheckSHCXX(context) + return not res + # Bram: Make this function obsolete? CheckHeader() is more generic. def CheckCHeader(context, header, include_quotes = '""'): diff --git a/scons/scons-local-0.97.0d20071212/SCons/SConsign.py b/scons/scons-local-1.2.0/SCons/SConsign.py similarity index 98% rename from scons/scons-local-0.97.0d20071212/SCons/SConsign.py rename to scons/scons-local-1.2.0/SCons/SConsign.py index 0e26f73ca..8e4c30c14 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/SConsign.py +++ b/scons/scons-local-1.2.0/SCons/SConsign.py @@ -5,7 +5,7 @@ Writing and reading information to the .sconsign file or files. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,9 +27,7 @@ Writing and reading information to the .sconsign file or files. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/SConsign.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/SConsign.py 3842 2008/12/20 22:59:52 scons" import cPickle import os diff --git a/scons/scons-local-1.2.0/SCons/Scanner/C.py b/scons/scons-local-1.2.0/SCons/Scanner/C.py new file mode 100644 index 000000000..926493e76 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Scanner/C.py @@ -0,0 +1,126 @@ +"""SCons.Scanner.C + +This module implements the depenency scanner for C/C++ code. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Scanner/C.py 3842 2008/12/20 22:59:52 scons" + +import SCons.Node.FS +import SCons.Scanner +import SCons.Util + +import SCons.cpp + +class SConsCPPScanner(SCons.cpp.PreProcessor): + """ + SCons-specific subclass of the cpp.py module's processing. + + We subclass this so that: 1) we can deal with files represented + by Nodes, not strings; 2) we can keep track of the files that are + missing. + """ + def __init__(self, *args, **kw): + apply(SCons.cpp.PreProcessor.__init__, (self,)+args, kw) + self.missing = [] + def initialize_result(self, fname): + self.result = SCons.Util.UniqueList([fname]) + def finalize_result(self, fname): + return self.result[1:] + def find_include_file(self, t): + keyword, quote, fname = t + result = SCons.Node.FS.find_file(fname, self.searchpath[quote]) + if not result: + self.missing.append((fname, self.current_file)) + return result + def read_file(self, file): + try: + fp = open(str(file.rfile())) + except EnvironmentError, e: + self.missing.append((file, self.current_file)) + return '' + else: + return fp.read() + +def dictify_CPPDEFINES(env): + cppdefines = env.get('CPPDEFINES', {}) + if cppdefines is None: + return {} + if SCons.Util.is_Sequence(cppdefines): + result = {} + for c in cppdefines: + if SCons.Util.is_Sequence(c): + result[c[0]] = c[1] + else: + result[c] = None + return result + if not SCons.Util.is_Dict(cppdefines): + return {cppdefines : None} + return cppdefines + +class SConsCPPScannerWrapper: + """ + The SCons wrapper around a cpp.py scanner. + + This is the actual glue between the calling conventions of generic + SCons scanners, and the (subclass of) cpp.py class that knows how + to look for #include lines with reasonably real C-preprocessor-like + evaluation of #if/#ifdef/#else/#elif lines. + """ + def __init__(self, name, variable): + self.name = name + self.path = SCons.Scanner.FindPathDirs(variable) + def __call__(self, node, env, path = ()): + cpp = SConsCPPScanner(current = node.get_dir(), + cpppath = path, + dict = dictify_CPPDEFINES(env)) + result = cpp(node) + for included, includer in cpp.missing: + fmt = "No dependency generated for file: %s (included from: %s) -- file not found" + SCons.Warnings.warn(SCons.Warnings.DependencyWarning, + fmt % (included, includer)) + return result + + def recurse_nodes(self, nodes): + return nodes + def select(self, node): + return self + +def CScanner(): + """Return a prototype Scanner instance for scanning source files + that use the C pre-processor""" + + # Here's how we would (or might) use the CPP scanner code above that + # knows how to evaluate #if/#ifdef/#else/#elif lines when searching + # for #includes. This is commented out for now until we add the + # right configurability to let users pick between the scanners. + #return SConsCPPScannerWrapper("CScanner", "CPPPATH") + + cs = SCons.Scanner.ClassicCPP("CScanner", + "$CPPSUFFIXES", + "CPPPATH", + '^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")') + return cs diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/D.py b/scons/scons-local-1.2.0/SCons/Scanner/D.py similarity index 66% rename from scons/scons-local-0.97.0d20071212/SCons/Scanner/D.py rename to scons/scons-local-1.2.0/SCons/Scanner/D.py index 1abfaa04f..97ece3a18 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/D.py +++ b/scons/scons-local-1.2.0/SCons/Scanner/D.py @@ -8,7 +8,7 @@ Coded by Andy Friesen """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,24 +30,39 @@ Coded by Andy Friesen # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Scanner/D.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Scanner/D.py 3842 2008/12/20 22:59:52 scons" +import re import string import SCons.Scanner def DScanner(): """Return a prototype Scanner instance for scanning D source files""" - ds = D(name = "DScanner", - suffixes = '$DSUFFIXES', - path_variable = 'DPATH', - regex = 'import\s+([^\;]*)\;') + ds = D() return ds class D(SCons.Scanner.Classic): + def __init__ (self): + SCons.Scanner.Classic.__init__ (self, + name = "DScanner", + suffixes = '$DSUFFIXES', + path_variable = 'DPATH', + regex = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;') + + self.cre2 = re.compile ('(?:import\s)?\s*([a-zA-Z0-9_.]+)\s*(?:,|;)', re.M) + def find_include(self, include, source_dir, path): # translate dots (package separators) to slashes inc = string.replace(include, '.', '/') i = SCons.Node.FS.find_file(inc + '.d', (source_dir,) + path) + if i is None: + i = SCons.Node.FS.find_file (inc + '.di', (source_dir,) + path) return i, include + + def find_include_names(self, node): + includes = [] + for i in self.cre.findall(node.get_contents()): + includes = includes + self.cre2.findall(i) + return includes diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/Dir.py b/scons/scons-local-1.2.0/SCons/Scanner/Dir.py similarity index 95% rename from scons/scons-local-0.97.0d20071212/SCons/Scanner/Dir.py rename to scons/scons-local-1.2.0/SCons/Scanner/Dir.py index 7a6a55f39..35d500861 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/Dir.py +++ b/scons/scons-local-1.2.0/SCons/Scanner/Dir.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Scanner/Dir.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Scanner/Dir.py 3842 2008/12/20 22:59:52 scons" import SCons.Node.FS import SCons.Scanner diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/Fortran.py b/scons/scons-local-1.2.0/SCons/Scanner/Fortran.py similarity index 98% rename from scons/scons-local-0.97.0d20071212/SCons/Scanner/Fortran.py rename to scons/scons-local-1.2.0/SCons/Scanner/Fortran.py index b3ebd0086..e629b80b0 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/Fortran.py +++ b/scons/scons-local-1.2.0/SCons/Scanner/Fortran.py @@ -5,7 +5,7 @@ This module implements the dependency scanner for Fortran code. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ This module implements the dependency scanner for Fortran code. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Scanner/Fortran.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Scanner/Fortran.py 3842 2008/12/20 22:59:52 scons" import re import string diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/IDL.py b/scons/scons-local-1.2.0/SCons/Scanner/IDL.py similarity index 90% rename from scons/scons-local-0.97.0d20071212/SCons/Scanner/IDL.py rename to scons/scons-local-1.2.0/SCons/Scanner/IDL.py index aee4b8f02..9bd172873 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/IDL.py +++ b/scons/scons-local-1.2.0/SCons/Scanner/IDL.py @@ -6,7 +6,7 @@ Definition Language) files. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,7 +28,7 @@ Definition Language) files. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Scanner/IDL.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Scanner/IDL.py 3842 2008/12/20 22:59:52 scons" import SCons.Node.FS import SCons.Scanner diff --git a/scons/scons-local-1.2.0/SCons/Scanner/LaTeX.py b/scons/scons-local-1.2.0/SCons/Scanner/LaTeX.py new file mode 100644 index 000000000..3e17e2548 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Scanner/LaTeX.py @@ -0,0 +1,334 @@ +"""SCons.Scanner.LaTeX + +This module implements the dependency scanner for LaTeX code. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Scanner/LaTeX.py 3842 2008/12/20 22:59:52 scons" + +import os.path +import string +import re + +import SCons.Scanner +import SCons.Util + +# list of graphics file extensions for TeX and LaTeX +TexGraphics = ['.eps', '.ps'] +LatexGraphics = ['.pdf', '.png', '.jpg', '.gif', '.tif'] + +# Used as a return value of modify_env_var if the variable is not set. +class _Null: + pass +_null = _Null + +# The user specifies the paths in env[variable], similar to other builders. +# They may be relative and must be converted to absolute, as expected +# by LaTeX and Co. The environment may already have some paths in +# env['ENV'][var]. These paths are honored, but the env[var] paths have +# higher precedence. All changes are un-done on exit. +def modify_env_var(env, var, abspath): + try: + save = env['ENV'][var] + except KeyError: + save = _null + env.PrependENVPath(var, abspath) + try: + if SCons.Util.is_List(env[var]): + #TODO(1.5) + #env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]]) + env.PrependENVPath(var, map(lambda p: os.path.abspath(str(p)), env[var])) + else: + # Split at os.pathsep to convert into absolute path + #TODO(1.5) env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)]) + env.PrependENVPath(var, map(lambda p: os.path.abspath(p), string.split(str(env[var]), os.pathsep))) + except KeyError: + pass + + # Convert into a string explicitly to append ":" (without which it won't search system + # paths as well). The problem is that env.AppendENVPath(var, ":") + # does not work, refuses to append ":" (os.pathsep). + + if SCons.Util.is_List(env['ENV'][var]): + # TODO(1.5) + #env['ENV'][var] = os.pathsep.join(env['ENV'][var]) + env['ENV'][var] = string.join(env['ENV'][var], os.pathsep) + # Append the trailing os.pathsep character here to catch the case with no env[var] + env['ENV'][var] = env['ENV'][var] + os.pathsep + + return save + +class FindENVPathDirs: + """A class to bind a specific *PATH variable name to a function that + will return all of the *path directories.""" + def __init__(self, variable): + self.variable = variable + def __call__(self, env, dir=None, target=None, source=None, argument=None): + import SCons.PathList + try: + path = env['ENV'][self.variable] + except KeyError: + return () + + dir = dir or env.fs._cwd + path = SCons.PathList.PathList(path).subst_path(env, target, source) + return tuple(dir.Rfindalldirs(path)) + + + +def LaTeXScanner(): + """Return a prototype Scanner instance for scanning LaTeX source files + when built with latex. + """ + ds = LaTeX(name = "LaTeXScanner", + suffixes = '$LATEXSUFFIXES', + # in the search order, see below in LaTeX class docstring + graphics_extensions = TexGraphics, + recursive = 0) + return ds + +def PDFLaTeXScanner(): + """Return a prototype Scanner instance for scanning LaTeX source files + when built with pdflatex. + """ + ds = LaTeX(name = "PDFLaTeXScanner", + suffixes = '$LATEXSUFFIXES', + # in the search order, see below in LaTeX class docstring + graphics_extensions = LatexGraphics, + recursive = 0) + return ds + +class LaTeX(SCons.Scanner.Base): + """Class for scanning LaTeX files for included files. + + Unlike most scanners, which use regular expressions that just + return the included file name, this returns a tuple consisting + of the keyword for the inclusion ("include", "includegraphics", + "input", or "bibliography"), and then the file name itself. + Based on a quick look at LaTeX documentation, it seems that we + should append .tex suffix for the "include" keywords, append .tex if + there is no extension for the "input" keyword, and need to add .bib + for the "bibliography" keyword that does not accept extensions by itself. + + Finally, if there is no extension for an "includegraphics" keyword + latex will append .ps or .eps to find the file, while pdftex may use .pdf, + .jpg, .tif, .mps, or .png. + + The actual subset and search order may be altered by + DeclareGraphicsExtensions command. This complication is ignored. + The default order corresponds to experimentation with teTeX + $ latex --version + pdfeTeX 3.141592-1.21a-2.2 (Web2C 7.5.4) + kpathsea version 3.5.4 + The order is: + ['.eps', '.ps'] for latex + ['.png', '.pdf', '.jpg', '.tif']. + + Another difference is that the search path is determined by the type + of the file being searched: + env['TEXINPUTS'] for "input" and "include" keywords + env['TEXINPUTS'] for "includegraphics" keyword + env['BIBINPUTS'] for "bibliography" keyword + env['BSTINPUTS'] for "bibliographystyle" keyword + + FIXME: also look for the class or style in document[class|style]{} + FIXME: also look for the argument of bibliographystyle{} + """ + keyword_paths = {'include': 'TEXINPUTS', + 'input': 'TEXINPUTS', + 'includegraphics': 'TEXINPUTS', + 'bibliography': 'BIBINPUTS', + 'bibliographystyle': 'BSTINPUTS', + 'usepackage': 'TEXINPUTS'} + env_variables = SCons.Util.unique(keyword_paths.values()) + + def __init__(self, name, suffixes, graphics_extensions, *args, **kw): + + # We have to include \n with the % we exclude from the first part + # part of the regex because the expression is compiled with re.M. + # Without the \n, the ^ could match the beginning of a *previous* + # line followed by one or more newline characters (i.e. blank + # lines), interfering with a match on the next line. + regex = r'^[^%\n]*\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography|usepackage){([^}]*)}' + self.cre = re.compile(regex, re.M) + self.graphics_extensions = graphics_extensions + + def _scan(node, env, path=(), self=self): + node = node.rfile() + if not node.exists(): + return [] + return self.scan(node, path) + + class FindMultiPathDirs: + """The stock FindPathDirs function has the wrong granularity: + it is called once per target, while we need the path that depends + on what kind of included files is being searched. This wrapper + hides multiple instances of FindPathDirs, one per the LaTeX path + variable in the environment. When invoked, the function calculates + and returns all the required paths as a dictionary (converted into + a tuple to become hashable). Then the scan function converts it + back and uses a dictionary of tuples rather than a single tuple + of paths. + """ + def __init__(self, dictionary): + self.dictionary = {} + for k,n in dictionary.items(): + self.dictionary[k] = ( SCons.Scanner.FindPathDirs(n), + FindENVPathDirs(n) ) + + def __call__(self, env, dir=None, target=None, source=None, + argument=None): + di = {} + for k,(c,cENV) in self.dictionary.items(): + di[k] = ( c(env, dir=None, target=None, source=None, + argument=None) , + cENV(env, dir=None, target=None, source=None, + argument=None) ) + # To prevent "dict is not hashable error" + return tuple(di.items()) + + class LaTeXScanCheck: + """Skip all but LaTeX source files, i.e., do not scan *.eps, + *.pdf, *.jpg, etc. + """ + def __init__(self, suffixes): + self.suffixes = suffixes + def __call__(self, node, env): + current = not node.has_builder() or node.is_up_to_date() + scannable = node.get_suffix() in env.subst_list(self.suffixes)[0] + # Returning false means that the file is not scanned. + return scannable and current + + kw['function'] = _scan + kw['path_function'] = FindMultiPathDirs(LaTeX.keyword_paths) + kw['recursive'] = 1 + kw['skeys'] = suffixes + kw['scan_check'] = LaTeXScanCheck(suffixes) + kw['name'] = name + + apply(SCons.Scanner.Base.__init__, (self,) + args, kw) + + def _latex_names(self, include): + filename = include[1] + if include[0] == 'input': + base, ext = os.path.splitext( filename ) + if ext == "": + return [filename + '.tex'] + if (include[0] == 'include'): + return [filename + '.tex'] + if include[0] == 'bibliography': + base, ext = os.path.splitext( filename ) + if ext == "": + return [filename + '.bib'] + if include[0] == 'usepackage': + base, ext = os.path.splitext( filename ) + if ext == "": + return [filename + '.sty'] + if include[0] == 'includegraphics': + base, ext = os.path.splitext( filename ) + if ext == "": + #TODO(1.5) return [filename + e for e in self.graphics_extensions] + return map(lambda e, f=filename: f+e, self.graphics_extensions) + return [filename] + + def sort_key(self, include): + return SCons.Node.FS._my_normcase(str(include)) + + def find_include(self, include, source_dir, path): + try: + sub_path = path[include[0]] + except (IndexError, KeyError): + sub_path = () + try_names = self._latex_names(include) + for n in try_names: + # see if we find it using the path in env[var] + i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[0]) + if i: + return i, include + # see if we find it using the path in env['ENV'][var] + i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[1]) + if i: + return i, include + return i, include + + def scan(self, node, path=()): + # Modify the default scan function to allow for the regular + # expression to return a comma separated list of file names + # as can be the case with the bibliography keyword. + + # Cache the includes list in node so we only scan it once: + path_dict = dict(list(path)) + noopt_cre = re.compile('\[.*$') + if node.includes != None: + includes = node.includes + else: + includes = self.cre.findall(node.get_contents()) + # 1. Split comma-separated lines, e.g. + # ('bibliography', 'phys,comp') + # should become two entries + # ('bibliography', 'phys') + # ('bibliography', 'comp') + # 2. Remove the options, e.g., such as + # ('includegraphics[clip,width=0.7\\linewidth]', 'picture.eps') + # should become + # ('includegraphics', 'picture.eps') + split_includes = [] + for include in includes: + inc_type = noopt_cre.sub('', include[0]) + inc_list = string.split(include[1],',') + for j in range(len(inc_list)): + split_includes.append( (inc_type, inc_list[j]) ) + # + includes = split_includes + node.includes = includes + + # This is a hand-coded DSU (decorate-sort-undecorate, or + # Schwartzian transform) pattern. The sort key is the raw name + # of the file as specifed on the \include, \input, etc. line. + # TODO: what about the comment in the original Classic scanner: + # """which lets + # us keep the sort order constant regardless of whether the file + # is actually found in a Repository or locally.""" + nodes = [] + source_dir = node.get_dir() + for include in includes: + # + # Handle multiple filenames in include[1] + # + n, i = self.find_include(include, source_dir, path_dict) + if n is None: + # Do not bother with 'usepackage' warnings, as they most + # likely refer to system-level files + if include[0] != 'usepackage': + SCons.Warnings.warn(SCons.Warnings.DependencyWarning, + "No dependency generated for file: %s (included from: %s) -- file not found" % (i, node)) + else: + sortkey = self.sort_key(n) + nodes.append((sortkey, n)) + # + nodes.sort() + nodes = map(lambda pair: pair[1], nodes) + return nodes diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/Prog.py b/scons/scons-local-1.2.0/SCons/Scanner/Prog.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Scanner/Prog.py rename to scons/scons-local-1.2.0/SCons/Scanner/Prog.py index aa7685f16..ad71ba449 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/Prog.py +++ b/scons/scons-local-1.2.0/SCons/Scanner/Prog.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Scanner/Prog.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Scanner/Prog.py 3842 2008/12/20 22:59:52 scons" import string @@ -54,10 +54,8 @@ def scan(node, env, libpath = ()): return [] if SCons.Util.is_String(libs): libs = string.split(libs) - elif SCons.Util.is_List(libs): - libs = SCons.Util.flatten(libs) else: - libs = [libs] + libs = SCons.Util.flatten(libs) try: prefix = env['LIBPREFIXES'] diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/C.py b/scons/scons-local-1.2.0/SCons/Scanner/RC.py similarity index 57% rename from scons/scons-local-0.97.0d20071212/SCons/Scanner/C.py rename to scons/scons-local-1.2.0/SCons/Scanner/RC.py index a79bea7c4..ecbc57256 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/C.py +++ b/scons/scons-local-1.2.0/SCons/Scanner/RC.py @@ -1,11 +1,12 @@ -"""SCons.Scanner.C +"""SCons.Scanner.RC -This module implements the depenency scanner for C/C++ code. +This module implements the depenency scanner for RC (Interface +Definition Language) files. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,16 +28,22 @@ This module implements the depenency scanner for C/C++ code. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Scanner/C.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Scanner/RC.py 3842 2008/12/20 22:59:52 scons" import SCons.Node.FS import SCons.Scanner +import re -def CScanner(): - """Return a prototype Scanner instance for scanning source files - that use the C pre-processor""" - cs = SCons.Scanner.ClassicCPP("CScanner", - "$CPPSUFFIXES", - "CPPPATH", - '^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")') - return cs +def RCScan(): + """Return a prototype Scanner instance for scanning RC source files""" + + res_re= r'^(?:\s*#\s*(?:include)|' \ + '.*?\s+(?:ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)' \ + '\s*.*?)' \ + '\s*(<|"| )([^>"\s]+)(?:[>" ])*$' + resScanner = SCons.Scanner.ClassicCPP( "ResourceScanner", + "$RCSUFFIXES", + "CPPPATH", + res_re ) + + return resScanner diff --git a/scons/scons-local-0.97.0d20071212/SCons/Scanner/__init__.py b/scons/scons-local-1.2.0/SCons/Scanner/__init__.py similarity index 97% rename from scons/scons-local-0.97.0d20071212/SCons/Scanner/__init__.py rename to scons/scons-local-1.2.0/SCons/Scanner/__init__.py index 07243c89a..e18f0fe30 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Scanner/__init__.py +++ b/scons/scons-local-1.2.0/SCons/Scanner/__init__.py @@ -5,7 +5,7 @@ The Scanner package for the SCons software construction utility. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ The Scanner package for the SCons software construction utility. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Scanner/__init__.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Scanner/__init__.py 3842 2008/12/20 22:59:52 scons" import re import string @@ -67,7 +67,7 @@ class FindPathDirs: will return all of the *path directories.""" def __init__(self, variable): self.variable = variable - def __call__(self, env, dir, target=None, source=None, argument=None): + def __call__(self, env, dir=None, target=None, source=None, argument=None): import SCons.PathList try: path = env[self.variable] @@ -346,13 +346,16 @@ class Classic(Current): def sort_key(self, include): return SCons.Node.FS._my_normcase(include) + def find_include_names(self, node): + return self.cre.findall(node.get_contents()) + def scan(self, node, path=()): # cache the includes list in node so we only scan it once: if node.includes != None: includes = node.includes else: - includes = self.cre.findall(node.get_contents()) + includes = self.find_include_names (node) node.includes = includes # This is a hand-coded DSU (decorate-sort-undecorate, or diff --git a/scons/scons-local-1.2.0/SCons/Script/Interactive.py b/scons/scons-local-1.2.0/SCons/Script/Interactive.py new file mode 100644 index 000000000..13cc41409 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Script/Interactive.py @@ -0,0 +1,376 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Script/Interactive.py 3842 2008/12/20 22:59:52 scons" + +__doc__ = """ +SCons interactive mode +""" + +# TODO: +# +# This has the potential to grow into something with a really big life +# of its own, which might or might not be a good thing. Nevertheless, +# here are some enhancements that will probably be requested some day +# and are worth keeping in mind (assuming this takes off): +# +# - A command to re-read / re-load the SConscript files. This may +# involve allowing people to specify command-line options (e.g. -f, +# -I, --no-site-dir) that affect how the SConscript files are read. +# +# - Additional command-line options on the "build" command. +# +# Of the supported options that seemed to make sense (after a quick +# pass through the list), the ones that seemed likely enough to be +# used are listed in the man page and have explicit test scripts. +# +# These had code changed in Script/Main.py to support them, but didn't +# seem likely to be used regularly, so had no test scripts added: +# +# build --diskcheck=* +# build --implicit-cache=* +# build --implicit-deps-changed=* +# build --implicit-deps-unchanged=* +# +# These look like they should "just work" with no changes to the +# existing code, but like those above, look unlikely to be used and +# therefore had no test scripts added: +# +# build --random +# +# These I'm not sure about. They might be useful for individual +# "build" commands, and may even work, but they seem unlikely enough +# that we'll wait until they're requested before spending any time on +# writing test scripts for them, or investigating whether they work. +# +# build -q [??? is there a useful analog to the exit status?] +# build --duplicate= +# build --profile= +# build --max-drift= +# build --warn=* +# build --Y +# +# - Most of the SCons command-line options that the "build" command +# supports should be settable as default options that apply to all +# subsequent "build" commands. Maybe a "set {option}" command that +# maps to "SetOption('{option}')". +# +# - Need something in the 'help' command that prints the -h output. +# +# - A command to run the configure subsystem separately (must see how +# this interacts with the new automake model). +# +# - Command-line completion of target names; maybe even of SCons options? +# Completion is something that's supported by the Python cmd module, +# so this should be doable without too much trouble. +# + +import cmd +import copy +import os +import re +import shlex +import string +import sys + +try: + import readline +except ImportError: + pass + +class SConsInteractiveCmd(cmd.Cmd): + """\ + build [TARGETS] Build the specified TARGETS and their dependencies. + 'b' is a synonym. + clean [TARGETS] Clean (remove) the specified TARGETS and their + dependencies. 'c' is a synonym. + exit Exit SCons interactive mode. + help [COMMAND] Prints help for the specified COMMAND. 'h' and + '?' are synonyms. + shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!' + are synonyms. + version Prints SCons version information. + """ + + synonyms = { + 'b' : 'build', + 'c' : 'clean', + 'h' : 'help', + 'scons' : 'build', + 'sh' : 'shell', + } + + def __init__(self, **kw): + cmd.Cmd.__init__(self) + for key, val in kw.items(): + setattr(self, key, val) + + if sys.platform == 'win32': + self.shell_variable = 'COMSPEC' + else: + self.shell_variable = 'SHELL' + + def default(self, argv): + print "*** Unknown command: %s" % argv[0] + + def onecmd(self, line): + line = string.strip(line) + if not line: + print self.lastcmd + return self.emptyline() + self.lastcmd = line + if line[0] == '!': + line = 'shell ' + line[1:] + elif line[0] == '?': + line = 'help ' + line[1:] + if os.sep == '\\': + line = string.replace(line, '\\', '\\\\') + argv = shlex.split(line) + argv[0] = self.synonyms.get(argv[0], argv[0]) + if not argv[0]: + return self.default(line) + else: + try: + func = getattr(self, 'do_' + argv[0]) + except AttributeError: + return self.default(argv) + return func(argv) + + def do_build(self, argv): + """\ + build [TARGETS] Build the specified TARGETS and their + dependencies. 'b' is a synonym. + """ + import SCons.Node + import SCons.SConsign + import SCons.Script.Main + + options = copy.deepcopy(self.options) + + options, targets = self.parser.parse_args(argv[1:], values=options) + + SCons.Script.COMMAND_LINE_TARGETS = targets + + if targets: + SCons.Script.BUILD_TARGETS = targets + else: + # If the user didn't specify any targets on the command line, + # use the list of default targets. + SCons.Script.BUILD_TARGETS = SCons.Script._build_plus_default + + nodes = SCons.Script.Main._build_targets(self.fs, + options, + targets, + self.target_top) + + if not nodes: + return + + # Call each of the Node's alter_targets() methods, which may + # provide additional targets that ended up as part of the build + # (the canonical example being a VariantDir() when we're building + # from a source directory) and which we therefore need their + # state cleared, too. + x = [] + for n in nodes: + x.extend(n.alter_targets()[0]) + nodes.extend(x) + + # Clean up so that we can perform the next build correctly. + # + # We do this by walking over all the children of the targets, + # and clearing their state. + # + # We currently have to re-scan each node to find their + # children, because built nodes have already been partially + # cleared and don't remember their children. (In scons + # 0.96.1 and earlier, this wasn't the case, and we didn't + # have to re-scan the nodes.) + # + # Because we have to re-scan each node, we can't clear the + # nodes as we walk over them, because we may end up rescanning + # a cleared node as we scan a later node. Therefore, only + # store the list of nodes that need to be cleared as we walk + # the tree, and clear them in a separate pass. + # + # XXX: Someone more familiar with the inner workings of scons + # may be able to point out a more efficient way to do this. + + SCons.Script.Main.progress_display("scons: Clearing cached node information ...") + + seen_nodes = {} + + def get_unseen_children(node, parent, seen_nodes=seen_nodes): + def is_unseen(node, seen_nodes=seen_nodes): + return not seen_nodes.has_key(node) + return filter(is_unseen, node.children(scan=1)) + + def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes): + seen_nodes[node] = 1 + + # If this file is in a VariantDir and has a + # corresponding source file in the source tree, remember the + # node in the source tree, too. This is needed in + # particular to clear cached implicit dependencies on the + # source file, since the scanner will scan it if the + # VariantDir was created with duplicate=0. + try: + rfile_method = node.rfile + except AttributeError: + return + else: + rfile = rfile_method() + if rfile != node: + seen_nodes[rfile] = 1 + + for node in nodes: + walker = SCons.Node.Walker(node, + kids_func=get_unseen_children, + eval_func=add_to_seen_nodes) + n = walker.next() + while n: + n = walker.next() + + for node in seen_nodes.keys(): + # Call node.clear() to clear most of the state + node.clear() + # node.clear() doesn't reset node.state, so call + # node.set_state() to reset it manually + node.set_state(SCons.Node.no_state) + node.implicit = None + + # Debug: Uncomment to verify that all Taskmaster reference + # counts have been reset to zero. + #if node.ref_count != 0: + # from SCons.Debug import Trace + # Trace('node %s, ref_count %s !!!\n' % (node, node.ref_count)) + + SCons.SConsign.Reset() + SCons.Script.Main.progress_display("scons: done clearing node information.") + + def do_clean(self, argv): + """\ + clean [TARGETS] Clean (remove) the specified TARGETS + and their dependencies. 'c' is a synonym. + """ + return self.do_build(['build', '--clean'] + argv[1:]) + + def do_EOF(self, argv): + print + self.do_exit(argv) + + def _do_one_help(self, arg): + try: + # If help_() exists, then call it. + func = getattr(self, 'help_' + arg) + except AttributeError: + try: + func = getattr(self, 'do_' + arg) + except AttributeError: + doc = None + else: + doc = self._doc_to_help(func) + if doc: + sys.stdout.write(doc + '\n') + sys.stdout.flush() + else: + doc = self.strip_initial_spaces(func()) + if doc: + sys.stdout.write(doc + '\n') + sys.stdout.flush() + + def _doc_to_help(self, obj): + doc = obj.__doc__ + if doc is None: + return '' + return self._strip_initial_spaces(doc) + + def _strip_initial_spaces(self, s): + #lines = s.split('\n') + lines = string.split(s, '\n') + spaces = re.match(' *', lines[0]).group(0) + #def strip_spaces(l): + # if l.startswith(spaces): + # l = l[len(spaces):] + # return l + #return '\n'.join([ strip_spaces(l) for l in lines ]) + def strip_spaces(l, spaces=spaces): + if l[:len(spaces)] == spaces: + l = l[len(spaces):] + return l + lines = map(strip_spaces, lines) + return string.join(lines, '\n') + + def do_exit(self, argv): + """\ + exit Exit SCons interactive mode. + """ + sys.exit(0) + + def do_help(self, argv): + """\ + help [COMMAND] Prints help for the specified COMMAND. 'h' + and '?' are synonyms. + """ + if argv[1:]: + for arg in argv[1:]: + if self._do_one_help(arg): + break + else: + # If bare 'help' is called, print this class's doc + # string (if it has one). + doc = self._doc_to_help(self.__class__) + if doc: + sys.stdout.write(doc + '\n') + sys.stdout.flush() + + def do_shell(self, argv): + """\ + shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and + '!' are synonyms. + """ + import subprocess + argv = argv[1:] + if not argv: + argv = os.environ[self.shell_variable] + try: + p = subprocess.Popen(argv) + except EnvironmentError, e: + sys.stderr.write('scons: %s: %s\n' % (argv[0], e.strerror)) + else: + p.wait() + + def do_version(self, argv): + """\ + version Prints SCons version information. + """ + sys.stdout.write(self.parser.version + '\n') + +def interact(fs, parser, options, targets, target_top): + c = SConsInteractiveCmd(prompt = 'scons>>> ', + fs = fs, + parser = parser, + options = options, + targets = targets, + target_top = target_top) + c.cmdloop() diff --git a/scons/scons-local-0.97.0d20071212/SCons/Script/Main.py b/scons/scons-local-1.2.0/SCons/Script/Main.py similarity index 80% rename from scons/scons-local-0.97.0d20071212/SCons/Script/Main.py rename to scons/scons-local-1.2.0/SCons/Script/Main.py index 764cba67c..5624038c0 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Script/Main.py +++ b/scons/scons-local-1.2.0/SCons/Script/Main.py @@ -12,7 +12,7 @@ it goes here. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -34,9 +34,7 @@ it goes here. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Script/Main.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/Script/Main.py 3842 2008/12/20 22:59:52 scons" import os import os.path @@ -68,6 +66,18 @@ import SCons.Taskmaster import SCons.Util import SCons.Warnings +import SCons.Script.Interactive + +def fetch_win32_parallel_msg(): + # A subsidiary function that exists solely to isolate this import + # so we don't have to pull it in on all platforms, and so that an + # in-line "import" statement in the _main() function below doesn't + # cause warnings about local names shadowing use of the 'SCons' + # globl in nest scopes and UnboundLocalErrors and the like in some + # versions (2.1) of Python. + import SCons.Platform.win32 + return SCons.Platform.win32.parallel_msg + # class SConsPrintHelpException(Exception): @@ -156,49 +166,60 @@ class BuildTask(SCons.Taskmaster.Task): self.progress(self.targets[0]) return SCons.Taskmaster.Task.prepare(self) - def execute(self): - for target in self.targets: - if target.get_state() == SCons.Node.up_to_date: - continue - if target.has_builder() and not hasattr(target.builder, 'status'): - if print_time: - start_time = time.time() - global first_command_start - if first_command_start is None: - first_command_start = start_time - SCons.Taskmaster.Task.execute(self) - if print_time: - global cumulative_command_time - global last_command_end - finish_time = time.time() - last_command_end = finish_time - cumulative_command_time = cumulative_command_time+finish_time-start_time - sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time)) - break + def needs_execute(self): + target = self.targets[0] + if target.get_state() == SCons.Node.executing: + return True else: if self.top and target.has_builder(): display("scons: `%s' is up to date." % str(self.node)) + return False + + def execute(self): + if print_time: + start_time = time.time() + global first_command_start + if first_command_start is None: + first_command_start = start_time + SCons.Taskmaster.Task.execute(self) + if print_time: + global cumulative_command_time + global last_command_end + finish_time = time.time() + last_command_end = finish_time + cumulative_command_time = cumulative_command_time+finish_time-start_time + sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time)) def do_failed(self, status=2): _BuildFailures.append(self.exception[1]) global exit_status + global this_build_status if self.options.ignore_errors: SCons.Taskmaster.Task.executed(self) elif self.options.keep_going: SCons.Taskmaster.Task.fail_continue(self) exit_status = status + this_build_status = status else: SCons.Taskmaster.Task.fail_stop(self) exit_status = status + this_build_status = status def executed(self): t = self.targets[0] if self.top and not t.has_builder() and not t.side_effect: if not t.exists(): - sys.stderr.write("scons: *** Do not know how to make target `%s'." % t) + errstr="Do not know how to make target `%s'." % t + sys.stderr.write("scons: *** " + errstr) if not self.options.keep_going: sys.stderr.write(" Stop.") sys.stderr.write("\n") + try: + raise SCons.Errors.BuildError(t, errstr) + except KeyboardInterrupt: + raise + except: + self.exception_set() self.do_failed() else: print "scons: Nothing to be done for `%s'." % t @@ -210,54 +231,55 @@ class BuildTask(SCons.Taskmaster.Task): # Handle the failure of a build task. The primary purpose here # is to display the various types of Errors and Exceptions # appropriately. - status = 2 exc_info = self.exc_info() try: t, e, tb = exc_info except ValueError: t, e = exc_info tb = None + if t is None: # The Taskmaster didn't record an exception for this Task; # see if the sys module has one. - t, e = sys.exc_info()[:2] + try: + t, e, tb = sys.exc_info()[:] + except ValueError: + t, e = exc_info + tb = None + + # Deprecated string exceptions will have their string stored + # in the first entry of the tuple. + if e is None: + e = t - def nodestring(n): - if not SCons.Util.is_List(n): - n = [ n ] - return string.join(map(str, n), ', ') + buildError = SCons.Errors.convert_to_BuildError(e) + if not buildError.node: + buildError.node = self.node + + node = buildError.node + if not SCons.Util.is_List(node): + node = [ node ] + nodename = string.join(map(str, node), ', ') errfmt = "scons: *** [%s] %s\n" + sys.stderr.write(errfmt % (nodename, buildError)) - if t == SCons.Errors.BuildError: - tname = nodestring(e.node) - errstr = e.errstr - if e.filename: - errstr = e.filename + ': ' + errstr - sys.stderr.write(errfmt % (tname, errstr)) - elif t == SCons.Errors.TaskmasterException: - tname = nodestring(e.node) - sys.stderr.write(errfmt % (tname, e.errstr)) - type, value, trace = e.exc_info + if (buildError.exc_info[2] and buildError.exc_info[1] and + # TODO(1.5) + #not isinstance( + # buildError.exc_info[1], + # (EnvironmentError, SCons.Errors.StopError, SCons.Errors.UserError))): + not isinstance(buildError.exc_info[1], EnvironmentError) and + not isinstance(buildError.exc_info[1], SCons.Errors.StopError) and + not isinstance(buildError.exc_info[1], SCons.Errors.UserError)): + type, value, trace = buildError.exc_info traceback.print_exception(type, value, trace) - elif t == SCons.Errors.ExplicitExit: - status = e.status - tname = nodestring(e.node) - errstr = 'Explicit exit, status %s' % status - sys.stderr.write(errfmt % (tname, errstr)) - else: - if e is None: - e = t - s = str(e) - if t == SCons.Errors.StopError and not self.options.keep_going: - s = s + ' Stop.' - sys.stderr.write("scons: *** %s\n" % s) + elif tb and print_stacktrace: + sys.stderr.write("scons: internal stack trace:\n") + traceback.print_tb(tb, file=sys.stderr) - if tb and print_stacktrace: - sys.stderr.write("scons: internal stack trace:\n") - traceback.print_tb(tb, file=sys.stderr) - - self.do_failed(status) + self.exception = (e, buildError, tb) # type, value, traceback + self.do_failed(buildError.exitstatus) self.exc_clear() @@ -366,7 +388,9 @@ class QuestionTask(SCons.Taskmaster.Task): if self.targets[0].get_state() != SCons.Node.up_to_date or \ (self.top and not self.targets[0].exists()): global exit_status + global this_build_status exit_status = 1 + this_build_status = 1 self.tm.stop() def executed(self): @@ -392,6 +416,16 @@ class TreePrinter: SCons.Util.print_tree(t, func, prune=self.prune, showtags=s) +def python_version_string(): + return string.split(sys.version)[0] + +def python_version_unsupported(version=sys.version_info): + return version < (1, 5, 2) + +def python_version_deprecated(version=sys.version_info): + return version < (2, 2, 0) + + # Global variables print_objects = 0 @@ -400,7 +434,8 @@ print_stacktrace = 0 print_time = 0 sconscript_time = 0 cumulative_command_time = 0 -exit_status = 0 # exit status, assume success by default +exit_status = 0 # final exit status, assume success by default +this_build_status = 0 # "exit status" of an individual build num_jobs = None delayed_warnings = [] @@ -566,57 +601,14 @@ def _scons_internal_error(): traceback.print_exc() sys.exit(2) -def _setup_warn(arg): - """The --warn option. An argument to this option - should be of the form or no-. - The warning class is munged in order to get an actual class - name from the SCons.Warnings module to enable or disable. - The supplied is split on hyphens, each element - is captialized, then smushed back together. Then the string - "SCons.Warnings." is added to the front and "Warning" is added - to the back to get the fully qualified class name. - - For example, --warn=deprecated will enable the - SCons.Warnings.DeprecatedWarning class. - - --warn=no-dependency will disable the - SCons.Warnings.DependencyWarning class. - - As a special case, --warn=all and --warn=no-all - will enable or disable (respectively) the base - class of all warnings, which is SCons.Warning.Warning.""" - - elems = string.split(string.lower(arg), '-') - enable = 1 - if elems[0] == 'no': - enable = 0 - del elems[0] - - if len(elems) == 1 and elems[0] == 'all': - class_name = "Warning" - else: - def _capitalize(s): - if s[:5] == "scons": - return "SCons" + s[5:] - else: - return string.capitalize(s) - class_name = string.join(map(_capitalize, elems), '') + "Warning" - try: - clazz = getattr(SCons.Warnings, class_name) - except AttributeError: - sys.stderr.write("No warning type: '%s'\n" % arg) - else: - if enable: - SCons.Warnings.enableWarningClass(clazz) - else: - SCons.Warnings.suppressWarningClass(clazz) - -def _SConstruct_exists(dirname='', repositories=[]): +def _SConstruct_exists(dirname='', repositories=[], filelist=None): """This function checks that an SConstruct file exists in a directory. If so, it returns the path of the file. By default, it checks the current directory. """ - for file in ['SConstruct', 'Sconstruct', 'sconstruct']: + if not filelist: + filelist = ['SConstruct', 'Sconstruct', 'sconstruct'] + for file in filelist: sfile = os.path.join(dirname, file) if os.path.isfile(sfile): return sfile @@ -730,8 +722,8 @@ def version_string(label, module): module.__buildsys__) def _main(parser): - import SCons global exit_status + global this_build_status options = parser.values @@ -745,17 +737,22 @@ def _main(parser): default_warnings = [ SCons.Warnings.CorruptSConsignWarning, SCons.Warnings.DeprecatedWarning, SCons.Warnings.DuplicateEnvironmentWarning, + SCons.Warnings.FutureReservedVariableWarning, + SCons.Warnings.LinkWarning, SCons.Warnings.MissingSConscriptWarning, SCons.Warnings.NoMD5ModuleWarning, SCons.Warnings.NoMetaclassSupportWarning, SCons.Warnings.NoObjectCountWarning, SCons.Warnings.NoParallelSupportWarning, - SCons.Warnings.MisleadingKeywordsWarning, ] + SCons.Warnings.MisleadingKeywordsWarning, + SCons.Warnings.ReservedVariableWarning, + SCons.Warnings.StackSizeWarning, + ] + for warning in default_warnings: SCons.Warnings.enableWarningClass(warning) SCons.Warnings._warningOut = _scons_internal_warning - if options.warn: - _setup_warn(options.warn) + SCons.Warnings.process_warn_strings(options.warn) # Now that we have the warnings configuration set up, we can actually # issue (or suppress) any warnings about warning-worthy things that @@ -788,13 +785,15 @@ def _main(parser): if options.climb_up: target_top = '.' # directory to prepend to targets script_dir = os.getcwd() # location of script - while script_dir and not _SConstruct_exists(script_dir, options.repository): + while script_dir and not _SConstruct_exists(script_dir, + options.repository, + options.file): script_dir, last_part = os.path.split(script_dir) if last_part: target_top = os.path.join(last_part, target_top) else: script_dir = '' - if script_dir: + if script_dir and script_dir != os.getcwd(): display("scons: Entering directory `%s'" % script_dir) os.chdir(script_dir) @@ -813,7 +812,8 @@ def _main(parser): if options.file: scripts.extend(options.file) if not scripts: - sfile = _SConstruct_exists(repositories=options.repository) + sfile = _SConstruct_exists(repositories=options.repository, + filelist=options.file) if sfile: scripts.append(sfile) @@ -835,10 +835,10 @@ def _main(parser): SCons.Node.implicit_cache = options.implicit_cache SCons.Node.implicit_deps_changed = options.implicit_deps_changed SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged + if options.no_exec: SCons.SConf.dryrun = 1 SCons.Action.execute_actions = None - CleanTask.execute = CleanTask.show if options.question: SCons.SConf.dryrun = 1 if options.clean: @@ -850,19 +850,6 @@ def _main(parser): if options.no_progress or options.silent: progress_display.set_mode(0) - if options.silent: - display.set_mode(0) - if options.silent: - SCons.Action.print_actions = None - - if options.cache_disable: - SCons.CacheDir.CacheDir = SCons.Util.Null() - if options.cache_debug: - SCons.CacheDir.cache_debug = options.cache_debug - if options.cache_force: - SCons.CacheDir.cache_force = True - if options.cache_show: - SCons.CacheDir.cache_show = True if options.site_dir: _load_site_scons_dir(d, options.site_dir) @@ -887,7 +874,18 @@ def _main(parser): SCons.Script._Add_Targets(targets + parser.rargs) SCons.Script._Add_Arguments(xmit_args) - sys.stdout = SCons.Util.Unbuffered(sys.stdout) + # If stdout is not a tty, replace it with a wrapper object to call flush + # after every write. + # + # Tty devices automatically flush after every newline, so the replacement + # isn't necessary. Furthermore, if we replace sys.stdout, the readline + # module will no longer work. This affects the behavior during + # --interactive mode. --interactive should only be used when stdin and + # stdout refer to a tty. + if not sys.stdout.isatty(): + sys.stdout = SCons.Util.Unbuffered(sys.stdout) + if not sys.stderr.isatty(): + sys.stderr = SCons.Util.Unbuffered(sys.stderr) memory_stats.append('before reading SConscript files:') count_stats.append(('pre-', 'read')) @@ -902,7 +900,7 @@ def _main(parser): SCons.Script._SConscript._SConscript(fs, script) except SCons.Errors.StopError, e: # We had problems reading an SConscript file, such as it - # couldn't be copied in to the BuildDir. Since we're just + # couldn't be copied in to the VariantDir. Since we're just # reading SConscript files and haven't started building # things yet, stop regardless of whether they used -i or -k # or anything else. @@ -917,6 +915,26 @@ def _main(parser): memory_stats.append('after reading SConscript files:') count_stats.append(('post-', 'read')) + # Re-{enable,disable} warnings in case they disabled some in + # the SConscript file. + # + # We delay enabling the PythonVersionWarning class until here so that, + # if they explicity disabled it in either in the command line or in + # $SCONSFLAGS, or in the SConscript file, then the search through + # the list of deprecated warning classes will find that disabling + # first and not issue the warning. + SCons.Warnings.enableWarningClass(SCons.Warnings.PythonVersionWarning) + SCons.Warnings.process_warn_strings(options.warn) + + # Now that we've read the SConscript files, we can check for the + # warning about deprecated Python versions--delayed until here + # in case they disabled the warning in the SConscript files. + if python_version_deprecated(): + msg = "Support for pre-2.2 Python (%s) is deprecated.\n" + \ + " If this will cause hardship, contact dev@scons.tigris.org." + SCons.Warnings.warn(SCons.Warnings.PythonVersionWarning, + msg % python_version_string()) + if not options.help: SCons.SConf.CreateConfigHBuilder(SCons.Defaults.DefaultEnvironment()) @@ -943,7 +961,7 @@ def _main(parser): # Change directory to the top-level SConstruct directory, then tell # the Node.FS subsystem that we're all done reading the SConscript - # files and calling Repository() and BuildDir() and changing + # files and calling Repository() and VariantDir() and changing # directories and the like, so it can go ahead and start memoizing # the string values of file system nodes. @@ -957,6 +975,49 @@ def _main(parser): SCons.Node.FS.set_duplicate(options.duplicate) fs.set_max_drift(options.max_drift) + SCons.Job.explicit_stack_size = options.stack_size + + if options.md5_chunksize: + SCons.Node.FS.File.md5_chunksize = options.md5_chunksize + + platform = SCons.Platform.platform_module() + + if options.interactive: + SCons.Script.Interactive.interact(fs, OptionsParser, options, + targets, target_top) + + else: + + # Build the targets + nodes = _build_targets(fs, options, targets, target_top) + if not nodes: + exit_status = 2 + +def _build_targets(fs, options, targets, target_top): + + global this_build_status + this_build_status = 0 + + progress_display.set_mode(not (options.no_progress or options.silent)) + display.set_mode(not options.silent) + SCons.Action.print_actions = not options.silent + SCons.Action.execute_actions = not options.no_exec + SCons.Node.FS.do_store_info = not options.no_exec + SCons.SConf.dryrun = options.no_exec + + if options.diskcheck: + SCons.Node.FS.set_diskcheck(options.diskcheck) + + SCons.CacheDir.cache_enabled = not options.cache_disable + SCons.CacheDir.cache_debug = options.cache_debug + SCons.CacheDir.cache_force = options.cache_force + SCons.CacheDir.cache_show = options.cache_show + + if options.no_exec: + CleanTask.execute = CleanTask.show + else: + CleanTask.execute = CleanTask.remove + lookup_top = None if targets or SCons.Script.BUILD_TARGETS != SCons.Script._build_plus_default: # They specified targets on the command line or modified @@ -1003,7 +1064,7 @@ def _main(parser): if not targets: sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n") - sys.exit(2) + return None def Entry(x, ltop=lookup_top, ttop=target_top, fs=fs): if isinstance(x, SCons.Node.Node): @@ -1046,7 +1107,7 @@ def _main(parser): opening_message = "Cleaning targets ..." closing_message = "done cleaning targets." if options.keep_going: - closing_message = "done cleaning targets (errors occurred during clean)." + failure_message = "done cleaning targets (errors occurred during clean)." else: failure_message = "cleaning terminated because of errors." except AttributeError: @@ -1091,29 +1152,43 @@ def _main(parser): msg = "parallel builds are unsupported by this version of Python;\n" + \ "\tignoring -j or num_jobs option.\n" elif sys.platform == 'win32': - import SCons.Platform.win32 - msg = SCons.Platform.win32.parallel_msg + msg = fetch_win32_parallel_msg() if msg: SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg) memory_stats.append('before building targets:') count_stats.append(('pre-', 'build')) - try: - progress_display("scons: " + opening_message) - jobs.run() - finally: - jobs.cleanup() - if exit_status: + def jobs_postfunc( + jobs=jobs, + options=options, + closing_message=closing_message, + failure_message=failure_message + ): + if jobs.were_interrupted(): + progress_display("scons: Build interrupted.") + global exit_status + global this_build_status + exit_status = 2 + this_build_status = 2 + + if this_build_status: progress_display("scons: " + failure_message) else: progress_display("scons: " + closing_message) if not options.no_exec: + if jobs.were_interrupted(): + progress_display("scons: writing .sconsign file.") SCons.SConsign.write() + progress_display("scons: " + opening_message) + jobs.run(postfunc = jobs_postfunc) + memory_stats.append('after building targets:') count_stats.append(('post-', 'build')) + return nodes + def _exec_main(parser, values): sconsflags = os.environ.get('SCONSFLAGS', '') all_args = string.split(sconsflags) + sys.argv[1:] @@ -1124,7 +1199,10 @@ def _exec_main(parser, values): import pdb pdb.Pdb().runcall(_main, parser) elif options.profile_file: - from profile import Profile + try: + from cProfile import Profile + except ImportError, e: + from profile import Profile # Some versions of Python 2.4 shipped a profiler that had the # wrong 'c_exception' entry in its dispatch table. Make sure @@ -1155,17 +1233,25 @@ def main(): global exit_status global first_command_start + # Check up front for a Python version we do not support. We + # delay the check for deprecated Python versions until later, + # after the SConscript files have been read, in case they + # disable that warning. + if python_version_unsupported(): + msg = "scons: *** SCons version %s does not run under Python version %s.\n" + sys.stderr.write(msg % (SCons.__version__, python_version_string())) + sys.exit(1) + parts = ["SCons by Steven Knight et al.:\n"] try: + import __main__ parts.append(version_string("script", __main__)) - except KeyboardInterrupt: - raise - except: + except (ImportError, AttributeError): # On Windows there is no scons.py, so there is no # __main__.__version__, hence there is no script version. pass parts.append(version_string("engine", SCons)) - parts.append("Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation") + parts.append("Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation") version = string.join(parts, '') import SConsOptions @@ -1180,7 +1266,7 @@ def main(): if s: exit_status = s except KeyboardInterrupt: - print "Build interrupted." + print("scons: Build interrupted.") sys.exit(2) except SyntaxError, e: _scons_syntax_error(e) @@ -1191,6 +1277,8 @@ def main(): except SConsPrintHelpException: parser.print_help() exit_status = 0 + except SCons.Errors.BuildError, e: + exit_status = e.exitstatus except: # An exception here is likely a builtin Python exception Python # code in an SConscript file. Show them precisely what the diff --git a/scons/scons-local-0.97.0d20071212/SCons/Script/SConsOptions.py b/scons/scons-local-1.2.0/SCons/Script/SConsOptions.py similarity index 87% rename from scons/scons-local-0.97.0d20071212/SCons/Script/SConsOptions.py rename to scons/scons-local-1.2.0/SCons/Script/SConsOptions.py index d466d43d8..636fd2024 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Script/SConsOptions.py +++ b/scons/scons-local-1.2.0/SCons/Script/SConsOptions.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,15 +21,21 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Script/SConsOptions.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/Script/SConsOptions.py 3842 2008/12/20 22:59:52 scons" import optparse +import re import string import sys import textwrap +try: + no_hyphen_re = re.compile(r'(\s+|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') +except re.error: + # Pre-2.0 Python versions don't have the (?<= negative + # look-behind assertion. + no_hyphen_re = re.compile(r'(\s+|-*\w{2,}-(?=\w{2,}))') + try: from gettext import gettext except ImportError: @@ -38,6 +44,7 @@ except ImportError: _ = gettext import SCons.Node.FS +import SCons.Warnings OptionValueError = optparse.OptionValueError SUPPRESS_HELP = optparse.SUPPRESS_HELP @@ -119,9 +126,12 @@ class SConsValues(optparse.Values): 'help', 'implicit_cache', 'max_drift', + 'md5_chunksize', 'no_exec', 'num_jobs', 'random', + 'stack_size', + 'warn', ] def set_option(self, name, value): @@ -163,6 +173,21 @@ class SConsValues(optparse.Values): # Set this right away so it can affect the rest of the # file/Node lookups while processing the SConscript files. SCons.Node.FS.set_diskcheck(value) + elif name == 'stack_size': + try: + value = int(value) + except ValueError: + raise SCons.Errors.UserError, "An integer is required: %s"%repr(value) + elif name == 'md5_chunksize': + try: + value = int(value) + except ValueError: + raise SCons.Errors.UserError, "An integer is required: %s"%repr(value) + elif name == 'warn': + if SCons.Util.is_String(value): + value = [value] + value = self.__SConscript_settings__.get(name, []) + value + SCons.Warnings.process_warn_strings(value) self.__SConscript_settings__[name] = value @@ -369,8 +394,16 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): def format_option(self, option): """ A copy of the normal optparse.IndentedHelpFormatter.format_option() - method, snarfed so we can set the subsequent_indent on the - textwrap.wrap() call below... + method. This has been snarfed so we can modify text wrapping to + out liking: + + -- add our own regular expression that doesn't break on hyphens + (so things like --no-print-directory don't get broken); + + -- wrap the list of options themselves when it's too long + (the wrapper.fill(opts) call below); + + -- set the subsequent_indent when wrapping the help_text. """ # The help for each option consists of two parts: # * the opt strings and metavars @@ -397,7 +430,11 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): opt_width = self.help_position - self.current_indent - 2 if len(opts) > opt_width: - opts = "%*s%s\n" % (self.current_indent, "", opts) + wrapper = textwrap.TextWrapper(width=self.width, + initial_indent = ' ', + subsequent_indent = ' ') + wrapper.wordsep_re = no_hyphen_re + opts = wrapper.fill(opts) + '\n' indent_first = self.help_position else: # start help on same line as opts opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) @@ -415,8 +452,10 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): help_text = expand_default(option) # SCons: indent every line of the help text but the first. - help_lines = textwrap.wrap(help_text, self.help_width, - subsequent_indent = ' ') + wrapper = textwrap.TextWrapper(width=self.help_width, + subsequent_indent = ' ') + wrapper.wordsep_re = no_hyphen_re + help_lines = wrapper.wrap(help_text) result.append("%*s%s\n" % (indent_first, "", help_lines[0])) for line in help_lines[1:]: result.append("%*s%s\n" % (self.help_position, "", line)) @@ -466,6 +505,7 @@ def Parser(version): usage="usage: scons [OPTION] [TARGET] ...",) op.preserve_unknown_options = True + op.version = version # Add the options to the parser we just created. # @@ -489,8 +529,13 @@ def Parser(version): # options ignored for compatibility def opt_ignore(option, opt, value, parser): sys.stderr.write("Warning: ignoring %s option\n" % opt) - op.add_option("-b", "-m", "-S", "-t", - "--no-keep-going", "--stop", "--touch", + op.add_option("-b", "-d", "-e", "-m", "-S", "-t", "-w", + "--environment-overrides", + "--no-keep-going", + "--no-print-directory", + "--print-directory", + "--stop", + "--touch", action="callback", callback=opt_ignore, help="Ignored for compatibility.") @@ -543,42 +588,38 @@ def Parser(version): help = opt_config_help, metavar="MODE") - def opt_not_yet(option, opt, value, parser): - sys.stderr.write("Warning: the %s option is not yet implemented\n" % opt) - sys.exit(0) - op.add_option('-d', - action="callback", callback=opt_not_yet, - help = "Print file dependency information.") - op.add_option('-D', dest="climb_up", default=None, action="store_const", const=2, help="Search up directory tree for SConstruct, " "build all Default() targets.") - debug_options = ["count", "dtree", "explain", "findlibs", - "includes", "memoizer", "memory", "objects", - "pdb", "presub", "stacktrace", "stree", - "time", "tree"] - deprecated_debug_options = { - "nomemoizer" : ' and has no effect', + "dtree" : '; please use --tree=derived instead', + "nomemoizer" : ' and has no effect', + "stree" : '; please use --tree=all,status instead', + "tree" : '; please use --tree=all instead', } + debug_options = ["count", "explain", "findlibs", + "includes", "memoizer", "memory", "objects", + "pdb", "presub", "stacktrace", + "time"] + deprecated_debug_options.keys() + def opt_debug(option, opt, value, parser, debug_options=debug_options, deprecated_debug_options=deprecated_debug_options): if value in debug_options: parser.values.debug.append(value) - elif value in deprecated_debug_options.keys(): - try: - parser.values.delayed_warnings - except AttributeError: - parser.values.delayed_warnings = [] - msg = deprecated_debug_options[value] - w = "The --debug=%s option is deprecated%s." % (value, msg) - t = (SCons.Warnings.DeprecatedWarning, w) - parser.values.delayed_warnings.append(t) + if value in deprecated_debug_options.keys(): + try: + parser.values.delayed_warnings + except AttributeError: + parser.values.delayed_warnings = [] + msg = deprecated_debug_options[value] + w = "The --debug=%s option is deprecated%s." % (value, msg) + t = (SCons.Warnings.DeprecatedWarning, w) + parser.values.delayed_warnings.append(t) else: raise OptionValueError("Warning: %s is not a valid debug type" % value) opt_debug_help = "Print various types of debugging information: %s." \ @@ -667,6 +708,11 @@ def Parser(version): action="callback", callback=opt_implicit_deps, help="Ignore changes in implicit dependencies.") + op.add_option('--interact', '--interactive', + dest='interactive', default=False, + action="store_true", + help="Run in interactive mode.") + op.add_option('-j', '--jobs', nargs=1, type="int", dest="num_jobs", default=1, @@ -686,6 +732,13 @@ def Parser(version): help="Set maximum system clock drift to N seconds.", metavar="N") + op.add_option('--md5-chunksize', + nargs=1, type="int", + dest='md5_chunksize', default=SCons.Node.FS.File.md5_chunksize, + action="store", + help="Set chunk-size for MD5 signature computation to N kilobytes.", + metavar="N") + op.add_option('-n', '--no-exec', '--just-print', '--dry-run', '--recon', dest='no_exec', default=False, action="store_true", @@ -730,6 +783,13 @@ def Parser(version): help="Use DIR instead of the usual site_scons dir.", metavar="DIR") + op.add_option('--stack-size', + nargs=1, type="int", + dest='stack_size', + action="store", + help="Set the stack size of the threads used to run jobs to N kilobytes.", + metavar="N") + op.add_option('--taskmastertrace', nargs=1, dest="taskmastertrace_file", default=None, @@ -777,17 +837,22 @@ def Parser(version): help="Search up directory tree for SConstruct, " "build Default() targets from local SConscript.") - def opt_version(option, opt, value, parser, version=version): - sys.stdout.write(version + '\n') + def opt_version(option, opt, value, parser): + sys.stdout.write(parser.version + '\n') sys.exit(0) op.add_option("-v", "--version", action="callback", callback=opt_version, help="Print the SCons version number and exit.") + def opt_warn(option, opt, value, parser, tree_options=tree_options): + if SCons.Util.is_String(value): + value = string.split(value, ',') + parser.values.warn.extend(value) + op.add_option('--warn', '--warning', - nargs=1, - dest="warn", default=None, - action="store", + nargs=1, type="string", + dest="warn", default=[], + action="callback", callback=opt_warn, help="Enable or disable warnings.", metavar="WARNING-SPEC") @@ -802,11 +867,12 @@ def Parser(version): # we don't want to change. These all get a "the -X option is not # yet implemented" message and don't show up in the help output. - op.add_option('-e', '--environment-overrides', - dest="environment_overrides", - action="callback", callback=opt_not_yet, - # help="Environment variables override makefiles." - help=SUPPRESS_HELP) + def opt_not_yet(option, opt, value, parser): + msg = "Warning: the %s option is not yet implemented\n" % opt + sys.stderr.write(msg) + sys.exit(0) + + op.add_option('-l', '--load-average', '--max-load', nargs=1, type="int", dest="load_average", default=0, @@ -853,16 +919,6 @@ def Parser(version): dest="no_builtin_rules", # help="Clear default environments and variables." help=SUPPRESS_HELP) - op.add_option('-w', '--print-directory', - action="callback", callback=opt_not_yet, - dest="print_directory", - # help="Print the current directory." - help=SUPPRESS_HELP) - op.add_option('--no-print-directory', - action="callback", callback=opt_not_yet, - dest="no_print_directory", - # help="Turn off -w, even if it was turned on implicitly." - help=SUPPRESS_HELP) op.add_option('--write-filenames', nargs=1, type="string", dest="write_filenames", diff --git a/scons/scons-local-0.97.0d20071212/SCons/Script/SConscript.py b/scons/scons-local-1.2.0/SCons/Script/SConscript.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Script/SConscript.py rename to scons/scons-local-1.2.0/SCons/Script/SConscript.py index 42350d384..c52c9798a 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Script/SConscript.py +++ b/scons/scons-local-1.2.0/SCons/Script/SConscript.py @@ -6,7 +6,7 @@ files. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,7 +28,7 @@ files. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Script/SConscript.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Script/SConscript.py 3842 2008/12/20 22:59:52 scons" import SCons import SCons.Action @@ -39,7 +39,6 @@ import SCons.Errors import SCons.Node import SCons.Node.Alias import SCons.Node.FS -import SCons.Options import SCons.Platform import SCons.SConf import SCons.Script.Main @@ -82,7 +81,10 @@ def get_calling_namespaces(): """Return the locals and globals for the function that called into this module in the current call stack.""" try: 1/0 - except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame + except ZeroDivisionError: + # Don't start iterating with the current stack-frame to + # prevent creating reference cycles (f_back is safe). + frame = sys.exc_info()[2].tb_frame.f_back # Find the first frame that *isn't* from this file. This means # that we expect all of the SCons frames that implement an Export() @@ -141,7 +143,8 @@ call_stack = [] def Return(*vars, **kw): retval = [] try: - for var in vars: + fvars = SCons.Util.flatten(vars) + for var in fvars: for v in string.split(var): retval.append(call_stack[-1].globals[v]) except KeyError, x: @@ -276,7 +279,20 @@ def _SConscript(fs, *files, **kw): fs.chdir(frame.prev_dir, change_os_dir=0) rdir = frame.prev_dir.rdir() rdir._create() # Make sure there's a directory there. - os.chdir(rdir.get_abspath()) + try: + os.chdir(rdir.get_abspath()) + except OSError, e: + # We still couldn't chdir there, so raise the error, + # but only if actions are being executed. + # + # If the -n option was used, the directory would *not* + # have been created and we should just carry on and + # let things muddle through. This isn't guaranteed + # to work if the SConscript files are reading things + # from disk (for example), but it should work well + # enough for most configurations. + if SCons.Action.execute_actions: + raise e results.append(frame.retval) @@ -403,16 +419,16 @@ class SConsEnvironment(SCons.Environment.Base): if kw.get('exports'): exports.extend(self.Split(kw['exports'])) - build_dir = kw.get('build_dir') - if build_dir: + variant_dir = kw.get('variant_dir') or kw.get('build_dir') + if variant_dir: if len(files) != 1: raise SCons.Errors.UserError, \ - "Invalid SConscript() usage - can only specify one SConscript with a build_dir" + "Invalid SConscript() usage - can only specify one SConscript with a variant_dir" duplicate = kw.get('duplicate', 1) src_dir = kw.get('src_dir') if not src_dir: src_dir, fname = os.path.split(str(files[0])) - files = [os.path.join(str(build_dir), fname)] + files = [os.path.join(str(variant_dir), fname)] else: if not isinstance(src_dir, SCons.Node.Node): src_dir = self.fs.Dir(src_dir) @@ -422,11 +438,11 @@ class SConsEnvironment(SCons.Environment.Base): if fn.is_under(src_dir): # Get path relative to the source directory. fname = fn.get_path(src_dir) - files = [os.path.join(str(build_dir), fname)] + files = [os.path.join(str(variant_dir), fname)] else: files = [fn.abspath] - kw['src_dir'] = build_dir - self.fs.BuildDir(build_dir, src_dir, duplicate) + kw['src_dir'] = variant_dir + self.fs.VariantDir(variant_dir, src_dir, duplicate) return (files, exports) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Script/__init__.py b/scons/scons-local-1.2.0/SCons/Script/__init__.py similarity index 95% rename from scons/scons-local-0.97.0d20071212/SCons/Script/__init__.py rename to scons/scons-local-1.2.0/SCons/Script/__init__.py index 414798caa..ad9999131 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Script/__init__.py +++ b/scons/scons-local-1.2.0/SCons/Script/__init__.py @@ -12,7 +12,7 @@ it goes here. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -34,7 +34,7 @@ it goes here. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Script/__init__.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Script/__init__.py 3842 2008/12/20 22:59:52 scons" import time start_time = time.time() @@ -84,6 +84,7 @@ import SCons.SConf import SCons.Subst import SCons.Tool import SCons.Util +import SCons.Variables import SCons.Defaults import Main @@ -138,22 +139,31 @@ call_stack = _SConscript.call_stack Action = SCons.Action.Action AddMethod = SCons.Util.AddMethod AllowSubstExceptions = SCons.Subst.SetAllowableExceptions -BoolOption = SCons.Options.BoolOption Builder = SCons.Builder.Builder Configure = _SConscript.Configure -EnumOption = SCons.Options.EnumOption Environment = SCons.Environment.Environment #OptParser = SCons.SConsOptions.OptParser FindPathDirs = SCons.Scanner.FindPathDirs -ListOption = SCons.Options.ListOption -PackageOption = SCons.Options.PackageOption -PathOption = SCons.Options.PathOption Platform = SCons.Platform.Platform Return = _SConscript.Return Scanner = SCons.Scanner.Base Tool = SCons.Tool.Tool WhereIs = SCons.Util.WhereIs +# +BoolVariable = SCons.Variables.BoolVariable +EnumVariable = SCons.Variables.EnumVariable +ListVariable = SCons.Variables.ListVariable +PackageVariable = SCons.Variables.PackageVariable +PathVariable = SCons.Variables.PathVariable + +# Deprecated names that will go away some day. +BoolOption = SCons.Options.BoolOption +EnumOption = SCons.Options.EnumOption +ListOption = SCons.Options.ListOption +PackageOption = SCons.Options.PackageOption +PathOption = SCons.Options.PathOption + # Action factories. Chmod = SCons.Defaults.Chmod Copy = SCons.Defaults.Copy @@ -262,6 +272,9 @@ def HelpFunction(text): sconscript_reading = 0 # +def Variables(files=[], args=ARGUMENTS): + return SCons.Variables.Variables(files, args) + def Options(files=[], args=ARGUMENTS): return SCons.Options.Options(files, args) @@ -321,6 +334,7 @@ GlobalDefaultEnvironmentFunctions = [ 'Tag', 'TargetSignatures', 'Value', + 'VariantDir', ] GlobalDefaultBuilders = [ diff --git a/scons/scons-local-0.97.0d20071212/SCons/Sig.py b/scons/scons-local-1.2.0/SCons/Sig.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Sig.py rename to scons/scons-local-1.2.0/SCons/Sig.py index 454f16460..2e50308c5 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Sig.py +++ b/scons/scons-local-1.2.0/SCons/Sig.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Sig.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Sig.py 3842 2008/12/20 22:59:52 scons" __doc__ = """Place-holder for the old SCons.Sig module hierarchy diff --git a/scons/scons-local-0.97.0d20071212/SCons/Subst.py b/scons/scons-local-1.2.0/SCons/Subst.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Subst.py rename to scons/scons-local-1.2.0/SCons/Subst.py index bff27ae25..afebca43f 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Subst.py +++ b/scons/scons-local-1.2.0/SCons/Subst.py @@ -5,7 +5,7 @@ SCons string substitution. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,9 +27,7 @@ SCons string substitution. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Subst.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/Subst.py 3842 2008/12/20 22:59:52 scons" import re import string @@ -39,11 +37,11 @@ import UserString import SCons.Errors -from SCons.Util import is_String, is_List, is_Tuple +from SCons.Util import is_String, is_Sequence # Indexed by the SUBST_* constants below. -_strconv = [SCons.Util.to_String, - SCons.Util.to_String, +_strconv = [SCons.Util.to_String_for_subst, + SCons.Util.to_String_for_subst, SCons.Util.to_String_for_signature] @@ -188,7 +186,7 @@ class NLWrapper: list = self.list if list is None: list = [] - elif not is_List(list) and not is_Tuple(list): + elif not is_Sequence(list): list = [list] # The map(self.func) call is what actually turns # a list into appropriate proxies. @@ -203,10 +201,10 @@ class Targets_or_Sources(UserList.UserList): wrapping a NLWrapper. This class handles the different methods used to access the list, calling the NLWrapper to create proxies on demand. - Note that we subclass UserList.UserList purely so that the is_List() - function will identify an object of this class as a list during - variable expansion. We're not really using any UserList.UserList - methods in practice. + Note that we subclass UserList.UserList purely so that the + is_Sequence() function will identify an object of this class as + a list during variable expansion. We're not really using any + UserList.UserList methods in practice. """ def __init__(self, nl): self.nl = nl @@ -272,7 +270,13 @@ def subst_dict(target, source): dict = {} if target: - tnl = NLWrapper(target, lambda x: x.get_subst_proxy()) + def get_tgt_subst_proxy(thing): + try: + subst_proxy = thing.get_subst_proxy() + except AttributeError: + subst_proxy = thing # probably a string, just return it + return subst_proxy + tnl = NLWrapper(target, get_tgt_subst_proxy) dict['TARGETS'] = Targets_or_Sources(tnl) dict['TARGET'] = Target_or_Source(tnl) else: @@ -287,7 +291,10 @@ def subst_dict(target, source): pass else: node = rfile() - return node.get_subst_proxy() + try: + return node.get_subst_proxy() + except AttributeError: + return node # probably a String, just return it snl = NLWrapper(source, get_src_subst_proxy) dict['SOURCES'] = Targets_or_Sources(snl) dict['SOURCE'] = Target_or_Source(snl) @@ -312,6 +319,25 @@ _remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)') # Indexed by the SUBST_* constants above. _regex_remove = [ _rm, None, _remove ] +def _rm_list(list): + #return [ l for l in list if not l in ('$(', '$)') ] + return filter(lambda l: not l in ('$(', '$)'), list) + +def _remove_list(list): + result = [] + do_append = result.append + for l in list: + if l == '$(': + do_append = lambda x: None + elif l == '$)': + do_append = result.append + else: + do_append(l) + return result + +# Indexed by the SUBST_* constants above. +_list_remove = [ _rm_list, None, _remove_list ] + # Regular expressions for splitting strings and handling substitutions, # for use by the scons_subst() and scons_subst_list() functions: # @@ -342,7 +368,8 @@ _separate_args = re.compile(r'(%s|\s+|[^\s\$]+|\$)' % _dollar_exps_str) _space_sep = re.compile(r'[\t ]+(?![^{]*})') def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None): - """Expand a string containing construction variable substitutions. + """Expand a string or list containing construction variable + substitutions. This is the work-horse function for substitutions in file names and the like. The companion scons_subst_list() function (below) @@ -427,11 +454,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ var = string.split(key, '.')[0] lv[var] = '' return self.substitute(s, lv) - elif is_List(s) or is_Tuple(s): + elif is_Sequence(s): def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars): return conv(substitute(l, lvars)) - r = map(func, s) - return string.join(r) + return map(func, s) elif callable(s): try: s = s(target=self.target, @@ -458,6 +484,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ separate tokens. """ if is_String(args) and not isinstance(args, CmdStringHolder): + args = str(args) # In case it's a UserString. try: def sub_match(match, conv=self.conv, expand=self.expand, lvars=lvars): return conv(expand(match.group(1), lvars)) @@ -472,11 +499,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ result = [] for a in args: result.append(self.conv(self.expand(a, lvars))) - try: - result = string.join(result, '') - except TypeError: - if len(result) == 1: - result = result[0] + if len(result) == 1: + result = result[0] + else: + result = string.join(map(str, result), '') return result else: return self.expand(args, lvars) @@ -524,6 +550,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ # Compress strings of white space characters into # a single space. result = string.strip(_space_sep.sub(' ', result)) + elif is_Sequence(result): + remove = _list_remove[mode] + if remove: + result = remove(result) return result @@ -542,7 +572,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv # except KeyError: # Subst_List_Strings[strSubst] = 1 # import SCons.Debug -# SCons.Debug.caller(1) +# SCons.Debug.caller_trace(1) class ListSubber(UserList.UserList): """A class to construct the results of a scons_subst_list() call. @@ -634,7 +664,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv lv[var] = '' self.substitute(s, lv, 0) self.this_word() - elif is_List(s) or is_Tuple(s): + elif is_Sequence(s): for a in s: self.substitute(a, lvars, 1) self.next_word() @@ -666,6 +696,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv """ if is_String(args) and not isinstance(args, CmdStringHolder): + args = str(args) # In case it's a UserString. args = _separate_args.findall(args) for a in args: if a[0] in ' \t\n\r\f\v': @@ -827,18 +858,18 @@ def scons_subst_once(strSubst, env, key): a = match.group(1) if a in matchlist: a = val - if is_List(a) or is_Tuple(a): + if is_Sequence(a): return string.join(map(str, a)) else: return str(a) - if is_List(strSubst) or is_Tuple(strSubst): + if is_Sequence(strSubst): result = [] for arg in strSubst: if is_String(arg): if arg in matchlist: arg = val - if is_List(arg) or is_Tuple(arg): + if is_Sequence(arg): result.extend(arg) else: result.append(arg) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Taskmaster.py b/scons/scons-local-1.2.0/SCons/Taskmaster.py similarity index 50% rename from scons/scons-local-0.97.0d20071212/SCons/Taskmaster.py rename to scons/scons-local-1.2.0/SCons/Taskmaster.py index 2fc4b08aa..354fcca4f 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Taskmaster.py +++ b/scons/scons-local-1.2.0/SCons/Taskmaster.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -48,20 +48,24 @@ interface and the SCons build engine. There are two key classes here: target(s) that it decides need to be evaluated and/or built. """ -__revision__ = "src/engine/SCons/Taskmaster.py 2523 2007/12/12 09:37:41 knight" - -import SCons.compat +__revision__ = "src/engine/SCons/Taskmaster.py 3842 2008/12/20 22:59:52 scons" +from itertools import chain import operator import string import sys import traceback -import SCons.Node import SCons.Errors +import SCons.Node StateString = SCons.Node.StateString - +NODE_NO_STATE = SCons.Node.no_state +NODE_PENDING = SCons.Node.pending +NODE_EXECUTING = SCons.Node.executing +NODE_UP_TO_DATE = SCons.Node.up_to_date +NODE_EXECUTED = SCons.Node.executed +NODE_FAILED = SCons.Node.failed # A subsystem for recording stats about how different Nodes are handled by @@ -134,6 +138,10 @@ class Task: self.node = node self.exc_clear() + def trace_message(self, method, node, description='node'): + fmt = '%-20s %s %s\n' + return fmt % (method + ':', description, self.tm.trace_node(node)) + def display(self, message): """ Hook to allow the calling interface to display a message. @@ -155,6 +163,8 @@ class Task: unlink underlying files and make all necessary directories before the Action is actually called to build the targets. """ + T = self.tm.trace + if T: T.write(self.trace_message('Task.prepare()', self.node)) # Now that it's the appropriate time, give the TaskMaster a # chance to raise any exceptions it encountered while preparing @@ -165,6 +175,17 @@ class Task: self.display(self.tm.message) self.tm.message = None + # Let the targets take care of any necessary preparations. + # This includes verifying that all of the necessary sources + # and dependencies exist, removing the target file(s), etc. + # + # As of April 2008, the get_executor().prepare() method makes + # sure that all of the aggregate sources necessary to build this + # Task's target(s) exist in one up-front check. The individual + # target t.prepare() methods check that each target's explicit + # or implicit dependencies exists, and also initialize the + # .sconsign info. + self.targets[0].get_executor().prepare() for t in self.targets: t.prepare() for s in t.side_effects: @@ -175,6 +196,17 @@ class Task: """ return self.node + def needs_execute(self): + """ + Called to determine whether the task's execute() method should + be run. + + This method allows one to skip the somethat costly execution + of the execute() method in a seperate thread. For example, + that would be unnecessary for up-to-date targets. + """ + return True + def execute(self): """ Called to execute the task. @@ -183,6 +215,8 @@ class Task: so only do thread safe stuff here. Do thread unsafe stuff in prepare(), executed() or failed(). """ + T = self.tm.trace + if T: T.write(self.trace_message('Task.execute()', self.node)) try: everything_was_cached = 1 @@ -192,8 +226,6 @@ class Task: break if not everything_was_cached: self.targets[0].build() - except KeyboardInterrupt: - raise except SystemExit: exc_value = sys.exc_info()[1] raise SCons.Errors.ExplicitExit(self.targets[0], exc_value.code) @@ -201,9 +233,11 @@ class Task: raise except SCons.Errors.BuildError: raise - except: - raise SCons.Errors.TaskmasterException(self.targets[0], - sys.exc_info()) + except Exception, e: + buildError = SCons.Errors.convert_to_BuildError(e) + buildError.node = self.targets[0] + buildError.exc_info = sys.exc_info() + raise buildError def executed_without_callbacks(self): """ @@ -211,11 +245,15 @@ class Task: and the Taskmaster instance doesn't want to call the Node's callback methods. """ + T = self.tm.trace + if T: T.write(self.trace_message('Task.executed_without_callbacks()', + self.node)) + for t in self.targets: - if t.get_state() == SCons.Node.executing: + if t.get_state() == NODE_EXECUTING: for side_effect in t.side_effects: - side_effect.set_state(SCons.Node.no_state) - t.set_state(SCons.Node.executed) + side_effect.set_state(NODE_NO_STATE) + t.set_state(NODE_EXECUTED) def executed_with_callbacks(self): """ @@ -230,11 +268,15 @@ class Task: post-visit actions that must take place regardless of whether or not the target was an actual built target or a source Node. """ + T = self.tm.trace + if T: T.write(self.trace_message('Task.executed_with_callbacks()', + self.node)) + for t in self.targets: - if t.get_state() == SCons.Node.executing: + if t.get_state() == NODE_EXECUTING: for side_effect in t.side_effects: - side_effect.set_state(SCons.Node.no_state) - t.set_state(SCons.Node.executed) + side_effect.set_state(NODE_NO_STATE) + t.set_state(NODE_EXECUTED) t.built() t.visited() @@ -243,15 +285,32 @@ class Task: def failed(self): """ Default action when a task fails: stop the build. + + Note: Although this function is normally invoked on nodes in + the executing state, it might also be invoked on up-to-date + nodes when using Configure(). """ self.fail_stop() def fail_stop(self): """ Explicit stop-the-build failure. + + This sets failure status on the target nodes and all of + their dependent parent nodes. + + Note: Although this function is normally invoked on nodes in + the executing state, it might also be invoked on up-to-date + nodes when using Configure(). """ - for t in self.targets: - t.set_state(SCons.Node.failed) + T = self.tm.trace + if T: T.write(self.trace_message('Task.failed_stop()', self.node)) + + # Invoke will_not_build() to clean-up the pending children + # list. + self.tm.will_not_build(self.targets, lambda n: n.set_state(NODE_FAILED)) + + # Tell the taskmaster to not start any new tasks self.tm.stop() # We're stopping because of a build failure, but give the @@ -266,12 +325,15 @@ class Task: This sets failure status on the target nodes and all of their dependent parent nodes. + + Note: Although this function is normally invoked on nodes in + the executing state, it might also be invoked on up-to-date + nodes when using Configure(). """ - for t in self.targets: - # Set failure state on all of the parents that were dependent - # on this failed build. - def set_state(node): node.set_state(SCons.Node.failed) - t.call_for_all_waiting_parents(set_state) + T = self.tm.trace + if T: T.write(self.trace_message('Task.failed_continue()', self.node)) + + self.tm.will_not_build(self.targets, lambda n: n.set_state(NODE_FAILED)) def make_ready_all(self): """ @@ -280,11 +342,14 @@ class Task: This is used when the interface needs every target Node to be visited--the canonical example being the "scons -c" option. """ + T = self.tm.trace + if T: T.write(self.trace_message('Task.make_ready_all()', self.node)) + self.out_of_date = self.targets[:] for t in self.targets: - t.disambiguate().set_state(SCons.Node.executing) + t.disambiguate().set_state(NODE_EXECUTING) for s in t.side_effects: - s.set_state(SCons.Node.executing) + s.set_state(NODE_EXECUTING) def make_ready_current(self): """ @@ -293,7 +358,12 @@ class Task: This is the default behavior for building only what's necessary. """ + T = self.tm.trace + if T: T.write(self.trace_message('Task.make_ready_current()', + self.node)) + self.out_of_date = [] + needs_executing = False for t in self.targets: try: t.disambiguate().make_ready() @@ -301,13 +371,24 @@ class Task: (not t.always_build and t.is_up_to_date()) except EnvironmentError, e: raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename) - if is_up_to_date: - t.set_state(SCons.Node.up_to_date) - else: + + if not is_up_to_date: self.out_of_date.append(t) - t.set_state(SCons.Node.executing) + needs_executing = True + + if needs_executing: + for t in self.targets: + t.set_state(NODE_EXECUTING) for s in t.side_effects: - s.set_state(SCons.Node.executing) + s.set_state(NODE_EXECUTING) + else: + for t in self.targets: + # We must invoke visited() to ensure that the node + # information has been computed before allowing the + # parent nodes to execute. (That could occur in a + # parallel build...) + t.visited() + t.set_state(NODE_UP_TO_DATE) make_ready = make_ready_current @@ -321,6 +402,8 @@ class Task: waiting parent Nodes, or Nodes waiting on a common side effect, that can be put back on the candidates list. """ + T = self.tm.trace + if T: T.write(self.trace_message('Task.postprocess()', self.node)) # We may have built multiple targets, some of which may have # common parents waiting for this build. Count up how many @@ -331,24 +414,34 @@ class Task: targets = set(self.targets) + pending_children = self.tm.pending_children parents = {} for t in targets: - for p in t.waiting_parents.keys(): + # A node can only be in the pending_children set if it has + # some waiting_parents. + if t.waiting_parents: + if T: T.write(self.trace_message('Task.postprocess()', + t, + 'removing')) + pending_children.discard(t) + for p in t.waiting_parents: parents[p] = parents.get(p, 0) + 1 for t in targets: for s in t.side_effects: - if s.get_state() == SCons.Node.executing: - s.set_state(SCons.Node.no_state) - for p in s.waiting_parents.keys(): - if not parents.has_key(p): - parents[p] = 1 - for p in s.waiting_s_e.keys(): + if s.get_state() == NODE_EXECUTING: + s.set_state(NODE_NO_STATE) + for p in s.waiting_parents: + parents[p] = parents.get(p, 0) + 1 + for p in s.waiting_s_e: if p.ref_count == 0: self.tm.candidates.append(p) for p, subtract in parents.items(): p.ref_count = p.ref_count - subtract + if T: T.write(self.trace_message('Task.postprocess()', + p, + 'adjusted parent ref count')) if p.ref_count == 0: self.tm.candidates.append(p) @@ -409,12 +502,15 @@ class Task: raise exc_type, exc_value, exc_traceback -def find_cycle(stack): - if stack[0] == stack[-1]: - return stack - for n in stack[-1].waiting_parents.keys(): +def find_cycle(stack, visited): + if stack[-1] in visited: + return None + visited.add(stack[-1]) + for n in stack[-1].waiting_parents: stack.append(n) - if find_cycle(stack): + if stack[0] == stack[-1]: + return stack + if find_cycle(stack, visited): return stack stack.pop() return None @@ -437,6 +533,7 @@ class Taskmaster: self.message = None self.trace = trace self.next_candidate = self.find_next_candidate + self.pending_children = set() def find_next_candidate(self): """ @@ -477,9 +574,104 @@ class Taskmaster: def no_next_candidate(self): """ Stops Taskmaster processing by not returning a next candidate. + + Note that we have to clean-up the Taskmaster candidate list + because the cycle detection depends on the fact all nodes have + been processed somehow. """ + while self.candidates: + candidates = self.candidates + self.candidates = [] + self.will_not_build(candidates) return None + def _validate_pending_children(self): + """ + Validate the content of the pending_children set. Assert if an + internal error is found. + + This function is used strictly for debugging the taskmaster by + checking that no invariants are violated. It is not used in + normal operation. + + The pending_children set is used to detect cycles in the + dependency graph. We call a "pending child" a child that is + found in the "pending" state when checking the dependencies of + its parent node. + + A pending child can occur when the Taskmaster completes a loop + through a cycle. For example, lets imagine a graph made of + three node (A, B and C) making a cycle. The evaluation starts + at node A. The taskmaster first consider whether node A's + child B is up-to-date. Then, recursively, node B needs to + check whether node C is up-to-date. This leaves us with a + dependency graph looking like: + + Next candidate \ + \ + Node A (Pending) --> Node B(Pending) --> Node C (NoState) + ^ | + | | + +-------------------------------------+ + + Now, when the Taskmaster examines the Node C's child Node A, + it finds that Node A is in the "pending" state. Therefore, + Node A is a pending child of node C. + + Pending children indicate that the Taskmaster has potentially + loop back through a cycle. We say potentially because it could + also occur when a DAG is evaluated in parallel. For example, + consider the following graph: + + + Node A (Pending) --> Node B(Pending) --> Node C (Pending) --> ... + | ^ + | | + +----------> Node D (NoState) --------+ + / + Next candidate / + + The Taskmaster first evaluates the nodes A, B, and C and + starts building some children of node C. Assuming, that the + maximum parallel level has not been reached, the Taskmaster + will examine Node D. It will find that Node C is a pending + child of Node D. + + In summary, evaluating a graph with a cycle will always + involve a pending child at one point. A pending child might + indicate either a cycle or a diamond-shaped DAG. Only a + fraction of the nodes ends-up being a "pending child" of + another node. This keeps the pending_children set small in + practice. + + We can differentiate between the two cases if we wait until + the end of the build. At this point, all the pending children + nodes due to a diamond-shaped DAG will have been properly + built (or will have failed to build). But, the pending + children involved in a cycle will still be in the pending + state. + + The taskmaster removes nodes from the pending_children set as + soon as a pending_children node moves out of the pending + state. This also helps to keep the pending_children set small. + """ + + for n in self.pending_children: + assert n.state in (NODE_PENDING, NODE_EXECUTING), \ + (str(n), StateString[n.state]) + assert len(n.waiting_parents) != 0, (str(n), len(n.waiting_parents)) + for p in n.waiting_parents: + assert p.ref_count > 0, (str(n), str(p), p.ref_count) + + + def trace_message(self, message): + return 'Taskmaster: %s\n' % message + + def trace_node(self, node): + return '<%-10s %-3s %s>' % (StateString[node.get_state()], + node.ref_count, + repr(str(node))) + def _find_next_ready_node(self): """ Finds the next node that is ready to be built. @@ -505,15 +697,25 @@ class Taskmaster: self.ready_exc = None T = self.trace + if T: T.write('\n' + self.trace_message('Looking for a node to evaluate')) while 1: node = self.next_candidate() if node is None: + if T: T.write(self.trace_message('No candidate anymore.') + '\n') return None node = node.disambiguate() state = node.get_state() + # For debugging only: + # + # try: + # self._validate_pending_children() + # except: + # self.ready_exc = sys.exc_info() + # return node + if CollectStats: if not hasattr(node, 'stats'): node.stats = Stats() @@ -523,119 +725,138 @@ class Taskmaster: else: S = None - if T: T.write('Taskmaster: %s:' % repr(str(node))) + if T: T.write(self.trace_message(' Considering node %s and its children:' % self.trace_node(node))) - # Skip this node if it has already been evaluated: - if state > SCons.Node.pending: + if state == NODE_NO_STATE: + # Mark this node as being on the execution stack: + node.set_state(NODE_PENDING) + elif state > NODE_PENDING: + # Skip this node if it has already been evaluated: if S: S.already_handled = S.already_handled + 1 - if T: T.write(' already handled (%s)\n' % StateString[state]) + if T: T.write(self.trace_message(' already handled (executed)')) continue - # Mark this node as being on the execution stack: - node.set_state(SCons.Node.pending) - try: - children = node.children() + node.prerequisites + children = node.children() except SystemExit: exc_value = sys.exc_info()[1] e = SCons.Errors.ExplicitExit(node, exc_value.code) self.ready_exc = (SCons.Errors.ExplicitExit, e) - if T: T.write(' SystemExit\n') + if T: T.write(self.trace_message(' SystemExit')) return node - except KeyboardInterrupt: - if T: T.write(' KeyboardInterrupt\n') - raise - except: + except Exception, e: # We had a problem just trying to figure out the # children (like a child couldn't be linked in to a - # BuildDir, or a Scanner threw something). Arrange to + # VariantDir, or a Scanner threw something). Arrange to # raise the exception when the Task is "executed." self.ready_exc = sys.exc_info() if S: S.problem = S.problem + 1 - if T: T.write(' exception\n') + if T: T.write(self.trace_message(' exception %s while scanning children.\n' % e)) return node - if T and children: - c = map(str, children) - c.sort() - T.write(' children:\n %s\n ' % c) + children_not_visited = [] + children_pending = set() + children_not_ready = [] + children_failed = False - childstate = map(lambda N: (N, N.get_state()), children) + for child in chain(children,node.prerequisites): + childstate = child.get_state() + + if T: T.write(self.trace_message(' ' + self.trace_node(child))) + + if childstate == NODE_NO_STATE: + children_not_visited.append(child) + elif childstate == NODE_PENDING: + children_pending.add(child) + elif childstate == NODE_FAILED: + children_failed = True + + if childstate <= NODE_EXECUTING: + children_not_ready.append(child) + + + # These nodes have not even been visited yet. Add + # them to the list so that on some next pass we can + # take a stab at evaluating them (or their children). + children_not_visited.reverse() + self.candidates.extend(self.order(children_not_visited)) + #if T and children_not_visited: + # T.write(self.trace_message(' adding to candidates: %s' % map(str, children_not_visited))) + # T.write(self.trace_message(' candidates now: %s\n' % map(str, self.candidates))) + + # Skip this node if any of its children have failed. + # + # This catches the case where we're descending a top-level + # target and one of our children failed while trying to be + # built by a *previous* descent of an earlier top-level + # target. + # + # It can also occur if a node is reused in multiple + # targets. One first descends though the one of the + # target, the next time occurs through the other target. + # + # Note that we can only have failed_children if the + # --keep-going flag was used, because without it the build + # will stop before diving in the other branch. + # + # Note that even if one of the children fails, we still + # added the other children to the list of candidate nodes + # to keep on building (--keep-going). + if children_failed: + node.set_state(NODE_FAILED) - # Skip this node if any of its children have failed. This - # catches the case where we're descending a top-level target - # and one of our children failed while trying to be built - # by a *previous* descent of an earlier top-level target. - failed_children = filter(lambda I: I[1] == SCons.Node.failed, - childstate) - if failed_children: - node.set_state(SCons.Node.failed) if S: S.child_failed = S.child_failed + 1 - if T: - c = map(str, failed_children) - c.sort() - T.write(' children failed:\n %s\n' % c) + if T: T.write(self.trace_message('****** %s\n' % self.trace_node(node))) continue - # Detect dependency cycles: - pending_nodes = filter(lambda I: I[1] == SCons.Node.pending, childstate) - if pending_nodes: - for p in pending_nodes: - cycle = find_cycle([p[0], node]) - if cycle: - desc = "Dependency cycle: " + string.join(map(str, cycle), " -> ") - if T: T.write(' dependency cycle\n') - raise SCons.Errors.UserError, desc + if children_not_ready: + for child in children_not_ready: + # We're waiting on one or more derived targets + # that have not yet finished building. + if S: S.not_built = S.not_built + 1 - not_built = filter(lambda I: I[1] <= SCons.Node.executing, childstate) - if not_built: - # We're waiting on one or more derived targets that have - # not yet finished building. + # Add this node to the waiting parents lists of + # anything we're waiting on, with a reference + # count so we can be put back on the list for + # re-evaluation when they've all finished. + node.ref_count = node.ref_count + child.add_to_waiting_parents(node) + if T: T.write(self.trace_message(' adjusted ref count: %s, child %s' % + (self.trace_node(node), repr(str(child))))) - not_visited = filter(lambda I: not I[1], not_built) - if not_visited: - # Some of them haven't even been visited yet. - # Add them to the list so that on some next pass - # we can take a stab at evaluating them (or - # their children). - not_visited = map(lambda I: I[0], not_visited) - not_visited.reverse() - self.candidates.extend(self.order(not_visited)) - - n_b_nodes = map(lambda I: I[0], not_built) - - # Add this node to the waiting parents lists of anything - # we're waiting on, with a reference count so we can be - # put back on the list for re-evaluation when they've - # all finished. - map(lambda n, P=node: n.add_to_waiting_parents(P), n_b_nodes) - node.ref_count = len(set(n_b_nodes)) - - if S: S.not_built = S.not_built + 1 if T: - c = map(str, n_b_nodes) - c.sort() - T.write(' waiting on unfinished children:\n %s\n' % c) + for pc in children_pending: + T.write(self.trace_message(' adding %s to the pending children set\n' % + self.trace_node(pc))) + self.pending_children = self.pending_children | children_pending + continue # Skip this node if it has side-effects that are # currently being built: - side_effects = filter(lambda N: - N.get_state() == SCons.Node.executing, - node.side_effects) - if side_effects: - map(lambda n, P=node: n.add_to_waiting_s_e(P), side_effects) + wait_side_effects = False + for se in node.side_effects: + if se.get_state() == NODE_EXECUTING: + se.add_to_waiting_s_e(node) + wait_side_effects = True + + if wait_side_effects: if S: S.side_effects = S.side_effects + 1 - if T: - c = map(str, side_effects) - c.sort() - T.write(' waiting on side effects:\n %s\n' % c) continue # The default when we've gotten through all of the checks above: # this node is ready to be built. if S: S.build = S.build + 1 - if T: T.write(' evaluating %s\n' % node) + if T: T.write(self.trace_message('Evaluating %s\n' % + self.trace_node(node))) + + # For debugging only: + # + # try: + # self._validate_pending_children() + # except: + # self.ready_exc = sys.exc_info() + # return node + return node return None @@ -657,11 +878,9 @@ class Taskmaster: task = self.tasker(self, tlist, node in self.original_top, node) try: task.make_ready() - except KeyboardInterrupt: - raise except: # We had a problem just trying to get this task ready (like - # a child couldn't be linked in to a BuildDir when deciding + # a child couldn't be linked in to a VariantDir when deciding # whether this node is current). Arrange to raise the # exception when the Task is "executed." self.ready_exc = sys.exc_info() @@ -673,8 +892,94 @@ class Taskmaster: return task + def will_not_build(self, nodes, node_func=lambda n: None): + """ + Perform clean-up about nodes that will never be built. Invokes + a user defined function on all of these nodes (including all + of their parents). + """ + + T = self.trace + + pending_children = self.pending_children + + to_visit = set(nodes) + pending_children = pending_children - to_visit + + if T: + for n in nodes: + T.write(self.trace_message(' removing node %s from the pending children set\n' % + self.trace_node(n))) + try: + while 1: + try: + node = to_visit.pop() + except AttributeError: + # Python 1.5.2 + if len(to_visit): + node = to_visit[0] + to_visit.remove(node) + else: + break + + node_func(node) + + # Prune recursion by flushing the waiting children + # list immediately. + parents = node.waiting_parents + node.waiting_parents = set() + + to_visit = to_visit | parents + pending_children = pending_children - parents + + for p in parents: + p.ref_count = p.ref_count - 1 + if T: T.write(self.trace_message(' removing parent %s from the pending children set\n' % + self.trace_node(p))) + except KeyError: + # The container to_visit has been emptied. + pass + + # We have the stick back the pending_children list into the + # task master because the python 1.5.2 compatibility does not + # allow us to use in-place updates + self.pending_children = pending_children + def stop(self): """ Stops the current build completely. """ self.next_candidate = self.no_next_candidate + + def cleanup(self): + """ + Check for dependency cycles. + """ + if not self.pending_children: + return + + # TODO(1.5) + #nclist = [ (n, find_cycle([n], set())) for n in self.pending_children ] + nclist = map(lambda n: (n, find_cycle([n], set())), self.pending_children) + + # TODO(1.5) + #genuine_cycles = [ + # node for node, cycle in nclist + # if cycle or node.get_state() != NODE_EXECUTED + #] + genuine_cycles = filter(lambda t: t[1] or t[0].get_state() != NODE_EXECUTED, nclist) + if not genuine_cycles: + # All of the "cycles" found were single nodes in EXECUTED state, + # which is to say, they really weren't cycles. Just return. + return + + desc = 'Found dependency cycle(s):\n' + for node, cycle in nclist: + if cycle: + desc = desc + " " + string.join(map(str, cycle), " -> ") + "\n" + else: + desc = desc + \ + " Internal Error: no cycle found for node %s (%s) in state %s\n" % \ + (node, repr(node), StateString[node.get_state()]) + + raise SCons.Errors.UserError, desc diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/386asm.py b/scons/scons-local-1.2.0/SCons/Tool/386asm.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/386asm.py rename to scons/scons-local-1.2.0/SCons/Tool/386asm.py index 6a0bd4da3..fc5c50004 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/386asm.py +++ b/scons/scons-local-1.2.0/SCons/Tool/386asm.py @@ -10,7 +10,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -32,7 +32,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/386asm.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/386asm.py 3842 2008/12/20 22:59:52 scons" from SCons.Tool.PharLapCommon import addPharLapPaths import SCons.Util diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/BitKeeper.py b/scons/scons-local-1.2.0/SCons/Tool/BitKeeper.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/BitKeeper.py rename to scons/scons-local-1.2.0/SCons/Tool/BitKeeper.py index 46dcc0051..15d1f0ad3 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/BitKeeper.py +++ b/scons/scons-local-1.2.0/SCons/Tool/BitKeeper.py @@ -10,7 +10,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -32,7 +32,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/BitKeeper.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/BitKeeper.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Builder diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/CVS.py b/scons/scons-local-1.2.0/SCons/Tool/CVS.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/CVS.py rename to scons/scons-local-1.2.0/SCons/Tool/CVS.py index 519a6f590..e1cc04d1e 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/CVS.py +++ b/scons/scons-local-1.2.0/SCons/Tool/CVS.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/CVS.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/CVS.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Builder diff --git a/scons/scons-local-1.2.0/SCons/Tool/FortranCommon.py b/scons/scons-local-1.2.0/SCons/Tool/FortranCommon.py new file mode 100644 index 000000000..8d3204ff1 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Tool/FortranCommon.py @@ -0,0 +1,241 @@ +"""SCons.Tool.FortranCommon + +Stuff for processing Fortran, common to all fortran dialects. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/FortranCommon.py 3842 2008/12/20 22:59:52 scons" + +import re +import string +import os.path + +import SCons.Action +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util + +def isfortran(env, source): + """Return 1 if any of code in source has fortran files in it, 0 + otherwise.""" + try: + fsuffixes = env['FORTRANSUFFIXES'] + except KeyError: + # If no FORTRANSUFFIXES, no fortran tool, so there is no need to look + # for fortran sources. + return 0 + + if not source: + # Source might be None for unusual cases like SConf. + return 0 + for s in source: + if s.sources: + ext = os.path.splitext(str(s.sources[0]))[1] + if ext in fsuffixes: + return 1 + return 0 + +def _fortranEmitter(target, source, env): + node = source[0].rfile() + if not node.exists() and not node.is_derived(): + print "Could not locate " + str(node.name) + return ([], []) + mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)""" + cre = re.compile(mod_regex,re.M) + # Retrieve all USE'd module names + modules = cre.findall(node.get_contents()) + # Remove unique items from the list + modules = SCons.Util.unique(modules) + # Convert module name to a .mod filename + suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source) + moddir = env.subst('$FORTRANMODDIR', target=target, source=source) + modules = map(lambda x, s=suffix: string.lower(x) + s, modules) + for m in modules: + target.append(env.fs.File(m, moddir)) + return (target, source) + +def FortranEmitter(target, source, env): + target, source = _fortranEmitter(target, source, env) + return SCons.Defaults.StaticObjectEmitter(target, source, env) + +def ShFortranEmitter(target, source, env): + target, source = _fortranEmitter(target, source, env) + return SCons.Defaults.SharedObjectEmitter(target, source, env) + +def ComputeFortranSuffixes(suffixes, ppsuffixes): + """suffixes are fortran source files, and ppsuffixes the ones to be + pre-processed. Both should be sequences, not strings.""" + assert len(suffixes) > 0 + s = suffixes[0] + sup = string.upper(s) + upper_suffixes = map(string.upper, suffixes) + if SCons.Util.case_sensitive_suffixes(s, sup): + ppsuffixes.extend(upper_suffixes) + else: + suffixes.extend(upper_suffixes) + +def CreateDialectActions(dialect): + """Create dialect specific actions.""" + CompAction = SCons.Action.Action('$%sCOM ' % dialect, '$%sCOMSTR' % dialect) + CompPPAction = SCons.Action.Action('$%sPPCOM ' % dialect, '$%sPPCOMSTR' % dialect) + ShCompAction = SCons.Action.Action('$SH%sCOM ' % dialect, '$SH%sCOMSTR' % dialect) + ShCompPPAction = SCons.Action.Action('$SH%sPPCOM ' % dialect, '$SH%sPPCOMSTR' % dialect) + + return CompAction, CompPPAction, ShCompAction, ShCompPPAction + +def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module = 0): + """Add dialect specific construction variables.""" + ComputeFortranSuffixes(suffixes, ppsuffixes) + + fscan = SCons.Scanner.Fortran.FortranScan("%sPATH" % dialect) + + for suffix in suffixes + ppsuffixes: + SCons.Tool.SourceFileScanner.add_scanner(suffix, fscan) + + env.AppendUnique(FORTRANSUFFIXES = suffixes + ppsuffixes) + + compaction, compppaction, shcompaction, shcompppaction = \ + CreateDialectActions(dialect) + + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in suffixes: + static_obj.add_action(suffix, compaction) + shared_obj.add_action(suffix, shcompaction) + static_obj.add_emitter(suffix, FortranEmitter) + shared_obj.add_emitter(suffix, ShFortranEmitter) + + for suffix in ppsuffixes: + static_obj.add_action(suffix, compppaction) + shared_obj.add_action(suffix, shcompppaction) + static_obj.add_emitter(suffix, FortranEmitter) + shared_obj.add_emitter(suffix, ShFortranEmitter) + + if not env.has_key('%sFLAGS' % dialect): + env['%sFLAGS' % dialect] = SCons.Util.CLVar('') + + if not env.has_key('SH%sFLAGS' % dialect): + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect) + + # If a tool does not define fortran prefix/suffix for include path, use C ones + if not env.has_key('INC%sPREFIX' % dialect): + env['INC%sPREFIX' % dialect] = '$INCPREFIX' + + if not env.has_key('INC%sSUFFIX' % dialect): + env['INC%sSUFFIX' % dialect] = '$INCSUFFIX' + + env['_%sINCFLAGS' % dialect] = '$( ${_concat(INC%sPREFIX, %sPATH, INC%sSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' % (dialect, dialect, dialect) + + if support_module == 1: + env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + else: + env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + +def add_fortran_to_env(env): + """Add Builders and construction variables for Fortran to an Environment.""" + try: + FortranSuffixes = env['FORTRANFILESUFFIXES'] + except KeyError: + FortranSuffixes = ['.f', '.for', '.ftn'] + + #print "Adding %s to fortran suffixes" % FortranSuffixes + try: + FortranPPSuffixes = env['FORTRANPPFILESUFFIXES'] + except KeyError: + FortranPPSuffixes = ['.fpp', '.FPP'] + + DialectAddToEnv(env, "FORTRAN", FortranSuffixes, + FortranPPSuffixes, support_module = 1) + + env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX + env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX + + env['FORTRANMODDIR'] = '' # where the compiler should place .mod files + env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX + env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX + env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + +def add_f77_to_env(env): + """Add Builders and construction variables for f77 to an Environment.""" + try: + F77Suffixes = env['F77FILESUFFIXES'] + except KeyError: + F77Suffixes = ['.f77'] + + #print "Adding %s to f77 suffixes" % F77Suffixes + try: + F77PPSuffixes = env['F77PPFILESUFFIXES'] + except KeyError: + F77PPSuffixes = [] + + DialectAddToEnv(env, "F77", F77Suffixes, F77PPSuffixes) + +def add_f90_to_env(env): + """Add Builders and construction variables for f90 to an Environment.""" + try: + F90Suffixes = env['F90FILESUFFIXES'] + except KeyError: + F90Suffixes = ['.f90'] + + #print "Adding %s to f90 suffixes" % F90Suffixes + try: + F90PPSuffixes = env['F90PPFILESUFFIXES'] + except KeyError: + F90PPSuffixes = [] + + DialectAddToEnv(env, "F90", F90Suffixes, F90PPSuffixes, + support_module = 1) + +def add_f95_to_env(env): + """Add Builders and construction variables for f95 to an Environment.""" + try: + F95Suffixes = env['F95FILESUFFIXES'] + except KeyError: + F95Suffixes = ['.f95'] + + #print "Adding %s to f95 suffixes" % F95Suffixes + try: + F95PPSuffixes = env['F95PPFILESUFFIXES'] + except KeyError: + F95PPSuffixes = [] + + DialectAddToEnv(env, "F95", F95Suffixes, F95PPSuffixes, + support_module = 1) + +def add_all_to_env(env): + """Add builders and construction variables for all supported fortran + dialects.""" + add_fortran_to_env(env) + add_f77_to_env(env) + add_f90_to_env(env) + add_f95_to_env(env) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/JavaCommon.py b/scons/scons-local-1.2.0/SCons/Tool/JavaCommon.py similarity index 89% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/JavaCommon.py rename to scons/scons-local-1.2.0/SCons/Tool/JavaCommon.py index 2aedd8559..12c31f37f 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/JavaCommon.py +++ b/scons/scons-local-1.2.0/SCons/Tool/JavaCommon.py @@ -5,7 +5,7 @@ Stuff for processing Java. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ Stuff for processing Java. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/JavaCommon.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/JavaCommon.py 3842 2008/12/20 22:59:52 scons" import os import os.path @@ -49,14 +49,16 @@ if java_parsing: # double-backslashes; # a single-line comment "//"; # single or double quotes preceeded by a backslash; - # single quotes, double quotes, open or close braces, semi-colons; + # single quotes, double quotes, open or close braces, semi-colons, + # periods, open or close parentheses; + # floating-point numbers; # any alphanumeric token (keyword, class name, specifier); + # any alphanumeric token surrounded by angle brackets (generics); # the multi-line comment begin and end tokens /* and */; - # array declarations "[]"; - # semi-colons; - # periods. + # array declarations "[]". _reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' + - r'[A-Za-z_][\w\$\.]*|/\*|\*/|\[\])') + r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' + + r'/\*|\*/|\[\])') class OuterState: """The initial state for parsing a Java file for classes, @@ -73,6 +75,7 @@ if java_parsing: self.stackBrackets = [] self.brackets = 0 self.nextAnon = 1 + self.localClasses = [] self.stackAnonClassBrackets = [] self.anonStacksStack = [[0]] self.package = None @@ -124,6 +127,7 @@ if java_parsing: if len(self.stackBrackets) and \ self.brackets == self.stackBrackets[-1]: self.listOutputs.append(string.join(self.listClasses, '$')) + self.localClasses.pop() self.listClasses.pop() self.anonStacksStack.pop() self.stackBrackets.pop() @@ -199,6 +203,8 @@ if java_parsing: return IgnoreState('*/', self) elif token == '\n': return self + elif token[0] == '<' and token[-1] == '>': + return self elif token == '(': self.brace_level = self.brace_level + 1 return self @@ -236,6 +242,20 @@ if java_parsing: # the next non-whitespace token should be the name of the class if token == '\n': return self + # If that's an inner class which is declared in a method, it + # requires an index prepended to the class-name, e.g. + # 'Foo$1Inner' (Tigris Issue 2087) + if self.outer_state.localClasses and \ + self.outer_state.stackBrackets[-1] > \ + self.outer_state.stackBrackets[-2]+1: + locals = self.outer_state.localClasses[-1] + try: + idx = locals[token] + locals[token] = locals[token]+1 + except KeyError: + locals[token] = 1 + token = str(locals[token]) + token + self.outer_state.localClasses.append({}) self.outer_state.listClasses.append(token) self.outer_state.anonStacksStack.append([0]) return self.outer_state diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/Perforce.py b/scons/scons-local-1.2.0/SCons/Tool/Perforce.py similarity index 95% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/Perforce.py rename to scons/scons-local-1.2.0/SCons/Tool/Perforce.py index 6a06f752e..97049f646 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/Perforce.py +++ b/scons/scons-local-1.2.0/SCons/Tool/Perforce.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/Perforce.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/Perforce.py 3842 2008/12/20 22:59:52 scons" import os diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/PharLapCommon.py b/scons/scons-local-1.2.0/SCons/Tool/PharLapCommon.py similarity index 96% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/PharLapCommon.py rename to scons/scons-local-1.2.0/SCons/Tool/PharLapCommon.py index d50446c69..76a566ab8 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/PharLapCommon.py +++ b/scons/scons-local-1.2.0/SCons/Tool/PharLapCommon.py @@ -7,7 +7,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,7 +29,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 3842 2008/12/20 22:59:52 scons" import os import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/RCS.py b/scons/scons-local-1.2.0/SCons/Tool/RCS.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/RCS.py rename to scons/scons-local-1.2.0/SCons/Tool/RCS.py index 73b8346c1..6d4706048 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/RCS.py +++ b/scons/scons-local-1.2.0/SCons/Tool/RCS.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/RCS.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/RCS.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Builder diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/SCCS.py b/scons/scons-local-1.2.0/SCons/Tool/SCCS.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/SCCS.py rename to scons/scons-local-1.2.0/SCons/Tool/SCCS.py index 16564e98f..842db137f 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/SCCS.py +++ b/scons/scons-local-1.2.0/SCons/Tool/SCCS.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/SCCS.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/SCCS.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Builder diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/Subversion.py b/scons/scons-local-1.2.0/SCons/Tool/Subversion.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/Subversion.py rename to scons/scons-local-1.2.0/SCons/Tool/Subversion.py index c8e8cf530..a593c6abe 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/Subversion.py +++ b/scons/scons-local-1.2.0/SCons/Tool/Subversion.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/Subversion.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/Subversion.py 3842 2008/12/20 22:59:52 scons" import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/__init__.py b/scons/scons-local-1.2.0/SCons/Tool/__init__.py similarity index 84% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/__init__.py rename to scons/scons-local-1.2.0/SCons/Tool/__init__.py index 17b7fd2d9..0b032820b 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/__init__.py +++ b/scons/scons-local-1.2.0/SCons/Tool/__init__.py @@ -14,7 +14,7 @@ tool definition. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -36,7 +36,7 @@ tool definition. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/__init__.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/__init__.py 3842 2008/12/20 22:59:52 scons" import imp import sys @@ -55,6 +55,7 @@ DefaultToolpath=[] CScanner = SCons.Scanner.C.CScanner() DScanner = SCons.Scanner.D.DScanner() LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner() +PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner() ProgramScanner = SCons.Scanner.Prog.ProgramScanner() SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner') @@ -76,8 +77,13 @@ for suffix in CSuffixes: for suffix in DSuffixes: SourceFileScanner.add_scanner(suffix, DScanner) +# FIXME: what should be done here? Two scanners scan the same extensions, +# but look for different files, e.g., "picture.eps" vs. "picture.pdf". +# The builders for DVI and PDF explicitly reference their scanners +# I think that means this is not needed??? for suffix in LaTeXSuffixes: - SourceFileScanner.add_scanner(suffix, LaTeXScanner) + SourceFileScanner.add_scanner(suffix, LaTeXScanner) + SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner) class Tool: def __init__(self, name, toolpath=[], **kw): @@ -136,7 +142,7 @@ class Tool: file.close() return module except ImportError, e: - if e!="No module named %s"%self.name: + if str(e)!="No module named %s"%self.name: raise SCons.Errors.EnvironmentError, e try: import zipimport @@ -163,10 +169,10 @@ class Tool: kw = self.init_kw env.Append(TOOLS = [ self.name ]) if hasattr(self, 'options'): - from SCons.Options import Options + import SCons.Variables if not env.has_key('options'): from SCons.Script import ARGUMENTS - env['options']=Options(args=ARGUMENTS) + env['options']=SCons.Variables.Variables(args=ARGUMENTS) opts=env['options'] self.options(opts) @@ -422,32 +428,33 @@ def CreateJavaFileBuilder(env): env['JAVASUFFIX'] = '.java' return java_file -class ToolInitializer: +class ToolInitializerMethod: """ - A class for delayed initialization of Tools modules. - - This is intended to be added to a construction environment in - place of the method(s) normally called for a Builder (env.Object, - env.StaticObject, etc.). When called, it searches the specified - list of tools, applies the first one that exists to the construction - environment, and calls whatever builder was (presumably) added the - construction environment in our place. + This is added to a construction environment in place of a + method(s) normally called for a Builder (env.Object, env.StaticObject, + etc.). When called, it has its associated ToolInitializer + object search the specified list of tools and apply the first + one that exists to the construction environment. It then calls + whatever builder was (presumably) added to the construction + environment in place of this particular instance. """ - def __init__(self, name, tools): + def __init__(self, name, initializer): """ Note: we store the tool name as __name__ so it can be used by the class that attaches this to a construction environment. """ self.__name__ = name - if not SCons.Util.is_List(tools): - tools = [tools] - self.tools = tools - def __call__(self, env, *args, **kw): - for t in self.tools: - tool = SCons.Tool.Tool(t) - if tool.exists(env): - env.Tool(tool) - break + self.initializer = initializer + + def get_builder(self, env): + """ + Returns the appropriate real Builder for this method name + after having the associated ToolInitializer object apply + the appropriate Tool module. + """ + builder = getattr(env, self.__name__) + + self.initializer.apply_tools(env) builder = getattr(env, self.__name__) if builder is self: @@ -455,21 +462,79 @@ class ToolInitializer: # for this name was found (or possibly there's a mismatch # between the name we were called by and the Builder name # added by the Tool module). - # - # (Eventually this is where we'll put a more informative - # error message about the inability to find that tool - # as cut over more Builders+Tools to using this. - return [], [] + return None - # Let the construction environment remove the added method - # so we no longer copy and re-bind this method when the - # construction environment gets cloned. - env.RemoveMethod(self) + self.initializer.remove_methods(env) + + return builder + + def __call__(self, env, *args, **kw): + """ + """ + builder = self.get_builder(env) + if builder is None: + return [], [] return apply(builder, args, kw) +class ToolInitializer: + """ + A class for delayed initialization of Tools modules. + + Instances of this class associate a list of Tool modules with + a list of Builder method names that will be added by those Tool + modules. As part of instantiating this object for a particular + construction environment, we also add the appropriate + ToolInitializerMethod objects for the various Builder methods + that we want to use to delay Tool searches until necessary. + """ + def __init__(self, env, tools, names): + if not SCons.Util.is_List(tools): + tools = [tools] + if not SCons.Util.is_List(names): + names = [names] + self.env = env + self.tools = tools + self.names = names + self.methods = {} + for name in names: + method = ToolInitializerMethod(name, self) + self.methods[name] = method + env.AddMethod(method) + + def remove_methods(self, env): + """ + Removes the methods that were added by the tool initialization + so we no longer copy and re-bind them when the construction + environment gets cloned. + """ + for method in self.methods.values(): + env.RemoveMethod(method) + + def apply_tools(self, env): + """ + Searches the list of associated Tool modules for one that + exists, and applies that to the construction environment. + """ + for t in self.tools: + tool = SCons.Tool.Tool(t) + if tool.exists(env): + env.Tool(tool) + return + + # If we fall through here, there was no tool module found. + # This is where we can put an informative error message + # about the inability to find the tool. We'll start doing + # this as we cut over more pre-defined Builder+Tools to use + # the ToolInitializer class. + def Initializers(env): - env.AddMethod(ToolInitializer('Install', 'install')) - env.AddMethod(ToolInitializer('InstallAs', 'install')) + ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs']) + def Install(self, *args, **kw): + return apply(self._InternalInstall, args, kw) + def InstallAs(self, *args, **kw): + return apply(self._InternalInstallAs, args, kw) + env.AddMethod(Install) + env.AddMethod(InstallAs) def FindTool(tools, env): for tool in tools: @@ -496,7 +561,7 @@ def tool_list(platform, env): c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ] cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ] assemblers = ['masm', 'nasm', 'gas', '386asm' ] - fortran_compilers = ['g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran'] + fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran'] ars = ['mslib', 'ar', 'tlib'] elif str(platform) == 'os2': "prefer IBM tools on OS/2" @@ -520,7 +585,8 @@ def tool_list(platform, env): c_compilers = ['suncc', 'gcc', 'cc'] cxx_compilers = ['sunc++', 'g++', 'c++'] assemblers = ['as', 'gas'] - fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran'] + fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77', + 'gfortran', 'g77', 'fortran'] ars = ['sunar'] elif str(platform) == 'hpux': "prefer aCC tools on HP-UX" @@ -544,7 +610,7 @@ def tool_list(platform, env): c_compilers = ['gcc', 'cc'] cxx_compilers = ['g++', 'c++'] assemblers = ['as'] - fortran_compilers = ['f95', 'f90', 'g77'] + fortran_compilers = ['gfortran', 'f95', 'f90', 'g77'] ars = ['ar'] else: "prefer GNU tools on all other platforms" @@ -552,7 +618,7 @@ def tool_list(platform, env): c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc'] cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++'] assemblers = ['gas', 'nasm', 'masm'] - fortran_compilers = ['f95', 'f90', 'g77', 'ifort', 'ifl', 'fortran'] + fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77'] ars = ['ar', 'mslib'] c_compiler = FindTool(c_compilers, env) or c_compilers[0] diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixc++.py b/scons/scons-local-1.2.0/SCons/Tool/aixc++.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/aixc++.py rename to scons/scons-local-1.2.0/SCons/Tool/aixc++.py index 380a9b951..5db91f768 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixc++.py +++ b/scons/scons-local-1.2.0/SCons/Tool/aixc++.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/aixc++.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/aixc++.py 3842 2008/12/20 22:59:52 scons" import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixcc.py b/scons/scons-local-1.2.0/SCons/Tool/aixcc.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/aixcc.py rename to scons/scons-local-1.2.0/SCons/Tool/aixcc.py index 2e43faf17..3c0b9d768 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixcc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/aixcc.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/aixcc.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/aixcc.py 3842 2008/12/20 22:59:52 scons" import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixf77.py b/scons/scons-local-1.2.0/SCons/Tool/aixf77.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/aixf77.py rename to scons/scons-local-1.2.0/SCons/Tool/aixf77.py index 4b3567725..794f7e220 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixf77.py +++ b/scons/scons-local-1.2.0/SCons/Tool/aixf77.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/aixf77.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/aixf77.py 3842 2008/12/20 22:59:52 scons" import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixlink.py b/scons/scons-local-1.2.0/SCons/Tool/aixlink.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/aixlink.py rename to scons/scons-local-1.2.0/SCons/Tool/aixlink.py index 858121cf7..3a1182a64 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/aixlink.py +++ b/scons/scons-local-1.2.0/SCons/Tool/aixlink.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/aixlink.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/aixlink.py 3842 2008/12/20 22:59:52 scons" import os import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/applelink.py b/scons/scons-local-1.2.0/SCons/Tool/applelink.py similarity index 84% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/applelink.py rename to scons/scons-local-1.2.0/SCons/Tool/applelink.py index a63fcdf3f..eb8df8caf 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/applelink.py +++ b/scons/scons-local-1.2.0/SCons/Tool/applelink.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,23 +31,25 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/applelink.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/applelink.py 3842 2008/12/20 22:59:52 scons" import SCons.Util -import gnulink +# Even though the Mac is based on the GNU toolchain, it doesn't understand +# the -rpath option, so we use the "link" tool instead of "gnulink". +import link def generate(env): """Add Builders and construction variables for applelink to an Environment.""" - gnulink.generate(env) + link.generate(env) env['FRAMEWORKPATHPREFIX'] = '-F' env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__)}' env['_FRAMEWORKS'] = '${_concat("-framework ", FRAMEWORKS, "", __env__)}' - env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS' + env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib') - env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS' + env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' # override the default for loadable modules, which are different # on OS X than dynamic shared libs. echoing what XCode does for @@ -60,5 +62,4 @@ def generate(env): def exists(env): - import sys - return sys.platform == 'darwin' + return env['PLATFORM'] == 'darwin' diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/ar.py b/scons/scons-local-1.2.0/SCons/Tool/ar.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/ar.py rename to scons/scons-local-1.2.0/SCons/Tool/ar.py index 65bec7fa7..7812fb3f2 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/ar.py +++ b/scons/scons-local-1.2.0/SCons/Tool/ar.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/ar.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/ar.py 3842 2008/12/20 22:59:52 scons" import SCons.Defaults import SCons.Tool diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/as.py b/scons/scons-local-1.2.0/SCons/Tool/as.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/as.py rename to scons/scons-local-1.2.0/SCons/Tool/as.py index 25fd5dbf1..623c8d75c 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/as.py +++ b/scons/scons-local-1.2.0/SCons/Tool/as.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/as.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/as.py 3842 2008/12/20 22:59:52 scons" import SCons.Defaults import SCons.Tool @@ -40,7 +40,7 @@ import SCons.Util assemblers = ['as'] ASSuffixes = ['.s', '.asm', '.ASM'] -ASPPSuffixes = ['.spp', '.SPP'] +ASPPSuffixes = ['.spp', '.SPP', '.sx'] if SCons.Util.case_sensitive_suffixes('.s', '.S'): ASPPSuffixes.extend(['.S']) else: diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/bcc32.py b/scons/scons-local-1.2.0/SCons/Tool/bcc32.py similarity index 94% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/bcc32.py rename to scons/scons-local-1.2.0/SCons/Tool/bcc32.py index 5a40c09a6..0488ba780 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/bcc32.py +++ b/scons/scons-local-1.2.0/SCons/Tool/bcc32.py @@ -5,7 +5,7 @@ XXX """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ XXX # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/bcc32.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/bcc32.py 3842 2008/12/20 22:59:52 scons" import os import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/c++.py b/scons/scons-local-1.2.0/SCons/Tool/c++.py similarity index 88% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/c++.py rename to scons/scons-local-1.2.0/SCons/Tool/c++.py index 6b9f0a92b..979814983 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/c++.py +++ b/scons/scons-local-1.2.0/SCons/Tool/c++.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/c++.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/c++.py 3842 2008/12/20 22:59:52 scons" import os.path @@ -71,13 +71,13 @@ def generate(env): shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) SCons.Tool.cc.add_common_cc_variables(env) - + env['CXX'] = 'c++' - env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $_CCCOMCOM $SOURCES' + env['CXXFLAGS'] = SCons.Util.CLVar('') + env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' env['SHCXX'] = '$CXX' env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - env['SHCXXCOM'] = '$SHCXX -o $TARGET -c $SHCXXFLAGS $_CCCOMCOM $SOURCES' + env['SHCXXCOM'] = '$SHCXX -o $TARGET -c $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES' env['CPPDEFPREFIX'] = '-D' env['CPPDEFSUFFIX'] = '' diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/cc.py b/scons/scons-local-1.2.0/SCons/Tool/cc.py similarity index 96% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/cc.py rename to scons/scons-local-1.2.0/SCons/Tool/cc.py index e4e87c7e5..ef1249d4c 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/cc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/cc.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/cc.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/cc.py 3842 2008/12/20 22:59:52 scons" import SCons.Tool import SCons.Defaults diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/cvf.py b/scons/scons-local-1.2.0/SCons/Tool/cvf.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/cvf.py rename to scons/scons-local-1.2.0/SCons/Tool/cvf.py index 689038ea1..203d9e414 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/cvf.py +++ b/scons/scons-local-1.2.0/SCons/Tool/cvf.py @@ -5,7 +5,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/cvf.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/cvf.py 3842 2008/12/20 22:59:52 scons" import fortran diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/default.py b/scons/scons-local-1.2.0/SCons/Tool/default.py similarity index 89% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/default.py rename to scons/scons-local-1.2.0/SCons/Tool/default.py index 182aa947d..a105f7f0c 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/default.py +++ b/scons/scons-local-1.2.0/SCons/Tool/default.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/default.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/default.py 3842 2008/12/20 22:59:52 scons" import SCons.Tool diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/dmd.py b/scons/scons-local-1.2.0/SCons/Tool/dmd.py similarity index 87% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/dmd.py rename to scons/scons-local-1.2.0/SCons/Tool/dmd.py index 8ef365189..88bff8abd 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/dmd.py +++ b/scons/scons-local-1.2.0/SCons/Tool/dmd.py @@ -14,14 +14,15 @@ use absolute paths. To hack around it, add '#/blah'. This will link blah.lib from the directory where SConstruct resides. Compiler variables: - DC - The name of the D compiler to use. Defaults to dmd. + DC - The name of the D compiler to use. Defaults to dmd or gdmd, + whichever is found. DPATH - List of paths to search for import modules. DVERSIONS - List of version tags to enable when compiling. DDEBUG - List of debug tags to enable when compiling. Linker related variables: LIBS - List of library files to link in. - DLINK - Name of the linker to use. Defaults to dmd. + DLINK - Name of the linker to use. Defaults to dmd or gdmd. DLINKFLAGS - List of linker flags. Lib tool variables: @@ -31,7 +32,7 @@ Lib tool variables: """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -53,7 +54,7 @@ Lib tool variables: # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/dmd.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/dmd.py 3842 2008/12/20 22:59:52 scons" import os import string @@ -93,7 +94,8 @@ def generate(env): static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) - env['DC'] = 'dmd' + dc = env.Detect(['dmd', 'gdmd']) + env['DC'] = dc env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES' env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)} $)' @@ -105,14 +107,15 @@ def generate(env): env['DVERSIONS'] = [] env['DDEBUG'] = [] - # Add the path to the standard library. - # This is merely for the convenience of the dependency scanner. - dmd_path = env.WhereIs('dmd') - if dmd_path: - x = string.rindex(dmd_path, 'dmd') - phobosDir = dmd_path[:x] + '/../src/phobos' - if os.path.isdir(phobosDir): - env.Append(DPATH = [phobosDir]) + if dc: + # Add the path to the standard library. + # This is merely for the convenience of the dependency scanner. + dmd_path = env.WhereIs(dc) + if dmd_path: + x = string.rindex(dmd_path, dc) + phobosDir = dmd_path[:x] + '/../src/phobos' + if os.path.isdir(phobosDir): + env.Append(DPATH = [phobosDir]) env['DINCPREFIX'] = '-I' env['DINCSUFFIX'] = '' @@ -191,14 +194,17 @@ def generate(env): env['SMART_LINKCOM'] = smart_link[linkcom] except KeyError: def _smartLink(source, target, env, for_signature, - defaultLinker=linkcom): + defaultLinker=linkcom, dc=dc): if isD(source): try: libs = env['LIBS'] except KeyError: libs = [] if 'phobos' not in libs: - env.Append(LIBS = ['phobos']) + if dc is 'dmd': + env.Append(LIBS = ['phobos']) + elif dc is 'gdmd': + env.Append(LIBS = ['gphobos']) if 'pthread' not in libs: env.Append(LIBS = ['pthread']) if 'm' not in libs: @@ -209,4 +215,4 @@ def generate(env): env['LINKCOM'] = '$SMART_LINKCOM ' def exists(env): - return env.Detect('dmd') + return env.Detect(['dmd', 'gdmd']) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/dvi.py b/scons/scons-local-1.2.0/SCons/Tool/dvi.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/dvi.py rename to scons/scons-local-1.2.0/SCons/Tool/dvi.py index a4eff52c0..af65671ea 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/dvi.py +++ b/scons/scons-local-1.2.0/SCons/Tool/dvi.py @@ -5,7 +5,7 @@ Common DVI Builder definition for various other Tool modules that use it. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ Common DVI Builder definition for various other Tool modules that use it. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/dvi.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/dvi.py 3842 2008/12/20 22:59:52 scons" import SCons.Builder import SCons.Tool diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/dvipdf.py b/scons/scons-local-1.2.0/SCons/Tool/dvipdf.py similarity index 62% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/dvipdf.py rename to scons/scons-local-1.2.0/SCons/Tool/dvipdf.py index eae34b0c7..821d125e6 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/dvipdf.py +++ b/scons/scons-local-1.2.0/SCons/Tool/dvipdf.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,14 +31,54 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/dvipdf.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/dvipdf.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Defaults import SCons.Tool.pdf +import SCons.Tool.tex import SCons.Util +_null = SCons.Scanner.LaTeX._null + +def DviPdfPsFunction(XXXDviAction, target = None, source= None, env=None): + """A builder for DVI files that sets the TEXPICTS environment + variable before running dvi2ps or dvipdf.""" + + try: + abspath = source[0].attributes.path + except AttributeError : + abspath = '' + + saved_env = SCons.Scanner.LaTeX.modify_env_var(env, 'TEXPICTS', abspath) + + result = XXXDviAction(target, source, env) + + if saved_env is _null: + try: + del env['ENV']['TEXPICTS'] + except KeyError: + pass # was never set + else: + env['ENV']['TEXPICTS'] = saved_env + + return result + +def DviPdfFunction(target = None, source= None, env=None): + result = DviPdfPsFunction(PDFAction,target,source,env) + return result + +def DviPdfStrFunction(target = None, source= None, env=None): + """A strfunction for dvipdf that returns the appropriate + command string for the no_exec options.""" + if env.GetOption("no_exec"): + result = env.subst('$DVIPDFCOM',0,target,source) + else: + result = '' + return result + PDFAction = None +DVIPDFAction = None def PDFEmitter(target, source, env): """Strips any .aux or .log files from the input source list. @@ -57,11 +97,15 @@ def generate(env): if PDFAction is None: PDFAction = SCons.Action.Action('$DVIPDFCOM', '$DVIPDFCOMSTR') + global DVIPDFAction + if DVIPDFAction is None: + DVIPDFAction = SCons.Action.Action(DviPdfFunction, strfunction = DviPdfStrFunction) + import pdf pdf.generate(env) bld = env['BUILDERS']['PDF'] - bld.add_action('.dvi', PDFAction) + bld.add_action('.dvi', DVIPDFAction) bld.add_emitter('.dvi', PDFEmitter) env['DVIPDF'] = 'dvipdf' diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/dvips.py b/scons/scons-local-1.2.0/SCons/Tool/dvips.py similarity index 71% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/dvips.py rename to scons/scons-local-1.2.0/SCons/Tool/dvips.py index 3d30f0cb7..db763f1d0 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/dvips.py +++ b/scons/scons-local-1.2.0/SCons/Tool/dvips.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,13 +31,28 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/dvips.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/dvips.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Builder +import SCons.Tool.dvipdf import SCons.Util +def DviPsFunction(target = None, source= None, env=None): + result = SCons.Tool.dvipdf.DviPdfPsFunction(PSAction,target,source,env) + return result + +def DviPsStrFunction(target = None, source= None, env=None): + """A strfunction for dvipdf that returns the appropriate + command string for the no_exec options.""" + if env.GetOption("no_exec"): + result = env.subst('$PSCOM',0,target,source) + else: + result = '' + return result + PSAction = None +DVIPSAction = None PSBuilder = None def generate(env): @@ -46,19 +61,24 @@ def generate(env): if PSAction is None: PSAction = SCons.Action.Action('$PSCOM', '$PSCOMSTR') + global DVIPSAction + if DVIPSAction is None: + DVIPSAction = SCons.Action.Action(DviPsFunction, strfunction = DviPsStrFunction) + global PSBuilder if PSBuilder is None: PSBuilder = SCons.Builder.Builder(action = PSAction, prefix = '$PSPREFIX', suffix = '$PSSUFFIX', src_suffix = '.dvi', - src_builder = 'DVI') + src_builder = 'DVI', + single_source=True) env['BUILDERS']['PostScript'] = PSBuilder env['DVIPS'] = 'dvips' env['DVIPSFLAGS'] = SCons.Util.CLVar('') - # I'm not quite sure I got the directories and filenames right for build_dir + # I'm not quite sure I got the directories and filenames right for variant_dir # We need to be in the correct directory for the sake of latex \includegraphics eps included files. env['PSCOM'] = 'cd ${TARGET.dir} && $DVIPS $DVIPSFLAGS -o ${TARGET.file} ${SOURCE.file}' env['PSPREFIX'] = '' diff --git a/scons/scons-local-1.2.0/SCons/Tool/f77.py b/scons/scons-local-1.2.0/SCons/Tool/f77.py new file mode 100644 index 000000000..21ab6d82d --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Tool/f77.py @@ -0,0 +1,56 @@ +"""engine.SCons.Tool.f77 + +Tool-specific initialization for the generic Posix f77 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/f77.py 3842 2008/12/20 22:59:52 scons" + +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env + +compilers = ['f77'] + +def generate(env): + add_all_to_env(env) + add_f77_to_env(env) + + fcomp = env.Detect(compilers) or 'f77' + env['F77'] = fcomp + env['SHF77'] = fcomp + + env['FORTRAN'] = fcomp + env['SHFORTRAN'] = fcomp + +def exists(env): + return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/g77.py b/scons/scons-local-1.2.0/SCons/Tool/f90.py similarity index 67% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/g77.py rename to scons/scons-local-1.2.0/SCons/Tool/f90.py index 5afcc5fe4..1078d2cca 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/g77.py +++ b/scons/scons-local-1.2.0/SCons/Tool/f90.py @@ -1,6 +1,6 @@ -"""engine.SCons.Tool.g77 +"""engine.SCons.Tool.f90 -Tool-specific initialization for g77. +Tool-specific initialization for the generic Posix f90 Fortran compiler. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,17 +31,26 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/g77.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/f90.py 3842 2008/12/20 22:59:52 scons" -import f77 +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_f90_to_env -compilers = ['g77', 'f77'] +compilers = ['f90'] def generate(env): - """Add Builders and construction variables for g77 to an Environment.""" - f77.generate(env) + add_all_to_env(env) + add_f90_to_env(env) - env['_FORTRAND'] = env.Detect(compilers) or 'g77' + fc = env.Detect(compilers) or 'f90' + env['F90'] = fc + env['SHF90'] = fc + + env['FORTRAN'] = fc + env['SHFORTRAN'] = fc def exists(env): return env.Detect(compilers) diff --git a/scons/scons-local-1.2.0/SCons/Tool/f95.py b/scons/scons-local-1.2.0/SCons/Tool/f95.py new file mode 100644 index 000000000..012930ca7 --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Tool/f95.py @@ -0,0 +1,57 @@ +"""engine.SCons.Tool.f95 + +Tool-specific initialization for the generic Posix f95 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/f95.py 3842 2008/12/20 22:59:52 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util +import fortran +from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env + +compilers = ['f95'] + +def generate(env): + add_all_to_env(env) + add_f95_to_env(env) + + fcomp = env.Detect(compilers) or 'f95' + env['F95'] = fcomp + env['SHF95'] = fcomp + + env['FORTRAN'] = fcomp + env['SHFORTRAN'] = fcomp + + +def exists(env): + return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/filesystem.py b/scons/scons-local-1.2.0/SCons/Tool/filesystem.py similarity index 94% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/filesystem.py rename to scons/scons-local-1.2.0/SCons/Tool/filesystem.py index ced41f86e..dbab56202 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/filesystem.py +++ b/scons/scons-local-1.2.0/SCons/Tool/filesystem.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/filesystem.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/filesystem.py 3842 2008/12/20 22:59:52 scons" import SCons from SCons.Tool.install import copyFunc diff --git a/scons/scons-local-1.2.0/SCons/Tool/fortran.py b/scons/scons-local-1.2.0/SCons/Tool/fortran.py new file mode 100644 index 000000000..aa53cf61b --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Tool/fortran.py @@ -0,0 +1,57 @@ +"""SCons.Tool.fortran + +Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/fortran.py 3842 2008/12/20 22:59:52 scons" + +import re +import string + +import SCons.Action +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_fortran_to_env + +compilers = ['f95', 'f90', 'f77'] + +def generate(env): + add_all_to_env(env) + add_fortran_to_env(env) + + fc = env.Detect(compilers) or 'f77' + env['SHFORTRAN'] = fc + env['FORTRAN'] = fc + +def exists(env): + return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/g++.py b/scons/scons-local-1.2.0/SCons/Tool/g++.py similarity index 67% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/g++.py rename to scons/scons-local-1.2.0/SCons/Tool/g++.py index e3519a142..feb39519e 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/g++.py +++ b/scons/scons-local-1.2.0/SCons/Tool/g++.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,12 +31,12 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/g++.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/g++.py 3842 2008/12/20 22:59:52 scons" import os.path import re +import subprocess -import SCons.Defaults import SCons.Tool import SCons.Util @@ -53,35 +53,32 @@ def generate(env): env['CXX'] = env.Detect(compilers) # platform specific settings - if env['PLATFORM'] == 'cygwin': - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - elif env['PLATFORM'] == 'aix': - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -DPIC -mminimal-toc') + if env['PLATFORM'] == 'aix': env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc') env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 env['SHOBJSUFFIX'] = '$OBJSUFFIX' elif env['PLATFORM'] == 'hpux': - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC -DPIC') - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC') env['SHOBJSUFFIX'] = '.pic.o' elif env['PLATFORM'] == 'sunos': - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC -DPIC') - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC') env['SHOBJSUFFIX'] = '.pic.o' - else: - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC -DPIC') - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC') # determine compiler version if env['CXX']: - line = os.popen(env['CXX'] + ' --version').readline() + #pipe = SCons.Action._subproc(env, [env['CXX'], '-dumpversion'], + pipe = SCons.Action._subproc(env, [env['CXX'], '--version'], + stdin = 'devnull', + stderr = 'devnull', + stdout = subprocess.PIPE) + if pipe.wait() != 0: return + # -dumpversion was added in GCC 3.0. As long as we're supporting + # GCC versions older than that, we should use --version and a + # regular expression. + #line = pipe.stdout.read().strip() + #if line: + # env['CXXVERSION'] = line + line = pipe.stdout.readline() match = re.search(r'[0-9]+(\.[0-9]+)+', line) if match: env['CXXVERSION'] = match.group(0) - def exists(env): return env.Detect(compilers) diff --git a/scons/scons-local-1.2.0/SCons/Tool/g77.py b/scons/scons-local-1.2.0/SCons/Tool/g77.py new file mode 100644 index 000000000..effc9fcfc --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Tool/g77.py @@ -0,0 +1,67 @@ +"""engine.SCons.Tool.g77 + +Tool-specific initialization for g77. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/g77.py 3842 2008/12/20 22:59:52 scons" + +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env + +compilers = ['g77', 'f77'] + +def generate(env): + """Add Builders and construction variables for g77 to an Environment.""" + add_all_to_env(env) + add_f77_to_env(env) + + fcomp = env.Detect(compilers) or 'g77' + if env['PLATFORM'] in ['cygwin', 'win32']: + env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS') + env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS') + else: + env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -fPIC') + env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS -fPIC') + + env['FORTRAN'] = fcomp + env['SHFORTRAN'] = '$FORTRAN' + + env['F77'] = fcomp + env['SHF77'] = '$F77' + + env['INCFORTRANPREFIX'] = "-I" + env['INCFORTRANSUFFIX'] = "" + + env['INCF77PREFIX'] = "-I" + env['INCF77SUFFIX'] = "" + +def exists(env): + return env.Detect(compilers) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/gas.py b/scons/scons-local-1.2.0/SCons/Tool/gas.py similarity index 90% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/gas.py rename to scons/scons-local-1.2.0/SCons/Tool/gas.py index e080c5e33..5595e9e13 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/gas.py +++ b/scons/scons-local-1.2.0/SCons/Tool/gas.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/gas.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/gas.py 3842 2008/12/20 22:59:52 scons" as_module = __import__('as', globals(), locals(), []) diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/gcc.py b/scons/scons-local-1.2.0/SCons/Tool/gcc.py similarity index 69% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/gcc.py rename to scons/scons-local-1.2.0/SCons/Tool/gcc.py index 81c137411..db07575b2 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/gcc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/gcc.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,13 +31,14 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/gcc.py 2523 2007/12/12 09:37:41 knight" - -import SCons.Util +__revision__ = "src/engine/SCons/Tool/gcc.py 3842 2008/12/20 22:59:52 scons" import cc import os import re +import subprocess + +import SCons.Util compilers = ['gcc', 'cc'] @@ -52,7 +53,19 @@ def generate(env): env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC') # determine compiler version if env['CC']: - line = os.popen(env['CC'] + ' --version').readline() + #pipe = SCons.Action._subproc(env, [env['CC'], '-dumpversion'], + pipe = SCons.Action._subproc(env, [env['CC'], '--version'], + stdin = 'devnull', + stderr = 'devnull', + stdout = subprocess.PIPE) + if pipe.wait() != 0: return + # -dumpversion was added in GCC 3.0. As long as we're supporting + # GCC versions older than that, we should use --version and a + # regular expression. + #line = pipe.stdout.read().strip() + #if line: + # env['CCVERSION'] = line + line = pipe.stdout.readline() match = re.search(r'[0-9]+(\.[0-9]+)+', line) if match: env['CCVERSION'] = match.group(0) diff --git a/scons/scons-local-1.2.0/SCons/Tool/gfortran.py b/scons/scons-local-1.2.0/SCons/Tool/gfortran.py new file mode 100644 index 000000000..7da19e4fd --- /dev/null +++ b/scons/scons-local-1.2.0/SCons/Tool/gfortran.py @@ -0,0 +1,58 @@ +"""SCons.Tool.gfortran + +Tool-specific initialization for gfortran, the GNU Fortran 95/Fortran +2003 compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/gfortran.py 3842 2008/12/20 22:59:52 scons" + +import SCons.Util + +import fortran + +def generate(env): + """Add Builders and construction variables for gfortran to an + Environment.""" + fortran.generate(env) + + for dialect in ['F77', 'F90', 'FORTRAN', 'F95']: + env['%s' % dialect] = 'gfortran' + env['SH%s' % dialect] = '$%s' % dialect + if env['PLATFORM'] in ['cygwin', 'win32']: + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect) + else: + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS -fPIC' % dialect) + + env['INC%sPREFIX' % dialect] = "-I" + env['INC%sSUFFIX' % dialect] = "" + +def exists(env): + return env.Detect('gfortran') diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/gnulink.py b/scons/scons-local-1.2.0/SCons/Tool/gnulink.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/gnulink.py rename to scons/scons-local-1.2.0/SCons/Tool/gnulink.py index 12d1a1728..de95ee1bb 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/gnulink.py +++ b/scons/scons-local-1.2.0/SCons/Tool/gnulink.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/gnulink.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/gnulink.py 3842 2008/12/20 22:59:52 scons" import SCons.Util diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/gs.py b/scons/scons-local-1.2.0/SCons/Tool/gs.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/gs.py rename to scons/scons-local-1.2.0/SCons/Tool/gs.py index 7e7325c32..c52440af6 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/gs.py +++ b/scons/scons-local-1.2.0/SCons/Tool/gs.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/gs.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/gs.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Platform diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/hpc++.py b/scons/scons-local-1.2.0/SCons/Tool/hpc++.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/hpc++.py rename to scons/scons-local-1.2.0/SCons/Tool/hpc++.py index 15eee3b3d..299c701ed 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/hpc++.py +++ b/scons/scons-local-1.2.0/SCons/Tool/hpc++.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/hpc++.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/hpc++.py 3842 2008/12/20 22:59:52 scons" import os.path import string diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/hpcc.py b/scons/scons-local-1.2.0/SCons/Tool/hpcc.py similarity index 90% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/hpcc.py rename to scons/scons-local-1.2.0/SCons/Tool/hpcc.py index 4b493e487..a4da9568b 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/hpcc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/hpcc.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/hpcc.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/hpcc.py 3842 2008/12/20 22:59:52 scons" import SCons.Util diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/hplink.py b/scons/scons-local-1.2.0/SCons/Tool/hplink.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/hplink.py rename to scons/scons-local-1.2.0/SCons/Tool/hplink.py index 5a4815549..0eb5b0a6b 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/hplink.py +++ b/scons/scons-local-1.2.0/SCons/Tool/hplink.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/hplink.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/hplink.py 3842 2008/12/20 22:59:52 scons" import os import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/icc.py b/scons/scons-local-1.2.0/SCons/Tool/icc.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/icc.py rename to scons/scons-local-1.2.0/SCons/Tool/icc.py index 5b1e1fd40..ac6d6aade 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/icc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/icc.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/icc.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/icc.py 3842 2008/12/20 22:59:52 scons" import cc diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/icl.py b/scons/scons-local-1.2.0/SCons/Tool/icl.py similarity index 91% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/icl.py rename to scons/scons-local-1.2.0/SCons/Tool/icl.py index 9ef0b120f..322de7935 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/icl.py +++ b/scons/scons-local-1.2.0/SCons/Tool/icl.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/icl.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/icl.py 3842 2008/12/20 22:59:52 scons" import SCons.Tool.intelc diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/ifl.py b/scons/scons-local-1.2.0/SCons/Tool/ifl.py similarity index 71% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/ifl.py rename to scons/scons-local-1.2.0/SCons/Tool/ifl.py index d180d7fa5..bfb157e6e 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/ifl.py +++ b/scons/scons-local-1.2.0/SCons/Tool/ifl.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,19 +31,32 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/ifl.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/ifl.py 3842 2008/12/20 22:59:52 scons" import SCons.Defaults - -import fortran +from SCons.Scanner.Fortran import FortranScan +from FortranCommon import add_all_to_env def generate(env): """Add Builders and construction variables for ifl to an Environment.""" - SCons.Tool.SourceFileScanner.add_scanner('.i90', fortran.FortranScan) - fortran.FortranSuffixes.extend(['.i90']) - fortran.generate(env) + fscan = FortranScan("FORTRANPATH") + SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) + SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan) + + if not env.has_key('FORTRANFILESUFFIXES'): + env['FORTRANFILESUFFIXES'] = ['.i'] + else: + env['FORTRANFILESUFFIXES'].append('.i') + + if not env.has_key('F90FILESUFFIXES'): + env['F90FILESUFFIXES'] = ['.i90'] + else: + env['F90FILESUFFIXES'].append('.i90') + + add_all_to_env(env) env['FORTRAN'] = 'ifl' + env['SHFORTRAN'] = '$FORTRAN' env['FORTRANCOM'] = '$FORTRAN $FORTRANFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' env['FORTRANPPCOM'] = '$FORTRAN $FORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' env['SHFORTRANCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/ifort.py b/scons/scons-local-1.2.0/SCons/Tool/ifort.py similarity index 57% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/ifort.py rename to scons/scons-local-1.2.0/SCons/Tool/ifort.py index d89855bb2..17b7bf7b3 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/ifort.py +++ b/scons/scons-local-1.2.0/SCons/Tool/ifort.py @@ -1,7 +1,7 @@ """SCons.Tool.ifort Tool-specific initialization for newer versions of the Intel Fortran Compiler -for Linux. +for Linux/Windows (and possibly Mac OS X). There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() @@ -10,7 +10,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -32,42 +32,52 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/ifort.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/ifort.py 3842 2008/12/20 22:59:52 scons" import string import SCons.Defaults - -import fortran +from SCons.Scanner.Fortran import FortranScan +from FortranCommon import add_all_to_env def generate(env): """Add Builders and construction variables for ifort to an Environment.""" # ifort supports Fortran 90 and Fortran 95 # Additionally, ifort recognizes more file extensions. - SCons.Tool.SourceFileScanner.add_scanner('.i', fortran.FortranScan) - SCons.Tool.SourceFileScanner.add_scanner('.i90', fortran.FortranScan) - fortran.FortranSuffixes.extend(['.i', '.i90']) - fortran.generate(env) + fscan = FortranScan("FORTRANPATH") + SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) + SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan) - env['_FORTRAND'] = 'ifort' + if not env.has_key('FORTRANFILESUFFIXES'): + env['FORTRANFILESUFFIXES'] = ['.i'] + else: + env['FORTRANFILESUFFIXES'].append('.i') - # If files are compiled into objects, the Intel Fortran Compiler must use - # ld to link shared libraries. - env['SHLINK'] = 'ld' + if not env.has_key('F90FILESUFFIXES'): + env['F90FILESUFFIXES'] = ['.i90'] + else: + env['F90FILESUFFIXES'].append('.i90') - # Additionally, no symbols can be defined in an archive file; to use - # Intel Fortran to create shared libraries, all external symbols must - # be in shared libraries. - env['SHLINKFLAGS'] = '-shared -no_archive' + add_all_to_env(env) + + fc = 'ifort' + + for dialect in ['F77', 'F90', 'FORTRAN', 'F95']: + env['%s' % dialect] = fc + env['SH%s' % dialect] = '$%s' % dialect + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS -fPIC' % dialect) - # if env['PLATFORM'] == 'win32': # On Windows, the ifort compiler specifies the object on the # command line with -object:, not -o. Massage the necessary # command-line construction variables. - for var in ['_FORTRANCOMD', '_FORTRANPPCOMD', - '_SHFORTRANCOMD', '_SHFORTRANPPCOMD']: - env[var] = string.replace(env[var], '-o $TARGET', '-object:$TARGET') + for dialect in ['F77', 'F90', 'FORTRAN', 'F95']: + for var in ['%sCOM' % dialect, '%sPPCOM' % dialect, + 'SH%sCOM' % dialect, 'SH%sPPCOM' % dialect]: + env[var] = string.replace(env[var], '-o $TARGET', '-object:$TARGET') + env['FORTRANMODDIRPREFIX'] = "/module:" + else: + env['FORTRANMODDIRPREFIX'] = "-module " def exists(env): return env.Detect('ifort') diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/ilink.py b/scons/scons-local-1.2.0/SCons/Tool/ilink.py similarity index 91% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/ilink.py rename to scons/scons-local-1.2.0/SCons/Tool/ilink.py index faf3ece79..b443a6b68 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/ilink.py +++ b/scons/scons-local-1.2.0/SCons/Tool/ilink.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/ilink.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/ilink.py 3842 2008/12/20 22:59:52 scons" import SCons.Defaults import SCons.Tool diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/ilink32.py b/scons/scons-local-1.2.0/SCons/Tool/ilink32.py similarity index 89% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/ilink32.py rename to scons/scons-local-1.2.0/SCons/Tool/ilink32.py index b2cfe4de8..f357bec67 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/ilink32.py +++ b/scons/scons-local-1.2.0/SCons/Tool/ilink32.py @@ -5,7 +5,7 @@ XXX """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ XXX # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/ilink32.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/ilink32.py 3842 2008/12/20 22:59:52 scons" import SCons.Tool import SCons.Tool.bcc32 @@ -36,6 +36,7 @@ import SCons.Util def generate(env): """Add Builders and construction variables for ilink to an Environment.""" + SCons.Tool.createSharedLibBuilder(env) SCons.Tool.createProgBuilder(env) env['LINK'] = '$CC' @@ -46,6 +47,7 @@ def generate(env): env['LIBLINKPREFIX']='' env['LIBLINKSUFFIX']='$LIBSUFFIX' + def exists(env): # Uses bcc32 to do linking as it generally knows where the standard # LIBS are and set up the linking correctly diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/install.py b/scons/scons-local-1.2.0/SCons/Tool/install.py similarity index 88% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/install.py rename to scons/scons-local-1.2.0/SCons/Tool/install.py index 1c7ff2e66..be36be08c 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/install.py +++ b/scons/scons-local-1.2.0/SCons/Tool/install.py @@ -8,7 +8,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +30,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/install.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/install.py 3842 2008/12/20 22:59:52 scons" import os import shutil @@ -75,7 +75,8 @@ def installFunc(target, source, env): except KeyError: raise SCons.Errors.UserError('Missing INSTALL construction variable.') - assert( len(target)==len(source) ) + assert len(target)==len(source), \ + "Installing source %s into target %s: target and source lists must have same length."%(map(str, source), map(str, target)) for t,s in zip(target,source): if install(t.get_path(),s.get_path(),env): return 1 @@ -131,8 +132,9 @@ installas_action = SCons.Action.Action(installFunc, stringFunc) BaseInstallBuilder = None -def InstallBuilderWrapper(env, target, source, dir=None): +def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw): if target and dir: + import SCons.Errors raise SCons.Errors.UserError, "Both target and dir defined for Install(), only one may be defined." if not dir: dir=target @@ -156,13 +158,15 @@ def InstallBuilderWrapper(env, target, source, dir=None): # '#' on the file name portion as meaning the Node should # be relative to the top-level SConstruct directory. target = env.fs.Entry('.'+os.sep+src.name, dnode) - tgt.extend(BaseInstallBuilder(env, target, src)) + #tgt.extend(BaseInstallBuilder(env, target, src, **kw)) + tgt.extend(apply(BaseInstallBuilder, (env, target, src), kw)) return tgt -def InstallAsBuilderWrapper(env, target, source): +def InstallAsBuilderWrapper(env, target=None, source=None, **kw): result = [] for src, tgt in map(lambda x, y: (x, y), source, target): - result.extend(BaseInstallBuilder(env, tgt, src)) + #result.extend(BaseInstallBuilder(env, tgt, src, **kw)) + result.extend(apply(BaseInstallBuilder, (env, tgt, src), kw)) return result added = None @@ -195,15 +199,8 @@ def generate(env): emitter = [ add_targets_to_INSTALLED_FILES, ], name = 'InstallBuilder') - try: - env['BUILDERS']['Install'] - except KeyError, e: - env['BUILDERS']['Install'] = InstallBuilderWrapper - - try: - env['BUILDERS']['InstallAs'] - except KeyError, e: - env['BUILDERS']['InstallAs'] = InstallAsBuilderWrapper + env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper + env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper # We'd like to initialize this doing something like the following, # but there isn't yet support for a ${SOURCE.type} expansion that diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/intelc.py b/scons/scons-local-1.2.0/SCons/Tool/intelc.py similarity index 83% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/intelc.py rename to scons/scons-local-1.2.0/SCons/Tool/intelc.py index 7ecd70b55..dfdedc4ab 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/intelc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/intelc.py @@ -10,7 +10,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -32,7 +32,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/intelc.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/intelc.py 3842 2008/12/20 22:59:52 scons" import math, sys, os.path, glob, string, re @@ -41,11 +41,14 @@ is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or (os.environ.has_key('PROCESSOR_ARCHITEW6432') and os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64')) is_linux = sys.platform == 'linux2' +is_mac = sys.platform == 'darwin' if is_windows: import SCons.Tool.msvc elif is_linux: import SCons.Tool.gcc +elif is_mac: + import SCons.Tool.gcc import SCons.Util import SCons.Warnings @@ -98,14 +101,19 @@ def check_abi(abi): valid_abis = {'ia32' : 'ia32', 'x86' : 'ia32', 'ia64' : 'ia64', - 'em64t' : 'ia32e', - 'amd64' : 'ia32e'} + 'em64t' : 'em64t', + 'amd64' : 'em64t'} if is_linux: valid_abis = {'ia32' : 'ia32', 'x86' : 'ia32', 'x86_64' : 'x86_64', 'em64t' : 'x86_64', 'amd64' : 'x86_64'} + if is_mac: + valid_abis = {'ia32' : 'ia32', + 'x86' : 'ia32', + 'x86_64' : 'x86_64', + 'em64t' : 'x86_64'} try: abi = valid_abis[abi] except KeyError: @@ -196,8 +204,22 @@ def get_all_compiler_versions(): if ok: versions.append(subkey) else: - # Registry points to nonexistent dir. Ignore this version. - print "Ignoring "+str(get_intel_registry_value('ProductDir', subkey, 'IA32')) + try: + # Registry points to nonexistent dir. Ignore this + # version. + value = get_intel_registry_value('ProductDir', subkey, 'IA32') + except MissingRegistryError, e: + + # Registry key is left dangling (potentially + # after uninstalling). + + print \ + "scons: *** Ignoring the registry key for the Intel compiler version %s.\n" \ + "scons: *** It seems that the compiler was uninstalled and that the registry\n" \ + "scons: *** was not cleaned up properly.\n" % subkey + else: + print "scons: *** Ignoring "+str(value) + i = i + 1 except EnvironmentError: # no more subkeys @@ -205,11 +227,22 @@ def get_all_compiler_versions(): elif is_linux: for d in glob.glob('/opt/intel_cc_*'): # Typical dir here is /opt/intel_cc_80. - versions.append(re.search(r'cc_(.*)$', d).group(1)) + m = re.search(r'cc_(.*)$', d) + if m: + versions.append(m.group(1)) for d in glob.glob('/opt/intel/cc*/*'): # Typical dir here is /opt/intel/cc/9.0 for IA32, # /opt/intel/cce/9.0 for EMT64 (AMD64) - versions.append(re.search(r'([0-9.]+)$', d).group(1)) + m = re.search(r'([0-9.]+)$', d) + if m: + versions.append(m.group(1)) + elif is_mac: + for d in glob.glob('/opt/intel/cc*/*'): + # Typical dir here is /opt/intel/cc/9.0 for IA32, + # /opt/intel/cce/9.0 for EMT64 (AMD64) + m = re.search(r'([0-9.]+)$', d) + if m: + versions.append(m.group(1)) versions = uniquify(versions) # remove dups versions.sort(vercmp) return versions @@ -229,7 +262,7 @@ def get_intel_compiler_top(version, abi): if not os.path.exists(os.path.join(top, "Bin", "icl.exe")): raise MissingDirError, \ "Can't find Intel compiler in %s"%(top) - elif is_linux: + elif is_mac or is_linux: # first dir is new (>=9.0) style, second is old (8.0) style. dirs=('/opt/intel/cc/%s', '/opt/intel_cc_%s') if abi == 'x86_64': @@ -256,7 +289,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): If topdir is used, version and abi are ignored. verbose: (int) if >0, prints compiler version used. """ - if not (is_linux or is_windows): + if not (is_mac or is_linux or is_windows): # can't handle this platform return @@ -264,6 +297,8 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): SCons.Tool.msvc.generate(env) elif is_linux: SCons.Tool.gcc.generate(env) + elif is_mac: + SCons.Tool.gcc.generate(env) # if version is unspecified, use latest vlist = get_all_compiler_versions() @@ -284,7 +319,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): # alternatives are ia64 for Itanium, or amd64 or em64t or x86_64 (all synonyms here) abi = check_abi(abi) if abi is None: - if is_linux: + if is_mac or is_linux: # Check if we are on 64-bit linux, default to 64 then. uname_m = os.uname()[4] if uname_m == 'x86_64': @@ -308,7 +343,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): # on $PATH and the user is importing their env. class ICLTopDirWarning(SCons.Warnings.Warning): pass - if is_linux and not env.Detect('icc') or \ + if (is_mac or is_linux) and not env.Detect('icc') or \ is_windows and not env.Detect('icl'): SCons.Warnings.enableWarningClass(ICLTopDirWarning) @@ -325,11 +360,14 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): if topdir: if verbose: - print "Intel C compiler: using version '%s' (%g), abi %s, in '%s'"%\ - (version, linux_ver_normalize(version),abi,topdir) + print "Intel C compiler: using version %s (%g), abi %s, in '%s'"%\ + (repr(version), linux_ver_normalize(version),abi,topdir) if is_linux: # Show the actual compiler version by running the compiler. os.system('%s/bin/icc --version'%topdir) + if is_mac: + # Show the actual compiler version by running the compiler. + os.system('%s/bin/icc --version'%topdir) env['INTEL_C_COMPILER_TOP'] = topdir if is_linux: @@ -337,13 +375,24 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): 'LIB' : 'lib', 'PATH' : 'bin', 'LD_LIBRARY_PATH' : 'lib'} - for p in paths: + for p in paths.keys(): + env.PrependENVPath(p, os.path.join(topdir, paths[p])) + if is_mac: + paths={'INCLUDE' : 'include', + 'LIB' : 'lib', + 'PATH' : 'bin', + 'LD_LIBRARY_PATH' : 'lib'} + for p in paths.keys(): env.PrependENVPath(p, os.path.join(topdir, paths[p])) if is_windows: # env key reg valname default subdir of top paths=(('INCLUDE', 'IncludeDir', 'Include'), ('LIB' , 'LibDir', 'Lib'), ('PATH' , 'BinDir', 'Bin')) + # We are supposed to ignore version if topdir is set, so set + # it to the emptry string if it's not already set. + if version is None: + version = '' # Each path has a registry entry, use that or default to subdir for p in paths: try: @@ -392,7 +441,9 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): licdir = None for ld in [envlicdir, reglicdir]: - if ld and os.path.exists(ld): + # If the string contains an '@', then assume it's a network + # license (port@system) and good by definition. + if ld and (string.find(ld, '@') != -1 or os.path.exists(ld)): licdir = ld break if not licdir: @@ -409,7 +460,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): env['ENV']['INTEL_LICENSE_FILE'] = licdir def exists(env): - if not (is_linux or is_windows): + if not (is_mac or is_linux or is_windows): # can't handle this platform return 0 @@ -424,6 +475,8 @@ def exists(env): return env.Detect('icl') elif is_linux: return env.Detect('icc') + elif is_mac: + return env.Detect('icc') return detected # end of file diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/jar.py b/scons/scons-local-1.2.0/SCons/Tool/jar.py similarity index 79% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/jar.py rename to scons/scons-local-1.2.0/SCons/Tool/jar.py index dd2d6f125..be50b016d 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/jar.py +++ b/scons/scons-local-1.2.0/SCons/Tool/jar.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,26 +31,39 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/jar.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/jar.py 3842 2008/12/20 22:59:52 scons" import SCons.Subst import SCons.Util def jarSources(target, source, env, for_signature): """Only include sources that are not a manifest file.""" - jarchdir = env.subst('$JARCHDIR', target=target, source=source) - if jarchdir: - jarchdir = env.fs.Dir(jarchdir) + try: + env['JARCHDIR'] + except KeyError: + jarchdir_set = False + else: + jarchdir_set = True + jarchdir = env.subst('$JARCHDIR', target=target, source=source) + if jarchdir: + jarchdir = env.fs.Dir(jarchdir) result = [] for src in source: contents = src.get_contents() if contents[:16] != "Manifest-Version": - if jarchdir: + if jarchdir_set: + _chdir = jarchdir + else: + try: + _chdir = src.attributes.java_classdir + except AttributeError: + _chdir = None + if _chdir: # If we are changing the dir with -C, then sources should # be relative to that directory. - src = SCons.Subst.Literal(src.get_path(jarchdir)) + src = SCons.Subst.Literal(src.get_path(_chdir)) result.append('-C') - result.append(jarchdir) + result.append(_chdir) result.append(src) return result diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/javac.py b/scons/scons-local-1.2.0/SCons/Tool/javac.py similarity index 96% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/javac.py rename to scons/scons-local-1.2.0/SCons/Tool/javac.py index 54bc94e85..b8cabe89b 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/javac.py +++ b/scons/scons-local-1.2.0/SCons/Tool/javac.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/javac.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/javac.py 3842 2008/12/20 22:59:52 scons" import os import os.path @@ -92,8 +92,9 @@ def emit_java_classes(target, source, env): raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % entry.__class__) version = env.get('JAVAVERSION', '1.4') - tlist = [] + full_tlist = [] for f in slist: + tlist = [] source_file_based = True pkg_dir = None if not f.is_derived(): @@ -124,7 +125,12 @@ def emit_java_classes(target, source, env): t.attributes.java_classname = classname(base) tlist.append(t) - return tlist, slist + for t in tlist: + t.set_specific_source([f]) + + full_tlist.extend(tlist) + + return full_tlist, slist JavaAction = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/javah.py b/scons/scons-local-1.2.0/SCons/Tool/javah.py similarity index 96% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/javah.py rename to scons/scons-local-1.2.0/SCons/Tool/javah.py index 195bfe068..3a39aebca 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/javah.py +++ b/scons/scons-local-1.2.0/SCons/Tool/javah.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/javah.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/javah.py 3842 2008/12/20 22:59:52 scons" import os.path import string diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/latex.py b/scons/scons-local-1.2.0/SCons/Tool/latex.py similarity index 76% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/latex.py rename to scons/scons-local-1.2.0/SCons/Tool/latex.py index 6dab15e11..549f6d374 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/latex.py +++ b/scons/scons-local-1.2.0/SCons/Tool/latex.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/latex.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/latex.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Defaults @@ -43,9 +43,11 @@ import SCons.Tool.tex LaTeXAction = None def LaTeXAuxFunction(target = None, source= None, env=None): - SCons.Tool.tex.InternalLaTeXAuxAction( LaTeXAction, target, source, env ) + result = SCons.Tool.tex.InternalLaTeXAuxAction( LaTeXAction, target, source, env ) + return result -LaTeXAuxAction = SCons.Action.Action(LaTeXAuxFunction, strfunction=None) +LaTeXAuxAction = SCons.Action.Action(LaTeXAuxFunction, + strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) def generate(env): """Add Builders and construction variables for LaTeX to an Environment.""" @@ -56,14 +58,17 @@ def generate(env): import dvi dvi.generate(env) + import pdf + pdf.generate(env) + bld = env['BUILDERS']['DVI'] bld.add_action('.ltx', LaTeXAuxAction) bld.add_action('.latex', LaTeXAuxAction) - bld.add_emitter('.ltx', SCons.Tool.tex.tex_emitter) - bld.add_emitter('.latex', SCons.Tool.tex.tex_emitter) + bld.add_emitter('.ltx', SCons.Tool.tex.tex_eps_emitter) + bld.add_emitter('.latex', SCons.Tool.tex.tex_eps_emitter) env['LATEX'] = 'latex' - env['LATEXFLAGS'] = SCons.Util.CLVar('') + env['LATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode') env['LATEXCOM'] = 'cd ${TARGET.dir} && $LATEX $LATEXFLAGS ${SOURCE.file}' env['LATEXRETRIES'] = 3 diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/lex.py b/scons/scons-local-1.2.0/SCons/Tool/lex.py similarity index 95% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/lex.py rename to scons/scons-local-1.2.0/SCons/Tool/lex.py index a710b6462..f2e0e856d 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/lex.py +++ b/scons/scons-local-1.2.0/SCons/Tool/lex.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/lex.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/lex.py 3842 2008/12/20 22:59:52 scons" import os.path diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/link.py b/scons/scons-local-1.2.0/SCons/Tool/link.py similarity index 72% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/link.py rename to scons/scons-local-1.2.0/SCons/Tool/link.py index 97c6713da..d02bb25fb 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/link.py +++ b/scons/scons-local-1.2.0/SCons/Tool/link.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,19 +31,43 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/link.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/link.py 3842 2008/12/20 22:59:52 scons" import SCons.Defaults import SCons.Tool import SCons.Util +import SCons.Warnings + +from SCons.Tool.FortranCommon import isfortran cplusplus = __import__('c++', globals(), locals(), []) +issued_mixed_link_warning = False + def smart_link(source, target, env, for_signature): - if cplusplus.iscplusplus(source): + has_cplusplus = cplusplus.iscplusplus(source) + has_fortran = isfortran(env, source) + if has_cplusplus and has_fortran: + global issued_mixed_link_warning + if not issued_mixed_link_warning: + msg = "Using $CXX to link Fortran and C++ code together.\n\t" + \ + "This may generate a buggy executable if the %s\n\t" + \ + "compiler does not know how to deal with Fortran runtimes." + SCons.Warnings.warn(SCons.Warnings.FortranCxxMixWarning, + msg % repr(env.subst('$CXX'))) + issued_mixed_link_warning = True + return '$CXX' + elif has_fortran: + return '$FORTRAN' + elif has_cplusplus: return '$CXX' return '$CC' +def shlib_emitter(target, source, env): + for tgt in target: + tgt.attributes.shared = 1 + return (target, source) + def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" SCons.Tool.createSharedLibBuilder(env) @@ -54,14 +78,14 @@ def generate(env): env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' # don't set up the emitter, cause AppendUnique will generate a list # starting with None :-( - #env['SHLIBEMITTER']= None + env.Append(SHLIBEMITTER = [shlib_emitter]) env['SMARTLINK'] = smart_link env['LINK'] = "$SMARTLINK" env['LINKFLAGS'] = SCons.Util.CLVar('') env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' env['LIBDIRPREFIX']='-L' env['LIBDIRSUFFIX']='' - env['_LIBFLAGS']='${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIX, LIBSUFFIX, __env__)}' + env['_LIBFLAGS']='${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}' env['LIBLINKPREFIX']='-l' env['LIBLINKSUFFIX']='' diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/linkloc.py b/scons/scons-local-1.2.0/SCons/Tool/linkloc.py similarity index 95% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/linkloc.py rename to scons/scons-local-1.2.0/SCons/Tool/linkloc.py index 33e9c5c6e..b0550c6e3 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/linkloc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/linkloc.py @@ -10,7 +10,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -32,7 +32,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/linkloc.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/linkloc.py 3842 2008/12/20 22:59:52 scons" import os.path import re diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/m4.py b/scons/scons-local-1.2.0/SCons/Tool/m4.py similarity index 92% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/m4.py rename to scons/scons-local-1.2.0/SCons/Tool/m4.py index fa9d50c5a..0d81d7146 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/m4.py +++ b/scons/scons-local-1.2.0/SCons/Tool/m4.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/m4.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/m4.py 3842 2008/12/20 22:59:52 scons" import SCons.Action import SCons.Builder diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/masm.py b/scons/scons-local-1.2.0/SCons/Tool/masm.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/masm.py rename to scons/scons-local-1.2.0/SCons/Tool/masm.py index 86f262c1a..850890087 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/masm.py +++ b/scons/scons-local-1.2.0/SCons/Tool/masm.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,14 +31,14 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/masm.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/masm.py 3842 2008/12/20 22:59:52 scons" import SCons.Defaults import SCons.Tool import SCons.Util ASSuffixes = ['.s', '.asm', '.ASM'] -ASPPSuffixes = ['.spp', '.SPP'] +ASPPSuffixes = ['.spp', '.SPP', '.sx'] if SCons.Util.case_sensitive_suffixes('.s', '.S'): ASPPSuffixes.extend(['.S']) else: diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/midl.py b/scons/scons-local-1.2.0/SCons/Tool/midl.py similarity index 94% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/midl.py rename to scons/scons-local-1.2.0/SCons/Tool/midl.py index 4ca6c1a66..df1bf9a5d 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/midl.py +++ b/scons/scons-local-1.2.0/SCons/Tool/midl.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/midl.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/midl.py 3842 2008/12/20 22:59:52 scons" import string diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/mingw.py b/scons/scons-local-1.2.0/SCons/Tool/mingw.py similarity index 96% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/mingw.py rename to scons/scons-local-1.2.0/SCons/Tool/mingw.py index 6dbf2ae92..faec2e9ed 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/mingw.py +++ b/scons/scons-local-1.2.0/SCons/Tool/mingw.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/mingw.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/mingw.py 3842 2008/12/20 22:59:52 scons" import os import os.path @@ -122,6 +122,7 @@ def generate(env): env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') env['SHLINKCOM'] = shlib_action + env['LDMODULECOM'] = shlib_action env.Append(SHLIBEMITTER = [shlib_emitter]) env['AS'] = 'as' diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/mslib.py b/scons/scons-local-1.2.0/SCons/Tool/mslib.py similarity index 94% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/mslib.py rename to scons/scons-local-1.2.0/SCons/Tool/mslib.py index 038130f4f..340f9927d 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/mslib.py +++ b/scons/scons-local-1.2.0/SCons/Tool/mslib.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/mslib.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/mslib.py 3842 2008/12/20 22:59:52 scons" import SCons.Defaults import SCons.Tool diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/mslink.py b/scons/scons-local-1.2.0/SCons/Tool/mslink.py similarity index 86% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/mslink.py rename to scons/scons-local-1.2.0/SCons/Tool/mslink.py index 487dad98c..298ae7c64 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/mslink.py +++ b/scons/scons-local-1.2.0/SCons/Tool/mslink.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/mslink.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/mslink.py 3842 2008/12/20 22:59:52 scons" import os.path @@ -76,6 +76,9 @@ def windowsShlinkSources(target, source, env, for_signature): def windowsLibEmitter(target, source, env): SCons.Tool.msvc.validate_vars(env) + extratargets = [] + extrasources = [] + dll = env.FindIxes(target, "SHLIBPREFIX", "SHLIBSUFFIX") no_import_lib = env.get('no_import_lib', 0) @@ -87,38 +90,44 @@ def windowsLibEmitter(target, source, env): not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"): # append a def file to the list of sources - source.append(env.ReplaceIxes(dll, - "SHLIBPREFIX", "SHLIBSUFFIX", - "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")) + extrasources.append( + env.ReplaceIxes(dll, + "SHLIBPREFIX", "SHLIBSUFFIX", + "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")) version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0')) if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0): # MSVC 8 automatically generates .manifest files that must be installed - target.append(env.ReplaceIxes(dll, - "SHLIBPREFIX", "SHLIBSUFFIX", - "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX")) + extratargets.append( + env.ReplaceIxes(dll, + "SHLIBPREFIX", "SHLIBSUFFIX", + "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX")) if env.has_key('PDB') and env['PDB']: pdb = env.arg2nodes('$PDB', target=target, source=source)[0] - target.append(pdb) + extratargets.append(pdb) target[0].attributes.pdb = pdb if not no_import_lib and \ not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"): # Append an import library to the list of targets. - target.append(env.ReplaceIxes(dll, - "SHLIBPREFIX", "SHLIBSUFFIX", - "LIBPREFIX", "LIBSUFFIX")) + extratargets.append( + env.ReplaceIxes(dll, + "SHLIBPREFIX", "SHLIBSUFFIX", + "LIBPREFIX", "LIBSUFFIX")) # and .exp file is created if there are exports from a DLL - target.append(env.ReplaceIxes(dll, - "SHLIBPREFIX", "SHLIBSUFFIX", - "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX")) + extratargets.append( + env.ReplaceIxes(dll, + "SHLIBPREFIX", "SHLIBSUFFIX", + "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX")) - return (target, source) + return (target+extratargets, source+extrasources) def prog_emitter(target, source, env): SCons.Tool.msvc.validate_vars(env) + extratargets = [] + exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX") if not exe: raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX") @@ -126,16 +135,17 @@ def prog_emitter(target, source, env): version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0')) if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0): # MSVC 8 automatically generates .manifest files that have to be installed - target.append(env.ReplaceIxes(exe, - "PROGPREFIX", "PROGSUFFIX", - "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX")) + extratargets.append( + env.ReplaceIxes(exe, + "PROGPREFIX", "PROGSUFFIX", + "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX")) if env.has_key('PDB') and env['PDB']: pdb = env.arg2nodes('$PDB', target=target, source=source)[0] - target.append(pdb) + extratargets.append(pdb) target[0].attributes.pdb = pdb - return (target,source) + return (target+extratargets,source) def RegServerFunc(target, source, env): if env.has_key('register') and env['register']: diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/msvc.py b/scons/scons-local-1.2.0/SCons/Tool/msvc.py similarity index 93% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/msvc.py rename to scons/scons-local-1.2.0/SCons/Tool/msvc.py index 4f4875077..5b7874a20 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/msvc.py +++ b/scons/scons-local-1.2.0/SCons/Tool/msvc.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/msvc.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/msvc.py 3842 2008/12/20 22:59:52 scons" import os.path import re @@ -45,6 +45,7 @@ import SCons.Tool import SCons.Tool.msvs import SCons.Util import SCons.Warnings +import SCons.Scanner.RC CSuffixes = ['.c', '.C'] CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] @@ -203,6 +204,11 @@ def _parse_msvc8_overrides(version,platform,suite): user_settings = doc.getElementsByTagName('UserSettings')[0] tool_options = user_settings.getElementsByTagName('ToolsOptions')[0] tool_options_categories = tool_options.getElementsByTagName('ToolsOptionsCategory') + environment_var_map = { + 'IncludeDirectories' : 'INCLUDE', + 'LibraryDirectories' : 'LIBRARY', + 'ExecutableDirectories' : 'PATH', + } for category in tool_options_categories: category_name = category.attributes.get('name') if category_name is not None and category_name.value == 'Projects': @@ -215,21 +221,21 @@ def _parse_msvc8_overrides(version,platform,suite): property_name = property.attributes.get('name') if property_name is None: continue - elif property_name.value == 'IncludeDirectories': - include_dirs = property.childNodes[0].data - # ToDo: Support for other destinations than Win32 - include_dirs = include_dirs.replace('Win32|', '') - dirs['INCLUDE'] = include_dirs - elif property_name.value == 'LibraryDirectories': - lib_dirs = property.childNodes[0].data.replace('Win32|', '') - # ToDo: Support for other destinations than Win32 - lib_dirs = lib_dirs.replace('Win32|', '') - dirs['LIBRARY'] = lib_dirs - elif property_name.value == 'ExecutableDirectories': - path_dirs = property.childNodes[0].data.replace('Win32|', '') - # ToDo: Support for other destinations than Win32 - path_dirs = path_dirs.replace('Win32|', '') - dirs['PATH'] = path_dirs + var_name = environment_var_map.get(property_name) + if var_name: + data = property.childNodes[0].data + value_list = string.split(data, '|') + if len(value_list) == 1: + dirs[var_name] = value_list[0] + else: + while value_list: + dest, value = value_list[:2] + del value_list[:2] + # ToDo: Support for destinations + # other than Win32 + if dest == 'Win32': + dirs[var_name] = value + break else: # There are no default directories in the registry for VS8 Express :( raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry." @@ -513,10 +519,6 @@ def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs): include_paths.append( os.path.join( atlmfc_path, 'include' ) ) lib_paths.append( os.path.join( atlmfc_path, 'lib' ) ) - env_include_path = SCons.Util.get_environment_var('INCLUDE') - if env_include_path: - include_paths.append( env_include_path ) - if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'): fwdir = paths['FRAMEWORKSDKDIR'] include_paths.append( os.path.join( fwdir, 'include' ) ) @@ -659,13 +661,17 @@ pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR') pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', emitter=pch_emitter, source_scanner=SCons.Tool.SourceFileScanner) -res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') + + +# Logic to build .rc files into .res files (resource files) +res_scanner = SCons.Scanner.RC.RCScan() +res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') res_builder = SCons.Builder.Builder(action=res_action, src_suffix='.rc', suffix='.res', src_builder=[], - source_scanner=SCons.Tool.SourceFileScanner) -SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) + source_scanner=res_scanner) + def generate(env): """Add Builders and construction variables for MSVC++ to an Environment.""" @@ -685,21 +691,21 @@ def generate(env): env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}']) env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}']) - env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS' + env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS' env['CC'] = 'cl' env['CCFLAGS'] = SCons.Util.CLVar('/nologo') env['CFLAGS'] = SCons.Util.CLVar('') - env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS' + env['CCCOM'] = '$CC /Fo$TARGET /c $SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM' env['SHCC'] = '$CC' env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') - env['SHCCCOM'] = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS' + env['SHCCCOM'] = '$SHCC /Fo$TARGET /c $SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM' env['CXX'] = '$CC' env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)') - env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS' + env['CXXCOM'] = '$CXX /Fo$TARGET /c $SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM' env['SHCXX'] = '$CXX' env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS' + env['SHCXXCOM'] = '$SHCXX /Fo$TARGET /c $SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM' env['CPPDEFPREFIX'] = '/D' env['CPPDEFSUFFIX'] = '' env['INCPREFIX'] = '/I' @@ -710,6 +716,7 @@ def generate(env): env['RC'] = 'rc' env['RCFLAGS'] = SCons.Util.CLVar('') + env['RCSUFFIXES']=['.rc','.rc2'] env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES' env['BUILDERS']['RES'] = res_builder env['OBJPREFIX'] = '' diff --git a/scons/scons-local-0.97.0d20071212/SCons/Tool/msvs.py b/scons/scons-local-1.2.0/SCons/Tool/msvs.py similarity index 96% rename from scons/scons-local-0.97.0d20071212/SCons/Tool/msvs.py rename to scons/scons-local-1.2.0/SCons/Tool/msvs.py index 5e029321a..f8a20ea1f 100644 --- a/scons/scons-local-0.97.0d20071212/SCons/Tool/msvs.py +++ b/scons/scons-local-1.2.0/SCons/Tool/msvs.py @@ -9,7 +9,7 @@ selection method. """ # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,10 +31,10 @@ selection method. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/msvs.py 2523 2007/12/12 09:37:41 knight" +__revision__ = "src/engine/SCons/Tool/msvs.py 3842 2008/12/20 22:59:52 scons" import base64 -import md5 +import hashlib import os.path import pickle import re @@ -79,7 +79,11 @@ def _generateGUID(slnfile, name): based on the MD5 signatures of the sln filename plus the name of the project. It basically just needs to be unique, and not change with each invocation.""" - solution = _hexdigest(md5.new(str(slnfile)+str(name)).digest()).upper() + m = hashlib.md5() + m.update(str(slnfile) + str(name)) + # TODO(1.5) + #solution = m.hexdigest().upper() + solution = string.upper(_hexdigest(m.digest())) # convert most of the signature to GUID form (discard the rest) solution = "{" + solution[:8] + "-" + solution[8:12] + "-" + solution[12:16] + "-" + solution[16:20] + "-" + solution[20:32] + "}" return solution @@ -295,7 +299,9 @@ class _DSPGenerator: self.sources[t[0]].append(self.env[t[1]]) for n in sourcenames: - self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower())) + # TODO(1.5): + #self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower())) + self.sources[n].sort(lambda a, b: cmp(string.lower(a), string.lower(b))) def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile): config = Config() @@ -394,7 +400,9 @@ class _GenerateV6DSP(_DSPGenerator): for base in ("BASE ",""): self.file.write('# PROP %sUse_MFC 0\n' '# PROP %sUse_Debug_Libraries ' % (base, base)) - if kind.lower().find('debug') < 0: + # TODO(1.5): + #if kind.lower().find('debug') < 0: + if string.find(string.lower(kind), 'debug') < 0: self.file.write('0\n') else: self.file.write('1\n') @@ -445,13 +453,17 @@ class _GenerateV6DSP(_DSPGenerator): 'Other Files': ''} cats = categories.keys() - cats.sort(lambda a, b: cmp(a.lower(), b.lower())) + # TODO(1.5): + #cats.sort(lambda a, b: cmp(a.lower(), b.lower())) + cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b))) for kind in cats: if not self.sources[kind]: continue # skip empty groups self.file.write('# Begin Group "' + kind + '"\n\n') - typelist = categories[kind].replace('|',';') + # TODO(1.5) + #typelist = categories[kind].replace('|', ';') + typelist = string.replace(categories[kind], '|', ';') self.file.write('# PROP Default_Filter "' + typelist + '"\n') for file in self.sources[kind]: @@ -474,7 +486,9 @@ class _GenerateV6DSP(_DSPGenerator): line = dspfile.readline() while line: - if line.find("# End Project") > -1: + # TODO(1.5): + #if line.find("# End Project") > -1: + if string.find(line, "# End Project") > -1: break line = dspfile.readline() @@ -692,7 +706,9 @@ class _GenerateV7DSP(_DSPGenerator): def printSources(self, hierarchy, commonprefix): sorteditems = hierarchy.items() - sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower())) + # TODO(1.5): + #sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower())) + sorteditems.sort(lambda a, b: cmp(string.lower(a[0]), string.lower(b[0]))) # First folders, then files for key, value in sorteditems: @@ -723,7 +739,9 @@ class _GenerateV7DSP(_DSPGenerator): self.file.write('\t\n') cats = categories.keys() - cats.sort(lambda a, b: cmp(a.lower(), b.lower())) + # TODO(1.5) + #cats.sort(lambda a, b: cmp(a.lower(), b.lower())) + cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b))) cats = filter(lambda k, s=self: s.sources[k], cats) for kind in cats: if len(cats) > 1: @@ -772,7 +790,9 @@ class _GenerateV7DSP(_DSPGenerator): line = dspfile.readline() while line: - if line.find('