From db9c4bc340eb9e01f54390b7a6a5c451ec74454d Mon Sep 17 00:00:00 2001 From: David Hummel <6109326+hummeltech@users.noreply.github.com> Date: Wed, 1 Mar 2023 11:40:40 -0700 Subject: [PATCH 1/2] Add `fonts` & `input_plugins` variables to libmapnik.pc --- cmake/MapnikExportPkgConfig.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/MapnikExportPkgConfig.cmake b/cmake/MapnikExportPkgConfig.cmake index f92e1e203..e459f80ef 100644 --- a/cmake/MapnikExportPkgConfig.cmake +++ b/cmake/MapnikExportPkgConfig.cmake @@ -65,6 +65,8 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} includedir=${prefix}/include libdir=${exec_prefix}/lib +fonts_dir=${prefix}/@FONTS_INSTALL_DIR@ +plugins_dir=${prefix}/@PLUGINS_INSTALL_DIR@ Name: @_lib_name@ Description: @_description@ From c646d245b491dc0b10ea7507046f4acdf2d4c7e8 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 8 Mar 2023 12:01:16 +0000 Subject: [PATCH 2/2] Upgrade SCons to v4.5.1 --- scons/scons-LICENSE | 2 +- scons/scons-README | 4 +- scons/scons-local-4.1.0/SCons/Action.py | 1476 ------- scons/scons-local-4.1.0/SCons/Builder.py | 893 ---- scons/scons-local-4.1.0/SCons/CacheDir.py | 294 -- scons/scons-local-4.1.0/SCons/Conftest.py | 805 ---- scons/scons-local-4.1.0/SCons/Debug.py | 251 -- scons/scons-local-4.1.0/SCons/Defaults.py | 644 --- scons/scons-local-4.1.0/SCons/Environment.py | 2555 ----------- .../SCons/EnvironmentValues.py | 119 - .../SCons/EnvironmentValuesTest.py | 39 - scons/scons-local-4.1.0/SCons/Errors.py | 222 - scons/scons-local-4.1.0/SCons/Executor.py | 666 --- scons/scons-local-4.1.0/SCons/Job.py | 431 -- scons/scons-local-4.1.0/SCons/Memoize.py | 242 -- scons/scons-local-4.1.0/SCons/Node/Alias.py | 176 - scons/scons-local-4.1.0/SCons/Node/FS.py | 3820 ----------------- scons/scons-local-4.1.0/SCons/Node/Python.py | 202 - .../scons-local-4.1.0/SCons/Node/__init__.py | 1780 -------- scons/scons-local-4.1.0/SCons/PathList.py | 224 - .../SCons/Platform/__init__.py | 314 -- scons/scons-local-4.1.0/SCons/Platform/aix.py | 80 - .../SCons/Platform/cygwin.py | 60 - .../SCons/Platform/darwin.py | 69 - .../scons-local-4.1.0/SCons/Platform/hpux.py | 44 - .../scons-local-4.1.0/SCons/Platform/irix.py | 40 - .../scons-local-4.1.0/SCons/Platform/mingw.py | 33 - scons/scons-local-4.1.0/SCons/Platform/os2.py | 55 - .../scons-local-4.1.0/SCons/Platform/posix.py | 124 - .../scons-local-4.1.0/SCons/Platform/sunos.py | 46 - .../SCons/Platform/virtualenv.py | 115 - .../scons-local-4.1.0/SCons/Platform/win32.py | 428 -- scons/scons-local-4.1.0/SCons/SConf.py | 1116 ----- scons/scons-local-4.1.0/SCons/SConsign.py | 427 -- scons/scons-local-4.1.0/SCons/Scanner/C.py | 218 - scons/scons-local-4.1.0/SCons/Scanner/D.py | 67 - scons/scons-local-4.1.0/SCons/Scanner/Dir.py | 108 - .../SCons/Scanner/Fortran.py | 319 -- scons/scons-local-4.1.0/SCons/Scanner/IDL.py | 43 - .../scons-local-4.1.0/SCons/Scanner/LaTeX.py | 423 -- scons/scons-local-4.1.0/SCons/Scanner/Prog.py | 114 - .../scons-local-4.1.0/SCons/Scanner/Python.py | 166 - scons/scons-local-4.1.0/SCons/Scanner/RC.py | 57 - scons/scons-local-4.1.0/SCons/Scanner/SWIG.py | 39 - .../SCons/Scanner/__init__.py | 417 -- .../SCons/Script/Interactive.py | 372 -- scons/scons-local-4.1.0/SCons/Script/Main.py | 1446 ------- .../SCons/Script/SConsOptions.py | 983 ----- .../SCons/Script/SConscript.py | 680 --- .../SCons/Script/__init__.py | 424 -- scons/scons-local-4.1.0/SCons/Subst.py | 972 ----- scons/scons-local-4.1.0/SCons/Taskmaster.py | 1059 ----- scons/scons-local-4.1.0/SCons/Tool/386asm.py | 61 - scons/scons-local-4.1.0/SCons/Tool/DCommon.py | 64 - .../SCons/Tool/FortranCommon.py | 279 -- .../SCons/Tool/GettextCommon.py | 469 -- .../SCons/Tool/JavaCommon.py | 513 --- .../SCons/Tool/MSCommon/README | 107 - .../SCons/Tool/MSCommon/__init__.py | 54 - .../SCons/Tool/MSCommon/arch.py | 66 - .../SCons/Tool/MSCommon/common.py | 353 -- .../SCons/Tool/MSCommon/netframework.py | 83 - .../SCons/Tool/MSCommon/sdk.py | 411 -- .../SCons/Tool/MSCommon/vc.py | 955 ----- .../SCons/Tool/MSCommon/vs.py | 597 --- .../SCons/Tool/PharLapCommon.py | 116 - .../scons-local-4.1.0/SCons/Tool/__init__.py | 868 ---- scons/scons-local-4.1.0/SCons/Tool/aixc++.py | 43 - scons/scons-local-4.1.0/SCons/Tool/aixcc.py | 74 - scons/scons-local-4.1.0/SCons/Tool/aixcxx.py | 77 - scons/scons-local-4.1.0/SCons/Tool/aixf77.py | 80 - scons/scons-local-4.1.0/SCons/Tool/aixlink.py | 78 - .../scons-local-4.1.0/SCons/Tool/applelink.py | 189 - scons/scons-local-4.1.0/SCons/Tool/ar.py | 63 - scons/scons-local-4.1.0/SCons/Tool/as.py | 49 - scons/scons-local-4.1.0/SCons/Tool/asm.py | 78 - scons/scons-local-4.1.0/SCons/Tool/bcc32.py | 81 - scons/scons-local-4.1.0/SCons/Tool/c++.py | 44 - scons/scons-local-4.1.0/SCons/Tool/cc.py | 105 - scons/scons-local-4.1.0/SCons/Tool/clang.py | 98 - .../SCons/Tool/clangCommon/__init__.py | 18 - scons/scons-local-4.1.0/SCons/Tool/clangxx.py | 107 - .../SCons/Tool/compilation_db.py | 255 -- scons/scons-local-4.1.0/SCons/Tool/cvf.py | 58 - scons/scons-local-4.1.0/SCons/Tool/cxx.py | 95 - scons/scons-local-4.1.0/SCons/Tool/cyglink.py | 212 - scons/scons-local-4.1.0/SCons/Tool/default.py | 50 - scons/scons-local-4.1.0/SCons/Tool/dmd.py | 169 - scons/scons-local-4.1.0/SCons/Tool/dvi.py | 64 - scons/scons-local-4.1.0/SCons/Tool/dvipdf.py | 125 - scons/scons-local-4.1.0/SCons/Tool/dvips.py | 95 - scons/scons-local-4.1.0/SCons/Tool/f03.py | 67 - scons/scons-local-4.1.0/SCons/Tool/f08.py | 67 - scons/scons-local-4.1.0/SCons/Tool/f77.py | 66 - scons/scons-local-4.1.0/SCons/Tool/f90.py | 66 - scons/scons-local-4.1.0/SCons/Tool/f95.py | 67 - .../SCons/Tool/filesystem.py | 98 - scons/scons-local-4.1.0/SCons/Tool/fortran.py | 62 - scons/scons-local-4.1.0/SCons/Tool/g++.py | 45 - scons/scons-local-4.1.0/SCons/Tool/g77.py | 73 - scons/scons-local-4.1.0/SCons/Tool/gas.py | 56 - scons/scons-local-4.1.0/SCons/Tool/gcc.py | 109 - scons/scons-local-4.1.0/SCons/Tool/gdc.py | 134 - .../SCons/Tool/gettext_tool.py | 60 - .../scons-local-4.1.0/SCons/Tool/gfortran.py | 66 - scons/scons-local-4.1.0/SCons/Tool/gnulink.py | 70 - scons/scons-local-4.1.0/SCons/Tool/gs.py | 91 - scons/scons-local-4.1.0/SCons/Tool/gxx.py | 78 - scons/scons-local-4.1.0/SCons/Tool/hpc++.py | 45 - scons/scons-local-4.1.0/SCons/Tool/hpcc.py | 53 - scons/scons-local-4.1.0/SCons/Tool/hpcxx.py | 88 - scons/scons-local-4.1.0/SCons/Tool/hplink.py | 72 - scons/scons-local-4.1.0/SCons/Tool/icc.py | 59 - scons/scons-local-4.1.0/SCons/Tool/icl.py | 52 - scons/scons-local-4.1.0/SCons/Tool/ifl.py | 72 - scons/scons-local-4.1.0/SCons/Tool/ifort.py | 88 - scons/scons-local-4.1.0/SCons/Tool/ilink.py | 55 - scons/scons-local-4.1.0/SCons/Tool/ilink32.py | 60 - scons/scons-local-4.1.0/SCons/Tool/install.py | 473 -- scons/scons-local-4.1.0/SCons/Tool/intelc.py | 612 --- scons/scons-local-4.1.0/SCons/Tool/ipkg.py | 75 - scons/scons-local-4.1.0/SCons/Tool/jar.py | 241 -- scons/scons-local-4.1.0/SCons/Tool/javac.py | 248 -- scons/scons-local-4.1.0/SCons/Tool/javah.py | 147 - scons/scons-local-4.1.0/SCons/Tool/latex.py | 80 - scons/scons-local-4.1.0/SCons/Tool/ldc.py | 147 - scons/scons-local-4.1.0/SCons/Tool/lex.py | 141 - scons/scons-local-4.1.0/SCons/Tool/link.py | 72 - .../SCons/Tool/linkCommon/LoadableModule.py | 131 - .../SCons/Tool/linkCommon/README.md | 89 - .../SCons/Tool/linkCommon/SharedLibrary.py | 199 - .../SCons/Tool/linkCommon/__init__.py | 167 - scons/scons-local-4.1.0/SCons/Tool/linkloc.py | 112 - scons/scons-local-4.1.0/SCons/Tool/m4.py | 63 - scons/scons-local-4.1.0/SCons/Tool/masm.py | 77 - scons/scons-local-4.1.0/SCons/Tool/midl.py | 88 - scons/scons-local-4.1.0/SCons/Tool/mingw.py | 215 - scons/scons-local-4.1.0/SCons/Tool/msgfmt.py | 122 - scons/scons-local-4.1.0/SCons/Tool/msginit.py | 133 - .../scons-local-4.1.0/SCons/Tool/msgmerge.py | 117 - scons/scons-local-4.1.0/SCons/Tool/mslib.py | 73 - scons/scons-local-4.1.0/SCons/Tool/mslink.py | 339 -- scons/scons-local-4.1.0/SCons/Tool/mssdk.py | 50 - scons/scons-local-4.1.0/SCons/Tool/msvc.py | 311 -- scons/scons-local-4.1.0/SCons/Tool/msvs.py | 2116 --------- scons/scons-local-4.1.0/SCons/Tool/mwcc.py | 207 - scons/scons-local-4.1.0/SCons/Tool/mwld.py | 108 - scons/scons-local-4.1.0/SCons/Tool/nasm.py | 72 - .../SCons/Tool/packaging/__init__.py | 328 -- .../SCons/Tool/packaging/ipk.py | 189 - .../SCons/Tool/packaging/msi.py | 525 --- .../SCons/Tool/packaging/rpm.py | 364 -- .../SCons/Tool/packaging/src_tarbz2.py | 43 - .../SCons/Tool/packaging/src_targz.py | 43 - .../SCons/Tool/packaging/src_tarxz.py | 43 - .../SCons/Tool/packaging/src_zip.py | 43 - .../SCons/Tool/packaging/tarbz2.py | 44 - .../SCons/Tool/packaging/targz.py | 44 - .../SCons/Tool/packaging/tarxz.py | 44 - .../SCons/Tool/packaging/zip.py | 44 - scons/scons-local-4.1.0/SCons/Tool/pdf.py | 78 - .../scons-local-4.1.0/SCons/Tool/pdflatex.py | 84 - scons/scons-local-4.1.0/SCons/Tool/pdftex.py | 109 - scons/scons-local-4.1.0/SCons/Tool/python.py | 49 - scons/scons-local-4.1.0/SCons/Tool/qt.py | 371 -- scons/scons-local-4.1.0/SCons/Tool/rmic.py | 139 - scons/scons-local-4.1.0/SCons/Tool/rpcgen.py | 70 - scons/scons-local-4.1.0/SCons/Tool/rpm.py | 133 - .../scons-local-4.1.0/SCons/Tool/rpmutils.py | 546 --- scons/scons-local-4.1.0/SCons/Tool/sgiar.py | 68 - scons/scons-local-4.1.0/SCons/Tool/sgic++.py | 43 - scons/scons-local-4.1.0/SCons/Tool/sgicc.py | 53 - scons/scons-local-4.1.0/SCons/Tool/sgicxx.py | 61 - scons/scons-local-4.1.0/SCons/Tool/sgilink.py | 59 - scons/scons-local-4.1.0/SCons/Tool/sunar.py | 64 - scons/scons-local-4.1.0/SCons/Tool/sunc++.py | 45 - scons/scons-local-4.1.0/SCons/Tool/suncc.py | 58 - scons/scons-local-4.1.0/SCons/Tool/suncxx.py | 153 - scons/scons-local-4.1.0/SCons/Tool/sunf77.py | 63 - scons/scons-local-4.1.0/SCons/Tool/sunf90.py | 64 - scons/scons-local-4.1.0/SCons/Tool/sunf95.py | 64 - scons/scons-local-4.1.0/SCons/Tool/sunlink.py | 79 - scons/scons-local-4.1.0/SCons/Tool/swig.py | 217 - scons/scons-local-4.1.0/SCons/Tool/tar.py | 73 - scons/scons-local-4.1.0/SCons/Tool/tex.py | 996 ----- .../scons-local-4.1.0/SCons/Tool/textfile.py | 200 - scons/scons-local-4.1.0/SCons/Tool/tlib.py | 53 - scons/scons-local-4.1.0/SCons/Tool/wix.py | 104 - .../scons-local-4.1.0/SCons/Tool/xgettext.py | 357 -- scons/scons-local-4.1.0/SCons/Tool/yacc.py | 177 - scons/scons-local-4.1.0/SCons/Tool/zip.py | 120 - scons/scons-local-4.1.0/SCons/Util.py | 1655 ------- .../SCons/Utilities/ConfigureCache.py | 171 - .../SCons/Utilities/__init__.py | 0 .../SCons/Utilities/sconsign.py | 494 --- .../SCons/Variables/BoolVariable.py | 85 - .../SCons/Variables/EnumVariable.py | 107 - .../SCons/Variables/ListVariable.py | 138 - .../SCons/Variables/PackageVariable.py | 104 - .../SCons/Variables/PathVariable.py | 144 - .../SCons/Variables/__init__.py | 325 -- scons/scons-local-4.1.0/SCons/Warnings.py | 236 - scons/scons-local-4.1.0/SCons/__init__.py | 9 - scons/scons-local-4.1.0/SCons/__main__.py | 27 - .../SCons/compat/__init__.py | 104 - .../SCons/compat/_scons_dbm.py | 42 - scons/scons-local-4.1.0/SCons/compat/win32.py | 101 - scons/scons-local-4.1.0/SCons/cpp.py | 655 --- scons/scons-local-4.1.0/SCons/dblite.py | 298 -- scons/scons-local-4.1.0/SCons/exitfuncs.py | 59 - scons/scons-time.py | 19 +- scons/scons.py | 19 +- scons/sconsign.py | 16 +- 213 files changed, 32 insertions(+), 53230 deletions(-) delete mode 100644 scons/scons-local-4.1.0/SCons/Action.py delete mode 100644 scons/scons-local-4.1.0/SCons/Builder.py delete mode 100644 scons/scons-local-4.1.0/SCons/CacheDir.py delete mode 100644 scons/scons-local-4.1.0/SCons/Conftest.py delete mode 100644 scons/scons-local-4.1.0/SCons/Debug.py delete mode 100644 scons/scons-local-4.1.0/SCons/Defaults.py delete mode 100644 scons/scons-local-4.1.0/SCons/Environment.py delete mode 100644 scons/scons-local-4.1.0/SCons/EnvironmentValues.py delete mode 100644 scons/scons-local-4.1.0/SCons/EnvironmentValuesTest.py delete mode 100644 scons/scons-local-4.1.0/SCons/Errors.py delete mode 100644 scons/scons-local-4.1.0/SCons/Executor.py delete mode 100644 scons/scons-local-4.1.0/SCons/Job.py delete mode 100644 scons/scons-local-4.1.0/SCons/Memoize.py delete mode 100644 scons/scons-local-4.1.0/SCons/Node/Alias.py delete mode 100644 scons/scons-local-4.1.0/SCons/Node/FS.py delete mode 100644 scons/scons-local-4.1.0/SCons/Node/Python.py delete mode 100644 scons/scons-local-4.1.0/SCons/Node/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/PathList.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/aix.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/cygwin.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/darwin.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/hpux.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/irix.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/mingw.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/os2.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/posix.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/sunos.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/virtualenv.py delete mode 100644 scons/scons-local-4.1.0/SCons/Platform/win32.py delete mode 100644 scons/scons-local-4.1.0/SCons/SConf.py delete mode 100644 scons/scons-local-4.1.0/SCons/SConsign.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/C.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/D.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/Dir.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/Fortran.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/IDL.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/LaTeX.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/Prog.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/Python.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/RC.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/SWIG.py delete mode 100644 scons/scons-local-4.1.0/SCons/Scanner/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Script/Interactive.py delete mode 100644 scons/scons-local-4.1.0/SCons/Script/Main.py delete mode 100644 scons/scons-local-4.1.0/SCons/Script/SConsOptions.py delete mode 100644 scons/scons-local-4.1.0/SCons/Script/SConscript.py delete mode 100644 scons/scons-local-4.1.0/SCons/Script/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Subst.py delete mode 100644 scons/scons-local-4.1.0/SCons/Taskmaster.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/386asm.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/DCommon.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/FortranCommon.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/GettextCommon.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/JavaCommon.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/README delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/arch.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/common.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/netframework.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/sdk.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/vc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/MSCommon/vs.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/PharLapCommon.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/aixc++.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/aixcc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/aixcxx.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/aixf77.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/aixlink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/applelink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/ar.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/as.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/asm.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/bcc32.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/c++.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/cc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/clang.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/clangCommon/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/clangxx.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/compilation_db.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/cvf.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/cxx.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/cyglink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/default.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/dmd.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/dvi.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/dvipdf.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/dvips.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/f03.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/f08.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/f77.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/f90.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/f95.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/filesystem.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/fortran.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/g++.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/g77.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gas.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gcc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gdc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gettext_tool.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gfortran.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gnulink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gs.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/gxx.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/hpc++.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/hpcc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/hpcxx.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/hplink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/icc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/icl.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/ifl.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/ifort.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/ilink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/ilink32.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/install.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/intelc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/ipkg.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/jar.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/javac.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/javah.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/latex.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/ldc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/lex.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/link.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/linkCommon/LoadableModule.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/linkCommon/README.md delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/linkCommon/SharedLibrary.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/linkCommon/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/linkloc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/m4.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/masm.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/midl.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/mingw.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/msgfmt.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/msginit.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/msgmerge.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/mslib.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/mslink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/mssdk.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/msvc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/msvs.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/mwcc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/mwld.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/nasm.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/ipk.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/msi.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/rpm.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarbz2.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/src_targz.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarxz.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/src_zip.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/tarbz2.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/targz.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/tarxz.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/packaging/zip.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/pdf.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/pdflatex.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/pdftex.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/python.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/qt.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/rmic.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/rpcgen.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/rpm.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/rpmutils.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sgiar.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sgic++.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sgicc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sgicxx.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sgilink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sunar.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sunc++.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/suncc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/suncxx.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sunf77.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sunf90.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sunf95.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/sunlink.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/swig.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/tar.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/tex.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/textfile.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/tlib.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/wix.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/xgettext.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/yacc.py delete mode 100644 scons/scons-local-4.1.0/SCons/Tool/zip.py delete mode 100644 scons/scons-local-4.1.0/SCons/Util.py delete mode 100644 scons/scons-local-4.1.0/SCons/Utilities/ConfigureCache.py delete mode 100644 scons/scons-local-4.1.0/SCons/Utilities/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Utilities/sconsign.py delete mode 100644 scons/scons-local-4.1.0/SCons/Variables/BoolVariable.py delete mode 100644 scons/scons-local-4.1.0/SCons/Variables/EnumVariable.py delete mode 100644 scons/scons-local-4.1.0/SCons/Variables/ListVariable.py delete mode 100644 scons/scons-local-4.1.0/SCons/Variables/PackageVariable.py delete mode 100644 scons/scons-local-4.1.0/SCons/Variables/PathVariable.py delete mode 100644 scons/scons-local-4.1.0/SCons/Variables/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/Warnings.py delete mode 100644 scons/scons-local-4.1.0/SCons/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/__main__.py delete mode 100644 scons/scons-local-4.1.0/SCons/compat/__init__.py delete mode 100644 scons/scons-local-4.1.0/SCons/compat/_scons_dbm.py delete mode 100644 scons/scons-local-4.1.0/SCons/compat/win32.py delete mode 100644 scons/scons-local-4.1.0/SCons/cpp.py delete mode 100644 scons/scons-local-4.1.0/SCons/dblite.py delete mode 100644 scons/scons-local-4.1.0/SCons/exitfuncs.py diff --git a/scons/scons-LICENSE b/scons/scons-LICENSE index 0083ed1d4..ef99104b6 100644 --- a/scons/scons-LICENSE +++ b/scons/scons-LICENSE @@ -5,7 +5,7 @@ MIT License -Copyright (c) 2001 - 2021 The SCons Foundation +Copyright (c) 2001 - 2023 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 719ce517f..e32b71e3b 100644 --- a/scons/scons-README +++ b/scons/scons-README @@ -1,4 +1,3 @@ -# Copyright (c) 2001 - 2021 The SCons Foundation SCons - a software construction tool @@ -47,6 +46,9 @@ EXECUTION REQUIREMENTS Running SCons requires Python 3.5 or higher. There should be no other dependencies or requirements to run SCons. +As of SCons 4.2.0 support for Python 3.5 is deprecated and will be removed +with the next major release. + The default SCons configuration assumes use of the Microsoft Visual C++ compiler suite on WIN32 systems (either through the Visual Studio product, or through the separate Build Tools), and assumes a C compiler diff --git a/scons/scons-local-4.1.0/SCons/Action.py b/scons/scons-local-4.1.0/SCons/Action.py deleted file mode 100644 index d7f10df52..000000000 --- a/scons/scons-local-4.1.0/SCons/Action.py +++ /dev/null @@ -1,1476 +0,0 @@ -# MIT License -# -# Copyright 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 Actions. - -Information about executing any sort of action that -can build one or more target Nodes (typically files) from one or more -source Nodes (also typically files) given a specific Environment. - -The base class here is ActionBase. The base class supplies just a few -utility methods and some generic methods for displaying information -about an Action in response to the various commands that control printing. - -A second-level base class is _ActionAction. This extends ActionBase -by providing the methods that can be used to show and perform an -action. True Action objects will subclass _ActionAction; Action -factory class objects will subclass ActionBase. - -The heavy lifting is handled by subclasses for the different types of -actions we might execute: - - CommandAction - CommandGeneratorAction - FunctionAction - ListAction - -The subclasses supply the following public interface methods used by -other modules: - - __call__() - THE public interface, "calling" an Action object executes the - command or Python function. This also takes care of printing - a pre-substitution command for debugging purposes. - - get_contents() - 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* - command substitution, but allows a CommandGeneratorAction to - generate the right action based on the specified target, - source and env. This is used by the Signature subsystem - (through the Executor) to obtain an (imprecise) representation - of the Action operation for informative purposes. - - -Subclasses also supply the following methods for internal use within -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 - that the __call__() methods can take care of displaying any - 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. - TODO(?): Change this to always return bytes and not str? - - strfunction() - Returns a substituted string representation of the Action. - This is used by the _ActionAction.show() command to display the - command/function that will be executed to generate the target(s). - -There is a related independent ActionCaller class that looks like a -regular Action, and which serves as a wrapper for arbitrary functions -that we want to let the user specify the arguments to now, but actually -execute later (when an out-of-date check determines that it's needed to -be executed, for example). Objects of this class are returned by an -ActionFactory class that provides a __call__() method as a convenient -way for wrapping up the functions. - -""" - -import os -import pickle -import re -import sys -import subprocess -from subprocess import DEVNULL -import itertools -import inspect -from collections import OrderedDict - -import SCons.Debug -from SCons.Debug import logInstanceCreation -import SCons.Errors -import SCons.Util -import SCons.Subst - -# we use these a lot, so try to optimize them -from SCons.Util import is_String, is_List - -class _null: - pass - -print_actions = 1 -execute_actions = 1 -print_actions_presub = 0 - -# Use pickle protocol 1 when pickling functions for signature -# otherwise python3 and python2 will yield different pickles -# for the same object. -# This is due to default being 1 for python 2.7, and 3 for 3.x -# TODO: We can roll this forward to 2 (if it has value), but not -# before a deprecation cycle as the sconsigns will change -ACTION_SIGNATURE_PICKLE_PROTOCOL = 1 - - -def rfile(n): - try: - return n.rfile() - except AttributeError: - return n - - -def default_exitstatfunc(s): - return s - -strip_quotes = re.compile('^[\'"](.*)[\'"]$') - - -def _callable_contents(obj): - """Return the signature contents of a callable Python object. - """ - try: - # Test if obj is a method. - return _function_contents(obj.__func__) - - except AttributeError: - try: - # Test if obj is a callable object. - return _function_contents(obj.__call__.__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.__func__) - - except AttributeError: - try: - # Test if obj is a callable object. - return _function_contents(obj.__call__.__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 as ae: - # Should be a pickle-able Python object. - try: - return _object_instance_content(obj) - # pickling an Action instance or object doesn't yield a stable - # content as instance property may be dumped in different orders - # return pickle.dumps(obj, ACTION_SIGNATURE_PICKLE_PROTOCOL) - except (pickle.PicklingError, TypeError, AttributeError) as ex: - # 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 bytearray(repr(obj), 'utf-8') - - -def _code_contents(code, docstring=None): - r"""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. - - See: - - https://docs.python.org/2/library/inspect.html - - http://python-reference.readthedocs.io/en/latest/docs/code/index.html - - For info on what each co\_ variable provides - - The signature is as follows (should be byte/chars): - co_argcount, len(co_varnames), len(co_cellvars), len(co_freevars), - ( comma separated signature for each object in co_consts ), - ( comma separated signature for each object in co_names ), - ( The bytecode with line number bytecodes removed from co_code ) - - co_argcount - Returns the number of positional arguments (including arguments with default values). - co_varnames - Returns a tuple containing the names of the local variables (starting with the argument names). - co_cellvars - Returns a tuple containing the names of local variables that are referenced by nested functions. - co_freevars - Returns a tuple containing the names of free variables. (?) - co_consts - Returns a tuple containing the literals used by the bytecode. - co_names - Returns a tuple containing the names used by the bytecode. - co_code - Returns a string representing the sequence of bytecode instructions. - - """ - - # contents = [] - - # The code contents depends on the number of local variables - # but not their actual names. - contents = bytearray("{}, {}".format(code.co_argcount, len(code.co_varnames)), 'utf-8') - - contents.extend(b", ") - contents.extend(bytearray(str(len(code.co_cellvars)), 'utf-8')) - contents.extend(b", ") - contents.extend(bytearray(str(len(code.co_freevars)), 'utf-8')) - - # 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. - z = [_object_contents(cc) for cc in code.co_consts if cc != docstring] - contents.extend(b',(') - contents.extend(bytearray(',', 'utf-8').join(z)) - contents.extend(b')') - - # 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. - z= [bytearray(_object_contents(cc)) for cc in code.co_names] - contents.extend(b',(') - contents.extend(bytearray(',','utf-8').join(z)) - contents.extend(b')') - - # The code contents depends on its actual code!!! - contents.extend(b',(') - contents.extend(code.co_code) - contents.extend(b')') - - return contents - - -def _function_contents(func): - """ - The signature is as follows (should be byte/chars): - < _code_contents (see above) from func.__code__ > - ,( comma separated _object_contents for function argument defaults) - ,( comma separated _object_contents for any closure contents ) - - - See also: https://docs.python.org/3/reference/datamodel.html - - func.__code__ - The code object representing the compiled function body. - - func.__defaults__ - A tuple containing default argument values for those arguments that have defaults, or None if no arguments have a default value - - func.__closure__ - None or a tuple of cells that contain bindings for the function's free variables. - - :Returns: - Signature contents of a function. (in bytes) - """ - - contents = [_code_contents(func.__code__, func.__doc__)] - - # The function contents depends on the value of defaults arguments - if func.__defaults__: - - function_defaults_contents = [_object_contents(cc) for cc in func.__defaults__] - - defaults = bytearray(b',(') - defaults.extend(bytearray(b',').join(function_defaults_contents)) - defaults.extend(b')') - - contents.append(defaults) - else: - contents.append(b',()') - - # The function contents depends on the closure captured cell values. - closure = func.__closure__ or [] - - try: - closure_contents = [_object_contents(x.cell_contents) for x in closure] - except AttributeError: - closure_contents = [] - - contents.append(b',(') - contents.append(bytearray(b',').join(closure_contents)) - contents.append(b')') - - retval = bytearray(b'').join(contents) - return retval - - -def _object_instance_content(obj): - """ - Returns consistant content for a action class or an instance thereof - - :Parameters: - - `obj` Should be either and action class or an instance thereof - - :Returns: - bytearray or bytes representing the obj suitable for generating a signature from. - """ - retval = bytearray() - - if obj is None: - return b'N.' - - if isinstance(obj, SCons.Util.BaseStringTypes): - return SCons.Util.to_bytes(obj) - - inst_class = obj.__class__ - inst_class_name = bytearray(obj.__class__.__name__,'utf-8') - inst_class_module = bytearray(obj.__class__.__module__,'utf-8') - inst_class_hierarchy = bytearray(repr(inspect.getclasstree([obj.__class__,])),'utf-8') - # print("ICH:%s : %s"%(inst_class_hierarchy, repr(obj))) - - properties = [(p, getattr(obj, p, "None")) for p in dir(obj) if not (p[:2] == '__' or inspect.ismethod(getattr(obj, p)) or inspect.isbuiltin(getattr(obj,p))) ] - properties.sort() - properties_str = ','.join(["%s=%s"%(p[0],p[1]) for p in properties]) - properties_bytes = bytearray(properties_str,'utf-8') - - methods = [p for p in dir(obj) if inspect.ismethod(getattr(obj, p))] - methods.sort() - - method_contents = [] - for m in methods: - # print("Method:%s"%m) - v = _function_contents(getattr(obj, m)) - # print("[%s->]V:%s [%s]"%(m,v,type(v))) - method_contents.append(v) - - retval = bytearray(b'{') - retval.extend(inst_class_name) - retval.extend(b":") - retval.extend(inst_class_module) - retval.extend(b'}[[') - retval.extend(inst_class_hierarchy) - retval.extend(b']]{{') - retval.extend(bytearray(b",").join(method_contents)) - retval.extend(b"}}{{{") - retval.extend(properties_bytes) - retval.extend(b'}}}') - return retval - - # print("class :%s"%inst_class) - # print("class_name :%s"%inst_class_name) - # print("class_module :%s"%inst_class_module) - # print("Class hier :\n%s"%pp.pformat(inst_class_hierarchy)) - # print("Inst Properties:\n%s"%pp.pformat(properties)) - # print("Inst Methods :\n%s"%pp.pformat(methods)) - -def _actionAppend(act1, act2): - # This function knows how to slap two actions together. - # Mainly, it handles ListActions by concatenating into - # a single ListAction. - a1 = Action(act1) - a2 = Action(act2) - if a1 is None: - return a2 - if a2 is None: - return a1 - if isinstance(a1, ListAction): - if isinstance(a2, ListAction): - return ListAction(a1.list + a2.list) - else: - return ListAction(a1.list + [ a2 ]) - else: - if isinstance(a2, ListAction): - return ListAction([ a1 ] + a2.list) - else: - return ListAction([ a1, a2 ]) - - -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'] = tuple(SCons.Util.flatten(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 - different semantics than passing lists as elements - of lists. - - The former will create a ListAction, the latter - will create a CommandAction by converting the inner - list elements to strings.""" - - if isinstance(act, ActionBase): - return act - - if is_String(act): - var=SCons.Util.get_environment_var(act) - if var: - # This looks like a string that is purely an Environment - # variable reference, like "$FOO" or "${FOO}". We do - # something special here...we lazily evaluate the contents - # of that Environment variable, so a user could put something - # like a function or a CommandGenerator in that variable - # instead of a string. - return LazyAction(var, kw) - commands = str(act).split('\n') - if len(commands) == 1: - return 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) - - if is_List(act): - return CommandAction(act, **kw) - - if callable(act): - try: - gen = kw['generator'] - del kw['generator'] - except KeyError: - gen = 0 - if gen: - action_type = CommandGeneratorAction - else: - action_type = FunctionAction - return action_type(act, kw) - - # Catch a common error case with a nice message: - if isinstance(act, int) or isinstance(act, float): - raise TypeError("Don't know how to create an Action from a number (%s)"%act) - # Else fail silently (???) - 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 ListAction([]) - elif len(acts) == 1: - return acts[0] - else: - return ListAction(acts) - - -def Action(act, *args, **kw): - """A factory for action objects.""" - # 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 - other objects (Builders, Executors, etc.) This provides the - common methods for manipulating and combining those actions.""" - - def __eq__(self, other): - return self.__dict__ == other - - def no_batch_key(self, env, target, source): - return None - - batch_key = no_batch_key - - def genstring(self, target, source, env): - return str(self) - - def get_contents(self, target, source, env): - result = self.get_presig(target, source, env) - - if not isinstance(result,(bytes, bytearray)): - result = bytearray(result, 'utf-8') - else: - # Make a copy and put in bytearray, without this the contents returned by get_presig - # can be changed by the logic below, appending with each call and causing very - # hard to track down issues... - result = bytearray(result) - - # At this point everything should be a bytearray - - # 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.get_varlist(target, source, env) - if is_String(vl): vl = (vl,) - for v in vl: - # do the subst this way to ignore $(...$) parts: - if isinstance(result, bytearray): - result.extend(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source))) - else: - raise Exception("WE SHOULD NEVER GET HERE result should be bytearray not:%s"%type(result)) - # result.append(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source))) - - - if isinstance(result, (bytes,bytearray)): - return result - else: - raise Exception("WE SHOULD NEVER GET HERE - #2 result should be bytearray not:%s" % type(result)) - # return b''.join(result) - - def __add__(self, other): - return _actionAppend(self, other) - - def __radd__(self, other): - return _actionAppend(other, self) - - def presub_lines(self, env): - # CommandGeneratorAction needs a real environment - # in order to return the proper string here, since - # it may call LazyAction, which looks up a key - # in that env. So we temporarily remember the env here, - # and CommandGeneratorAction will use this env - # when it calls its _generate method. - self.presub_env = env - lines = str(self).split('\n') - self.presub_env = None # don't need this any more - return lines - - def get_varlist(self, target, source, env, executor=None): - return self.varlist - - def get_targets(self, env, executor): - """ - Returns the type of targets ($TARGETS, $CHANGED_TARGETS) used - by this action. - """ - return self.targets - - -class _ActionAction(ActionBase): - """Base class for actions that create output objects.""" - def __init__(self, cmdstr=_null, strfunction=_null, varlist=(), - presub=_null, chdir=None, exitstatfunc=None, - batch_key=None, targets='$TARGETS', - **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: - exitstatfunc = default_exitstatfunc - self.exitstatfunc = exitstatfunc - - self.targets = targets - - if batch_key: - if not callable(batch_key): - # They have set batch_key, but not to their own - # callable. The default behavior here will batch - # *all* targets+sources using this action, separated - # for each construction environment. - def default_batch_key(self, env, target, source): - return (id(self), id(env)) - batch_key = default_batch_key - SCons.Util.AddMethod(self, batch_key, 'batch_key') - - def print_cmd_line(self, s, target, source, env): - """ - In python 3, and in some of our tests, sys.stdout is - a String io object, and it takes unicode strings only - This code assumes s is a regular string. - """ - sys.stdout.write(s + "\n") - - def __call__(self, target, source, env, - exitstatfunc=_null, - presub=_null, - show=_null, - execute=_null, - chdir=_null, - executor=None): - if not is_List(target): - target = [target] - if not is_List(source): - source = [source] - - if presub is _null: - presub = self.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 - save_cwd = None - if chdir: - save_cwd = os.getcwd() - try: - chdir = str(chdir.get_abspath()) - except AttributeError: - if not is_String(chdir): - if executor: - chdir = str(executor.batches[0].targets[0].dir) - else: - chdir = str(target[0].dir) - if presub: - if executor: - target = executor.get_all_targets() - source = executor.get_all_sources() - t = ' and '.join(map(str, target)) - l = '\n '.join(self.presub_lines(env)) - out = "Building %s with action:\n %s\n" % (t, l) - sys.stdout.write(out) - cmd = None - if show and self.strfunction: - if executor: - target = executor.get_all_targets() - source = executor.get_all_sources() - try: - cmd = self.strfunction(target, source, env, executor) - except TypeError: - cmd = self.strfunction(target, source, env) - if cmd: - if chdir: - cmd = ('os.chdir(%s)\n' % repr(chdir)) + cmd - try: - get = env.get - except AttributeError: - print_func = self.print_cmd_line - else: - print_func = get('PRINT_CMD_LINE_FUNC') - if not print_func: - print_func = self.print_cmd_line - print_func(cmd, target, source, env) - stat = 0 - if execute: - if chdir: - os.chdir(chdir) - try: - stat = self.execute(target, source, env, executor=executor) - if isinstance(stat, SCons.Errors.BuildError): - s = exitstatfunc(stat.status) - if s: - stat.status = s - else: - stat = s - else: - stat = exitstatfunc(stat) - finally: - if save_cwd: - os.chdir(save_cwd) - if cmd and save_cwd: - print_func('os.chdir(%s)' % repr(save_cwd), target, source, env) - - return stat - - -def _string_from_cmd_list(cmd_list): - """Takes a list of command line arguments and returns a pretty - representation for printing.""" - cl = [] - for arg in map(str, cmd_list): - if ' ' in arg or '\t' in arg: - arg = '"' + arg + '"' - cl.append(arg) - return ' '.join(cl) - -default_ENV = None - - -def get_default_ENV(env): - """ - 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. - """ - 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 - - -def _subproc(scons_env, cmd, error='ignore', **kw): - """Wrapper for subprocess which pulls from construction env. - - Use for calls to subprocess which need to interpolate values from - an SCons construction environment into the environment passed to - subprocess. Adds an an error-handling argument. Adds ability - to specify std{in,out,err} with "'devnull'" tag. - """ - # TODO: just uses subprocess.DEVNULL now, we can drop the "devnull" - # string now - it is a holdover from Py2, which didn't have DEVNULL. - for stream in 'stdin', 'stdout', 'stderr': - io = kw.get(stream) - if is_String(io) and io == 'devnull': - kw[stream] = DEVNULL - - # Figure out what shell environment to use - ENV = kw.get('env', None) - if ENV is None: ENV = get_default_ENV(scons_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] = os.pathsep.join(map(str, value)) - 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: - pobj = subprocess.Popen(cmd, **kw) - except EnvironmentError as 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, input=None): return ('', '') - def wait(self): return -self.exception.errno - stdin = None - class f: - def read(self): return '' - def readline(self): return '' - def __iter__(self): return iter(()) - stdout = stderr = f() - pobj = dummyPopen(e) - finally: - # clean up open file handles stored in parent's kw - for k, v in kw.items(): - if inspect.ismethod(getattr(v, 'close', None)): - v.close() - - return pobj - - -class CommandAction(_ActionAction): - """Class for command-execution actions.""" - 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 - # execute. Only a single command should be executed by this - # object; lists of commands should be handled by embedding - # these objects in a ListAction object (which the Action() - # factory above does). cmd will be passed to - # Environment.subst_list() for substituting environment - # variables. - if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.CommandAction') - - _ActionAction.__init__(self, **kw) - if is_List(cmd): - if [c for c in cmd if is_List(c)]: - raise TypeError("CommandAction should be given only " - "a single command") - self.cmd_list = cmd - - def __str__(self): - if is_List(self.cmd_list): - return ' '.join(map(str, self.cmd_list)) - return str(self.cmd_list) - - def process(self, target, source, env, executor=None): - if executor: - result = env.subst_list(self.cmd_list, 0, executor=executor) - else: - result = env.subst_list(self.cmd_list, 0, target, source) - silent = None - ignore = None - while True: - try: c = result[0][0][0] - except IndexError: c = None - if c == '@': silent = 1 - elif c == '-': ignore = 1 - else: break - result[0][0] = result[0][0][1:] - try: - if not result[0][0]: - result[0] = result[0][1:] - except IndexError: - pass - return result, ignore, silent - - def strfunction(self, target, source, env, executor=None): - if self.cmdstr is None: - return None - if self.cmdstr is not _null: - from SCons.Subst import SUBST_RAW - if executor: - c = env.subst(self.cmdstr, SUBST_RAW, executor=executor) - else: - c = env.subst(self.cmdstr, SUBST_RAW, target, source) - if c: - return c - cmd_list, ignore, silent = self.process(target, source, env, executor) - if silent: - return '' - return _string_from_cmd_list(cmd_list[0]) - - def execute(self, target, source, env, executor=None): - """Execute a command action. - - This will handle lists of commands as well as individual commands, - because construction variable substitution may turn a single - "command" into a list. This means that this class can actually - handle lists of commands, even though that's not how we use it - externally. - """ - escape_list = SCons.Subst.escape_list - flatten_sequence = SCons.Util.flatten_sequence - - try: - shell = env['SHELL'] - except KeyError: - raise SCons.Errors.UserError('Missing SHELL construction variable.') - - try: - spawn = env['SPAWN'] - except KeyError: - raise SCons.Errors.UserError('Missing SPAWN construction variable.') - else: - if is_String(spawn): - spawn = env.subst(spawn, raw=1, conv=lambda x: x) - - escape = env.get('ESCAPE', lambda x: x) - - ENV = get_default_ENV(env) - - # Ensure that the ENV values are all strings: - for key, value in ENV.items(): - if not is_String(value): - 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 = flatten_sequence(value) - ENV[key] = os.pathsep.join(map(str, value)) - else: - # 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: - ENV[key] = str(value) - - if executor: - target = executor.get_all_targets() - source = executor.get_all_sources() - cmd_list, ignore, silent = self.process(target, list(map(rfile, source)), env, executor) - - # Use len() to filter out any "command" that's zero-length. - for cmd_line in filter(len, cmd_list): - # Escape the command line for the interpreter we are using. - cmd_line = escape_list(cmd_line, escape) - result = spawn(shell, escape, cmd_line[0], cmd_line, ENV) - if not ignore and result: - msg = "Error %s" % result - return SCons.Errors.BuildError(errstr=msg, - status=result, - action=self, - command=cmd_line) - return 0 - - def get_presig(self, target, source, env, executor=None): - """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. - """ - from SCons.Subst import SUBST_SIG - cmd = self.cmd_list - if is_List(cmd): - cmd = ' '.join(map(str, cmd)) - else: - cmd = str(cmd) - if executor: - return env.subst_target_source(cmd, SUBST_SIG, executor=executor) - else: - return env.subst_target_source(cmd, SUBST_SIG, target, source) - - def get_implicit_deps(self, target, source, env, executor=None): - """Return the implicit dependencies of this action's command line.""" - icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True) - if is_String(icd) and icd[:1] == '$': - icd = env.subst(icd) - - if not icd or str(icd).lower in ('0', 'none', 'false', 'no', 'off'): - return [] - - try: - icd_int = int(icd) - except ValueError: - icd_int = None - - if (icd_int and icd_int > 1) or icd == 'all': - # An integer value greater than 1 specifies the number of entries - # to scan. "all" means to scan all. - return self._get_implicit_deps_heavyweight(target, source, env, executor, icd_int) - else: - # Everything else (usually 1 or True) means that we want - # lightweight dependency scanning. - return self._get_implicit_deps_lightweight(target, source, env, executor) - - def _get_implicit_deps_lightweight(self, target, source, env, executor): - """ - Lightweight dependency scanning involves only scanning the first entry - in an action string, even if it contains &&. - """ - from SCons.Subst import SUBST_SIG - if executor: - cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, executor=executor) - else: - cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, target, source) - res = [] - for cmd_line in cmd_list: - if cmd_line: - d = str(cmd_line[0]) - m = strip_quotes.match(d) - if m: - d = m.group(1) - d = env.WhereIs(d) - if d: - res.append(env.fs.File(d)) - return res - - def _get_implicit_deps_heavyweight(self, target, source, env, executor, - icd_int): - """ - Heavyweight dependency scanning involves scanning more than just the - first entry in an action string. The exact behavior depends on the - value of icd_int. Only files are taken as implicit dependencies; - directories are ignored. - - If icd_int is an integer value, it specifies the number of entries to - scan for implicit dependencies. Action strings are also scanned after - a &&. So for example, if icd_int=2 and the action string is - "cd && $PYTHON $SCRIPT_PATH ", the implicit - dependencies would be the path to the python binary and the path to the - script. - - If icd_int is None, all entries are scanned for implicit dependencies. - """ - - # Avoid circular and duplicate dependencies by not providing source, - # target, or executor to subst_list. This causes references to - # $SOURCES, $TARGETS, and all related variables to disappear. - from SCons.Subst import SUBST_SIG - cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, conv=lambda x: x) - res = [] - - for cmd_line in cmd_list: - if cmd_line: - entry_count = 0 - for entry in cmd_line: - d = str(entry) - if ((icd_int is None or entry_count < icd_int) and - not d.startswith(('&', '-', '/') if os.name == 'nt' - else ('&', '-'))): - m = strip_quotes.match(d) - if m: - d = m.group(1) - - if d: - # Resolve the first entry in the command string using - # PATH, which env.WhereIs() looks in. - # For now, only match files, not directories. - p = os.path.abspath(d) if os.path.isfile(d) else None - if not p and entry_count == 0: - p = env.WhereIs(d) - - if p: - res.append(env.fs.File(p)) - - entry_count = entry_count + 1 - else: - entry_count = 0 if d == '&&' else entry_count + 1 - - # Despite not providing source and target to env.subst() above, we - # can still end up with sources in this list. For example, files in - # LIBS will still resolve in env.subst(). This won't result in - # circular dependencies, but it causes problems with cache signatures - # changing between full and incremental builds. - return [r for r in res if r not in target and r not in source] - - -class CommandGeneratorAction(ActionBase): - """Class for command-generator actions.""" - def __init__(self, generator, kw): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.CommandGeneratorAction') - self.generator = generator - self.gen_kw = kw - self.varlist = kw.get('varlist', ()) - self.targets = kw.get('targets', '$TARGETS') - - def _generate(self, target, source, env, for_signature, executor=None): - # ensure that target is a list, to make it easier to write - # generator functions: - if not is_List(target): - target = [target] - - if executor: - target = executor.get_all_targets() - source = executor.get_all_sources() - ret = self.generator(target=target, - source=source, - env=env, - for_signature=for_signature) - gen_cmd = 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 - - def __str__(self): - try: - env = self.presub_env - except AttributeError: - env = None - if env is None: - env = SCons.Defaults.DefaultEnvironment() - act = self._generate([], [], env, 1) - return str(act) - - def batch_key(self, env, target, source): - return self._generate(target, source, env, 1).batch_key(env, target, source) - - def genstring(self, target, source, env, executor=None): - return self._generate(target, source, env, 1, executor).genstring(target, source, env) - - def __call__(self, target, source, env, exitstatfunc=_null, presub=_null, - show=_null, execute=_null, chdir=_null, executor=None): - act = self._generate(target, source, env, 0, executor) - if act is None: - raise SCons.Errors.UserError( - "While building `%s': " - "Cannot deduce file extension from source files: %s" - % (repr(list(map(str, target))), repr(list(map(str, source)))) - ) - return act( - target, source, env, exitstatfunc, presub, show, execute, chdir, executor - ) - - def get_presig(self, target, source, env, executor=None): - """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, executor).get_presig(target, source, env) - - def get_implicit_deps(self, target, source, env, executor=None): - return self._generate(target, source, env, 1, executor).get_implicit_deps(target, source, env) - - def get_varlist(self, target, source, env, executor=None): - return self._generate(target, source, env, 1, executor).get_varlist(target, source, env, executor) - - def get_targets(self, env, executor): - return self._generate(None, None, env, 1, executor).get_targets(env, executor) - - -class LazyAction(CommandGeneratorAction, CommandAction): - """ - A LazyAction is a kind of hybrid generator and command action for - strings of the form "$VAR". These strings normally expand to other - strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also - want to be able to replace them with functions in the construction - environment. Consequently, we want lazy evaluation and creation of - an Action in the case of the function, but that's overkill in the more - normal case of expansion to other strings. - - So we do this with a subclass that's both a generator *and* - a command action. The overridden methods all do a quick check - of the construction variable, and if it's a string we just call - the corresponding CommandAction method to do the heavy lifting. - If not, then we call the same-named CommandGeneratorAction method. - The CommandGeneratorAction methods work by using the overridden - _generate() method, that is, our own way of handling "generation" of - an action based on what's in the construction variable. - """ - - def __init__(self, var, kw): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.LazyAction') - CommandAction.__init__(self, '${'+var+'}', **kw) - self.var = SCons.Util.to_String(var) - self.gen_kw = kw - - def get_parent_class(self, env): - c = env.get(self.var) - if is_String(c) and '\n' not in c: - return CommandAction - return CommandGeneratorAction - - def _generate_cache(self, env): - if env: - c = env.get(self.var, '') - else: - c = '' - gen_cmd = 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 - - def _generate(self, target, source, env, for_signature, executor=None): - return self._generate_cache(env) - - def __call__(self, target, source, env, *args, **kw): - c = self.get_parent_class(env) - return c.__call__(self, target, source, env, *args, **kw) - - def get_presig(self, target, source, env): - c = self.get_parent_class(env) - return c.get_presig(self, target, source, env) - - def get_varlist(self, target, source, env, executor=None): - c = self.get_parent_class(env) - return c.get_varlist(self, target, source, env, executor) - - -class FunctionAction(_ActionAction): - """Class for Python function actions.""" - - def __init__(self, execfunction, kw): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.FunctionAction') - - self.execfunction = execfunction - 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) - - _ActionAction.__init__(self, **kw) - - def function_name(self): - try: - return self.execfunction.__name__ - except AttributeError: - try: - return self.execfunction.__class__.__name__ - except AttributeError: - return "unknown_python_function" - - def strfunction(self, target, source, env, executor=None): - if self.cmdstr is None: - return None - if self.cmdstr is not _null: - from SCons.Subst import SUBST_RAW - if executor: - c = env.subst(self.cmdstr, SUBST_RAW, executor=executor) - else: - c = env.subst(self.cmdstr, SUBST_RAW, target, source) - if c: - return c - - def array(a): - def quote(s): - try: - str_for_display = s.str_for_display - except AttributeError: - s = repr(s) - else: - s = str_for_display() - return s - return '[' + ", ".join(map(quote, a)) + ']' - try: - strfunc = self.execfunction.strfunction - except AttributeError: - pass - else: - if strfunc is None: - return None - if callable(strfunc): - return strfunc(target, source, env) - name = self.function_name() - tstr = array(target) - sstr = array(source) - return "%s(%s, %s)" % (name, tstr, sstr) - - def __str__(self): - name = self.function_name() - if name == 'ActionCaller': - return str(self.execfunction) - return "%s(target, source, env)" % name - - def execute(self, target, source, env, executor=None): - exc_info = (None,None,None) - try: - if executor: - target = executor.get_all_targets() - source = executor.get_all_sources() - rsources = list(map(rfile, source)) - try: - result = self.execfunction(target=target, source=rsources, env=env) - except KeyboardInterrupt as e: - raise - except SystemExit as e: - raise - except Exception as 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 - try: - result.command=self.strfunction(target, source, env, executor) - except TypeError: - 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 [] - -class ListAction(ActionBase): - """Class for lists of other actions.""" - def __init__(self, actionlist): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.ListAction') - def list_of_actions(x): - if isinstance(x, ActionBase): - return x - return Action(x) - self.list = list(map(list_of_actions, actionlist)) - # our children will have had any varlist - # applied; we don't need to do it again - self.varlist = () - self.targets = '$TARGETS' - - def genstring(self, target, source, env): - return '\n'.join([a.genstring(target, source, env) for a in self.list]) - - def __str__(self): - return '\n'.join(map(str, self.list)) - - def presub_lines(self, env): - return SCons.Util.flatten_sequence( - [a.presub_lines(env) for a in 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. - """ - return b"".join([bytes(x.get_contents(target, source, env)) for x in self.list]) - - def __call__(self, target, source, env, exitstatfunc=_null, presub=_null, - show=_null, execute=_null, chdir=_null, executor=None): - if executor: - target = executor.get_all_targets() - source = executor.get_all_sources() - for act in self.list: - stat = act(target, source, env, exitstatfunc, presub, - show, execute, chdir, executor) - if stat: - return stat - return 0 - - def get_implicit_deps(self, target, source, env): - result = [] - for act in self.list: - result.extend(act.get_implicit_deps(target, source, env)) - return result - - def get_varlist(self, target, source, env, executor=None): - result = OrderedDict() - for act in self.list: - for var in act.get_varlist(target, source, env, executor): - result[var] = True - return list(result.keys()) - - -class ActionCaller: - """A class for delaying calling an Action function with specific - (positional and keyword) arguments until the Action is actually - executed. - - This class looks to the rest of the world like a normal Action object, - but what it's really doing is hanging on to the arguments until we - have a target, source and env to use for the expansion. - """ - def __init__(self, parent, args, kw): - self.parent = parent - self.args = args - self.kw = kw - - def get_contents(self, target, source, env): - actfunc = self.parent.actfunc - try: - # "self.actfunc" is a function. - contents = actfunc.__code__.co_code - except AttributeError: - # "self.actfunc" is a callable object. - try: - contents = actfunc.__call__.__func__.__code__.co_code - except AttributeError: - # No __call__() method, so it might be a builtin - # or something like that. Do the best we can. - contents = repr(actfunc) - - 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 is_String(s): - return env.subst(s, 1, target, source) - return self.parent.convert(s) - - def subst_args(self, target, source, env): - return [self.subst(x, target, source, env) for x in self.args] - - def subst_kw(self, target, source, env): - kw = {} - for key in list(self.kw.keys()): - kw[key] = self.subst(self.kw[key], target, source, env) - return kw - - def __call__(self, target, source, env, executor=None): - args = self.subst_args(target, source, env) - kw = self.subst_kw(target, source, env) - return 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) - return self.parent.strfunc(*args, **kw) - - def __str__(self): - return self.parent.strfunc(*self.args, **self.kw) - - -class ActionFactory: - """A factory class that will wrap up an arbitrary function - as an SCons-executable Action object. - - The real heavy lifting here is done by the ActionCaller class. - We just collect the (positional and keyword) arguments that we're - called with and give them to the ActionCaller object we create, - so it can hang onto them until it needs them. - """ - def __init__(self, actfunc, strfunc, convert=lambda x: x): - 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) - return action - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Builder.py b/scons/scons-local-4.1.0/SCons/Builder.py deleted file mode 100644 index 34bd33083..000000000 --- a/scons/scons-local-4.1.0/SCons/Builder.py +++ /dev/null @@ -1,893 +0,0 @@ -# MIT License -# -# Copyright 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.Builder - -Builder object subsystem. - -A Builder object is a callable that encapsulates information about how -to execute actions to create a target Node (file) from source Nodes -(files), and how to create those dependencies for tracking. - -The main entry point here is the Builder() factory method. This provides -a procedural interface that creates the right underlying Builder object -based on the keyword arguments supplied and the types of the arguments. - -The goal is for this external interface to be simple enough that the -vast majority of users can create new Builders as necessary to support -building new types of files in their configurations, without having to -dive any deeper into this subsystem. - -The base class here is BuilderBase. This is a concrete base class which -does, in fact, represent the Builder objects that we (or users) create. - -There is also a proxy that looks like a Builder: - - CompositeBuilder - - This proxies for a Builder with an action that is actually a - dictionary that knows how to map file suffixes to a specific - action. This is so that we can invoke different actions - (compilers, compile options) for different flavors of source - files. - -Builders and their proxies have the following public interface methods -used by other modules: - - - __call__() - THE public interface. Calling a Builder object (with the - use of internal helper methods) sets up the target and source - dependencies, appropriate mapping to a specific action, and the - environment manipulation necessary for overridden construction - variable. This also takes care of warning about possible mistakes - in keyword arguments. - - - add_emitter() - Adds an emitter for a specific file suffix, used by some Tool - modules to specify that (for example) a yacc invocation on a .y - can create a .h *and* a .c file. - - - add_action() - Adds an action for a specific file suffix, heavily used by - Tool modules to add their specific action(s) for turning - a source file into an object file to the global static - and shared object file Builders. - -There are the following methods for internal use within this module: - - - _execute() - The internal method that handles the heavily lifting when a - Builder is called. This is used so that the __call__() methods - can set up warning about possible mistakes in keyword-argument - overrides, and *then* execute all of the steps necessary so that - the warnings only occur once. - - - get_name() - Returns the Builder's name within a specific Environment, - primarily used to try to return helpful information in error - messages. - - - adjust_suffix() - - get_prefix() - - get_suffix() - - get_src_suffix() - - set_src_suffix() - Miscellaneous stuff for handling the prefix and suffix - manipulation we use in turning source file names into target - file names. - -""" - -from collections import UserDict, UserList - -import SCons.Action -import SCons.Debug -from SCons.Debug import logInstanceCreation -from SCons.Errors import InternalError, UserError -import SCons.Executor -import SCons.Memoize -import SCons.Util -import SCons.Warnings - -class _Null: - pass - -_null = _Null - -def match_splitext(path, suffixes = []): - if suffixes: - matchsuf = [S for S in suffixes if path[-len(S):] == S] - if matchsuf: - suf = max([(len(_f),_f) for _f in matchsuf])[1] - return [path[:-len(suf)], path[-len(suf):]] - return SCons.Util.splitext(path) - -class DictCmdGenerator(SCons.Util.Selector): - """This is a callable class that can be used as a - command generator function. It holds on to a dictionary - mapping file suffixes to Actions. It uses that dictionary - to return the proper action based on the file suffix of - the source file.""" - - def __init__(self, dict=None, source_ext_match=1): - SCons.Util.Selector.__init__(self, dict) - self.source_ext_match = source_ext_match - - def src_suffixes(self): - return list(self.keys()) - - def add_action(self, suffix, action): - """Add a suffix-action pair to the mapping. - """ - self[suffix] = action - - def __call__(self, target, source, env, for_signature): - if not source: - return [] - - if self.source_ext_match: - suffixes = self.src_suffixes() - ext = None - for src in map(str, source): - my_ext = match_splitext(src, suffixes)[1] - if ext and my_ext != ext: - raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s" - % (repr(list(map(str, target))), src, ext, my_ext)) - ext = my_ext - else: - ext = match_splitext(str(source[0]), self.src_suffixes())[1] - - if not ext: - #return ext - raise UserError("While building `%s': " - "Cannot deduce file extension from source files: %s" - % (repr(list(map(str, target))), repr(list(map(str, source))))) - - try: - ret = SCons.Util.Selector.__call__(self, env, source, ext) - except KeyError as e: - raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e.args[0], e.args[1], e.args[2])) - if ret is None: - raise UserError("While building `%s' from `%s': Don't know how to build from a source file with suffix `%s'. Expected a suffix in this list: %s." % \ - (repr(list(map(str, target))), repr(list(map(str, source))), ext, repr(list(self.keys())))) - return ret - -class CallableSelector(SCons.Util.Selector): - """A callable dictionary that will, in turn, call the value it - finds if it can.""" - def __call__(self, env, source): - value = SCons.Util.Selector.__call__(self, env, source) - if callable(value): - value = value(env, source) - return value - -class DictEmitter(SCons.Util.Selector): - """A callable dictionary that maps file suffixes to emitters. - When called, it finds the right emitter in its dictionary for the - suffix of the first source file, and calls that emitter to get the - right lists of targets and sources to return. If there's no emitter - for the suffix in its dictionary, the original target and source are - returned. - """ - def __call__(self, target, source, env): - emitter = SCons.Util.Selector.__call__(self, env, source) - if emitter: - target, source = emitter(target, source, env) - return (target, source) - -class ListEmitter(UserList): - """A callable list of emitters that calls each in sequence, - returning the result. - """ - def __call__(self, target, source, env): - for e in self.data: - target, source = e(target, source, env) - return (target, source) - -# These are a common errors when calling a Builder; -# they are similar to the 'target' and 'source' keyword args to builders, -# so we issue warnings when we see them. The warnings can, of course, -# be disabled. -misleading_keywords = { - 'targets' : 'target', - 'sources' : 'source', -} - -class OverrideWarner(UserDict): - """A class for warning about keyword arguments that we use as - overrides in a Builder call. - - This class exists to handle the fact that a single Builder call - can actually invoke multiple builders. This class only emits the - warnings once, no matter how many Builders are invoked. - """ - def __init__(self, dict): - UserDict.__init__(self, dict) - if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.OverrideWarner') - self.already_warned = None - def warn(self): - if self.already_warned: - return - for k in self.keys(): - if k in misleading_keywords: - alt = misleading_keywords[k] - msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k) - SCons.Warnings.warn(SCons.Warnings.MisleadingKeywordsWarning, msg) - self.already_warned = 1 - -def Builder(**kw): - """A factory for builder objects.""" - composite = None - if 'generator' in kw: - if 'action' in kw: - raise UserError("You must not specify both an action and a generator.") - kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator'], {}) - del kw['generator'] - elif 'action' in kw: - source_ext_match = kw.get('source_ext_match', 1) - if 'source_ext_match' in 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['src_suffix'] = composite.src_suffixes() - else: - kw['action'] = SCons.Action.Action(kw['action']) - - if 'emitter' in kw: - emitter = kw['emitter'] - if SCons.Util.is_String(emitter): - # This allows users to pass in an Environment - # variable reference (like "$FOO") as an emitter. - # We will look in that Environment variable for - # a callable to use as the actual emitter. - var = SCons.Util.get_environment_var(emitter) - if not var: - raise UserError("Supplied emitter '%s' does not appear to refer to an Environment variable" % emitter) - kw['emitter'] = EmitterProxy(var) - elif SCons.Util.is_Dict(emitter): - kw['emitter'] = DictEmitter(emitter) - elif SCons.Util.is_List(emitter): - kw['emitter'] = ListEmitter(emitter) - - result = BuilderBase(**kw) - - if composite is not None: - result = CompositeBuilder(result, composite) - - return result - -def _node_errors(builder, env, tlist, slist): - """Validate that the lists of target and source nodes are - legal for this builder and environment. Raise errors or - issue warnings as appropriate. - """ - - # First, figure out if there are any errors in the way the targets - # were specified. - for t in tlist: - if t.side_effect: - raise UserError("Multiple ways to build the same target were specified for: %s" % t) - if t.has_explicit_builder(): - # Check for errors when the environments are different - # No error if environments are the same Environment instance - if (t.env is not None and t.env is not env and - # Check OverrideEnvironment case - no error if wrapped Environments - # are the same instance, and overrides lists match - not (getattr(t.env, '__subject', 0) is getattr(env, '__subject', 1) and - getattr(t.env, 'overrides', 0) == getattr(env, 'overrides', 1) and - not builder.multi)): - action = t.builder.action - t_contents = t.builder.action.get_contents(tlist, slist, t.env) - contents = builder.action.get_contents(tlist, slist, env) - - if t_contents == contents: - msg = "Two different environments were specified for target %s,\n\tbut they appear to have the same action: %s" % (t, action.genstring(tlist, slist, t.env)) - SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning, msg) - else: - try: - msg = "Two environments with different actions were specified for the same target: %s\n(action 1: %s)\n(action 2: %s)" % (t,t_contents.decode('utf-8'),contents.decode('utf-8')) - except UnicodeDecodeError: - msg = "Two environments with different actions were specified for the same target: %s"%t - raise UserError(msg) - if builder.multi: - if t.builder != builder: - msg = "Two different builders (%s and %s) were specified for the same target: %s" % (t.builder.get_name(env), builder.get_name(env), t) - raise UserError(msg) - # TODO(batch): list constructed each time! - if t.get_executor().get_all_targets() != tlist: - msg = "Two different target lists have a target in common: %s (from %s and from %s)" % (t, list(map(str, t.get_executor().get_all_targets())), list(map(str, tlist))) - raise UserError(msg) - elif t.sources != slist: - msg = "Multiple ways to build the same target were specified for: %s (from %s and from %s)" % (t, list(map(str, t.sources)), list(map(str, slist))) - raise UserError(msg) - - if builder.single_source: - if len(slist) > 1: - raise UserError("More than one source given for single-source builder: targets=%s sources=%s" % (list(map(str,tlist)), list(map(str,slist)))) - -class EmitterProxy: - """This is a callable class that can act as a - Builder emitter. It holds on to a string that - is a key into an Environment dictionary, and will - look there at actual build time to see if it holds - a callable. If so, we will call that as the actual - emitter.""" - def __init__(self, var): - self.var = SCons.Util.to_String(var) - - def __call__(self, target, source, env): - emitter = self.var - - # Recursively substitute the variable. - # We can't use env.subst() because it deals only - # in strings. Maybe we should change that? - while SCons.Util.is_String(emitter) and emitter in env: - emitter = env[emitter] - if callable(emitter): - target, source = emitter(target, source, env) - elif SCons.Util.is_List(emitter): - for e in emitter: - target, source = e(target, source, env) - - return (target, source) - - - def __eq__(self, other): - return self.var == other.var - - def __lt__(self, other): - return self.var < other.var - -class BuilderBase: - """Base class for Builders, objects that create output - nodes (files) from input nodes (files). - """ - - def __init__(self, action = None, - prefix = '', - suffix = '', - src_suffix = '', - target_factory = None, - source_factory = None, - target_scanner = None, - source_scanner = None, - emitter = None, - multi = 0, - env = None, - single_source = 0, - name = None, - chdir = _null, - is_explicit = 1, - src_builder = None, - ensure_suffix = False, - **overrides): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.BuilderBase') - self._memo = {} - self.action = action - self.multi = multi - if SCons.Util.is_Dict(prefix): - prefix = CallableSelector(prefix) - self.prefix = prefix - if SCons.Util.is_Dict(suffix): - suffix = CallableSelector(suffix) - self.env = env - self.single_source = single_source - if 'overrides' in overrides: - msg = "The \"overrides\" keyword to Builder() creation has been removed;\n" +\ - "\tspecify the items as keyword arguments to the Builder() call instead." - raise TypeError(msg) - if 'scanner' in overrides: - msg = "The \"scanner\" keyword to Builder() creation has been removed;\n" +\ - "\tuse: source_scanner or target_scanner as appropriate." - raise TypeError(msg) - self.overrides = overrides - - self.set_suffix(suffix) - self.set_src_suffix(src_suffix) - self.ensure_suffix = ensure_suffix - - self.target_factory = target_factory - self.source_factory = source_factory - self.target_scanner = target_scanner - self.source_scanner = source_scanner - - self.emitter = emitter - - # Optional Builder name should only be used for Builders - # that don't get attached to construction environments. - if name: - self.name = name - self.executor_kw = {} - if chdir is not _null: - self.executor_kw['chdir'] = chdir - self.is_explicit = is_explicit - - if src_builder is None: - src_builder = [] - elif not SCons.Util.is_List(src_builder): - src_builder = [ src_builder ] - self.src_builder = src_builder - - def __bool__(self): - raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead") - - def get_name(self, env): - """Attempts to get the name of the Builder. - - Look at the BUILDERS variable of env, expecting it to be a - dictionary containing this Builder, and return the key of the - dictionary. If there's no key, then return a directly-configured - name (if there is one) or the name of the class (by default).""" - - try: - index = list(env['BUILDERS'].values()).index(self) - return list(env['BUILDERS'].keys())[index] - except (AttributeError, KeyError, TypeError, ValueError): - try: - return self.name - except AttributeError: - return str(self.__class__) - - def __eq__(self, other): - return self.__dict__ == other.__dict__ - - def splitext(self, path, env=None): - if not env: - env = self.env - if env: - suffixes = self.src_suffixes(env) - else: - suffixes = [] - return match_splitext(path, suffixes) - - def _adjustixes(self, files, pre, suf, ensure_suffix=False): - if not files: - return [] - result = [] - if not SCons.Util.is_List(files): - files = [files] - - for f in files: - if SCons.Util.is_String(f): - f = SCons.Util.adjustixes(f, pre, suf, ensure_suffix) - result.append(f) - return result - - def _create_nodes(self, env, target = None, source = None): - """Create and return lists of target and source nodes. - """ - src_suf = self.get_src_suffix(env) - - target_factory = env.get_factory(self.target_factory) - source_factory = env.get_factory(self.source_factory) - - source = self._adjustixes(source, None, src_suf) - slist = env.arg2nodes(source, source_factory) - - pre = self.get_prefix(env, slist) - suf = self.get_suffix(env, slist) - - if target is None: - try: - t_from_s = slist[0].target_from_source - except AttributeError: - raise UserError("Do not know how to create a target from source `%s'" % slist[0]) - except IndexError: - tlist = [] - else: - splitext = lambda S: self.splitext(S,env) - tlist = [ t_from_s(pre, suf, splitext) ] - else: - # orig_target = target - target = self._adjustixes(target, pre, suf, self.ensure_suffix) - 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 - # being called *from* a builder invocation, the new targets - # don't yet have a builder set on them and will look like - # source files. Fool the emitter's str() calls by setting - # up a temporary builder on the new targets. - new_targets = [] - for t in tlist: - if not t.is_derived(): - t.builder_set(self) - new_targets.append(t) - - orig_tlist = tlist[:] - orig_slist = slist[:] - - target, source = self.emitter(target=tlist, source=slist, env=env) - - # Now delete the temporary builders that we attached to any - # new targets, so that _node_errors() doesn't do weird stuff - # to them because it thinks they already have builders. - for t in new_targets: - if t.builder is self: - # Only delete the temporary builder if the emitter - # didn't change it on us. - t.builder_set(None) - - # Have to call arg2nodes yet again, since it is legal for - # emitters to spit out strings as well as Node instances. - tlist = env.arg2nodes(target, target_factory, - target=orig_tlist, source=orig_slist) - slist = env.arg2nodes(source, source_factory, - target=orig_tlist, source=orig_slist) - - return tlist, slist - - def _execute(self, env, target, source, overwarn={}, executor_kw={}): - # We now assume that target and source are lists or None. - if self.src_builder: - source = self.src_builder_sources(env, source, overwarn) - - if self.single_source and len(source) > 1 and target is None: - result = [] - if target is None: target = [None]*len(source) - for tgt, src in zip(target, source): - if tgt is not None: - tgt = [tgt] - if src is not None: - src = [src] - result.extend(self._execute(env, tgt, src, overwarn)) - return SCons.Node.NodeList(result) - - overwarn.warn() - - tlist, slist = self._create_nodes(env, target, source) - - # If there is more than one target ensure that if we need to reset - # the implicit list to new scan of dependency all targets implicit lists - # are cleared. (SCons GH Issue #2811 and MongoDB SERVER-33111) - if len(tlist) > 1: - for t in tlist: - t.target_peers = tlist - - # Check for errors with the specified target/source lists. - _node_errors(self, env, tlist, slist) - - # The targets are fine, so find or make the appropriate Executor to - # build this particular list of targets from this particular list of - # sources. - - executor = None - key = None - - if self.multi: - try: - executor = tlist[0].get_executor(create = 0) - except (AttributeError, IndexError): - pass - else: - executor.add_sources(slist) - - if executor is None: - if not self.action: - fmt = "Builder %s must have an action to build %s." - raise UserError(fmt % (self.get_name(env or self.env), - list(map(str,tlist)))) - key = self.action.batch_key(env or self.env, tlist, slist) - if key: - try: - executor = SCons.Executor.GetBatchExecutor(key) - except KeyError: - pass - else: - executor.add_batch(tlist, slist) - - if executor is None: - executor = SCons.Executor.Executor(self.action, env, [], - tlist, slist, executor_kw) - if key: - SCons.Executor.AddBatchExecutor(key, executor) - - # Now set up the relevant information in the target Nodes themselves. - for t in tlist: - t.cwd = env.fs.getcwd() - t.builder_set(self) - t.env_set(env) - t.add_source(slist) - t.set_executor(executor) - t.set_explicit(self.is_explicit) - - return SCons.Node.NodeList(tlist) - - def __call__(self, env, target=None, source=None, chdir=_null, **kw): - # We now assume that target and source are lists or None. - # The caller (typically Environment.BuilderWrapper) is - # responsible for converting any scalar values to lists. - if chdir is _null: - ekw = self.executor_kw - else: - ekw = self.executor_kw.copy() - ekw['chdir'] = chdir - if 'chdir' in ekw and SCons.Util.is_String(ekw['chdir']): - ekw['chdir'] = env.subst(ekw['chdir']) - if kw: - if 'srcdir' in kw: - def prependDirIfRelative(f, srcdir=kw['srcdir']): - import os.path - if SCons.Util.is_String(f) and not os.path.isabs(f): - f = os.path.join(srcdir, f) - return f - if not SCons.Util.is_List(source): - source = [source] - source = list(map(prependDirIfRelative, source)) - del kw['srcdir'] - if self.overrides: - env_kw = self.overrides.copy() - env_kw.update(kw) - else: - env_kw = kw - else: - env_kw = self.overrides - - # TODO if env_kw: then the following line. there's no purpose in calling if no overrides. - env = env.Override(env_kw) - return self._execute(env, target, source, OverrideWarner(kw), ekw) - - def adjust_suffix(self, suff): - if suff and not suff[0] in [ '.', '_', '$' ]: - return '.' + suff - return suff - - def get_prefix(self, env, sources=[]): - prefix = self.prefix - if callable(prefix): - prefix = prefix(env, sources) - return env.subst(prefix) - - def set_suffix(self, suffix): - if not callable(suffix): - suffix = self.adjust_suffix(suffix) - self.suffix = suffix - - def get_suffix(self, env, sources=[]): - suffix = self.suffix - if callable(suffix): - suffix = suffix(env, sources) - return env.subst(suffix) - - def set_src_suffix(self, src_suffix): - if not src_suffix: - src_suffix = [] - elif not SCons.Util.is_List(src_suffix): - src_suffix = [ src_suffix ] - self.src_suffix = [callable(suf) and suf or self.adjust_suffix(suf) for suf in src_suffix] - - def get_src_suffix(self, env): - """Get the first src_suffix in the list of src_suffixes.""" - ret = self.src_suffixes(env) - if not ret: - return '' - return ret[0] - - def add_emitter(self, suffix, emitter): - """Add a suffix-emitter mapping to this Builder. - - This assumes that emitter has been initialized with an - appropriate dictionary type, and will throw a TypeError if - not, so the caller is responsible for knowing that this is an - appropriate method to call for the Builder in question. - """ - self.emitter[suffix] = emitter - - def add_src_builder(self, builder): - """ - Add a new Builder to the list of src_builders. - - This requires wiping out cached values so that the computed - lists of source suffixes get re-calculated. - """ - self._memo = {} - self.src_builder.append(builder) - - def _get_sdict(self, env): - """ - Returns a dictionary mapping all of the source suffixes of all - src_builders of this Builder to the underlying Builder that - should be called first. - - This dictionary is used for each target specified, so we save a - lot of extra computation by memoizing it for each construction - environment. - - Note that this is re-computed each time, not cached, because there - might be changes to one of our source Builders (or one of their - source Builders, and so on, and so on...) that we can't "see." - - The underlying methods we call cache their computed values, - though, so we hope repeatedly aggregating them into a dictionary - like this won't be too big a hit. We may need to look for a - better way to do this if performance data show this has turned - into a significant bottleneck. - """ - sdict = {} - for bld in self.get_src_builders(env): - for suf in bld.src_suffixes(env): - sdict[suf] = bld - return sdict - - def src_builder_sources(self, env, source, overwarn={}): - sdict = self._get_sdict(env) - - src_suffixes = self.src_suffixes(env) - - lengths = list(set(map(len, src_suffixes))) - - def match_src_suffix(name, src_suffixes=src_suffixes, lengths=lengths): - node_suffixes = [name[-l:] for l in lengths] - for suf in src_suffixes: - if suf in node_suffixes: - return suf - return None - - result = [] - for s in SCons.Util.flatten(source): - if SCons.Util.is_String(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] - else: - match_suffix = match_src_suffix(s.name) - if match_suffix: - try: - bld = sdict[match_suffix] - except KeyError: - result.append(s) - else: - tlist = bld._execute(env, None, [s], overwarn) - # If the subsidiary Builder returned more than one - # target, then filter out any sources that this - # Builder isn't capable of building. - if len(tlist) > 1: - tlist = [t for t in tlist if match_src_suffix(t.name)] - result.extend(tlist) - else: - result.append(s) - - source_factory = env.get_factory(self.source_factory) - - return env.arg2nodes(result, source_factory) - - def _get_src_builders_key(self, env): - return id(env) - - @SCons.Memoize.CountDictCall(_get_src_builders_key) - def get_src_builders(self, env): - """ - Returns the list of source Builders for this Builder. - - This exists mainly to look up Builders referenced as - strings in the 'BUILDER' variable of the construction - environment and cache the result. - """ - memo_key = id(env) - try: - memo_dict = self._memo['get_src_builders'] - except KeyError: - memo_dict = {} - self._memo['get_src_builders'] = memo_dict - else: - try: - return memo_dict[memo_key] - except KeyError: - pass - - builders = [] - for bld in self.src_builder: - if SCons.Util.is_String(bld): - try: - bld = env['BUILDERS'][bld] - except KeyError: - continue - builders.append(bld) - - memo_dict[memo_key] = builders - return builders - - def _subst_src_suffixes_key(self, env): - return id(env) - - @SCons.Memoize.CountDictCall(_subst_src_suffixes_key) - def subst_src_suffixes(self, env): - """ - The suffix list may contain construction variable expansions, - so we have to evaluate the individual strings. To avoid doing - this over and over, we memoize the results for each construction - environment. - """ - memo_key = id(env) - try: - memo_dict = self._memo['subst_src_suffixes'] - except KeyError: - memo_dict = {} - self._memo['subst_src_suffixes'] = memo_dict - else: - try: - return memo_dict[memo_key] - except KeyError: - pass - suffixes = [env.subst(x) for x in self.src_suffix] - memo_dict[memo_key] = suffixes - return suffixes - - def src_suffixes(self, env): - """ - Returns the list of source suffixes for all src_builders of this - Builder. - - This is essentially a recursive descent of the src_builder "tree." - (This value isn't cached because there may be changes in a - src_builder many levels deep that we can't see.) - """ - sdict = {} - suffixes = self.subst_src_suffixes(env) - for s in suffixes: - sdict[s] = 1 - for builder in self.get_src_builders(env): - for s in builder.src_suffixes(env): - if s not in sdict: - sdict[s] = 1 - suffixes.append(s) - return suffixes - -class CompositeBuilder(SCons.Util.Proxy): - """A Builder Proxy whose main purpose is to always have - a DictCmdGenerator as its action, and to provide access - to the DictCmdGenerator's add_action() method. - """ - - def __init__(self, builder, cmdgen): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.CompositeBuilder') - SCons.Util.Proxy.__init__(self, builder) - - # cmdgen should always be an instance of DictCmdGenerator. - self.cmdgen = cmdgen - self.builder = builder - - __call__ = SCons.Util.Delegate('__call__') - - def add_action(self, suffix, action): - self.cmdgen.add_action(suffix, action) - self.set_src_suffix(self.cmdgen.src_suffixes()) - -def is_a_Builder(obj): - """"Returns True if the specified obj is one of our Builder classes. - - The test is complicated a bit by the fact that CompositeBuilder - is a proxy, not a subclass of BuilderBase. - """ - return (isinstance(obj, BuilderBase) - or isinstance(obj, CompositeBuilder) - or callable(obj)) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/CacheDir.py b/scons/scons-local-4.1.0/SCons/CacheDir.py deleted file mode 100644 index d0c7e5fd6..000000000 --- a/scons/scons-local-4.1.0/SCons/CacheDir.py +++ /dev/null @@ -1,294 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""CacheDir support -""" - -import atexit -import json -import os -import stat -import sys - -import SCons.Action -import SCons.Errors -import SCons.Warnings - -cache_enabled = True -cache_debug = False -cache_force = False -cache_show = False -cache_readonly = False - -def CacheRetrieveFunc(target, source, env): - t = target[0] - fs = t.fs - cd = env.get_CacheDir() - cd.requests += 1 - cachedir, cachefile = cd.cachepath(t) - if not fs.exists(cachefile): - cd.CacheDebug('CacheRetrieve(%s): %s not in cache\n', t, cachefile) - return 1 - cd.hits += 1 - cd.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile) - if SCons.Action.execute_actions: - if fs.islink(cachefile): - fs.symlink(fs.readlink(cachefile), t.get_internal_path()) - else: - env.copy_from_cache(cachefile, t.get_internal_path()) - try: - os.utime(cachefile, None) - except OSError: - pass - st = fs.stat(cachefile) - fs.chmod(t.get_internal_path(), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) - return 0 - -def CacheRetrieveString(target, source, env): - t = target[0] - fs = t.fs - cd = env.get_CacheDir() - cachedir, cachefile = cd.cachepath(t) - if t.fs.exists(cachefile): - return "Retrieved `%s' from cache" % t.get_internal_path() - return None - -CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString) - -CacheRetrieveSilent = SCons.Action.Action(CacheRetrieveFunc, None) - -def CachePushFunc(target, source, env): - if cache_readonly: - return - - t = target[0] - if t.nocache: - return - fs = t.fs - cd = env.get_CacheDir() - cachedir, cachefile = cd.cachepath(t) - if fs.exists(cachefile): - # Don't bother copying it if it's already there. Note that - # usually this "shouldn't happen" because if the file already - # existed in cache, we'd have retrieved the file from there, - # not built it. This can happen, though, in a race, if some - # other person running the same build pushes their copy to - # the cache after we decide we need to build it but before our - # build completes. - cd.CacheDebug('CachePush(%s): %s already exists in cache\n', t, cachefile) - return - - cd.CacheDebug('CachePush(%s): pushing to %s\n', t, cachefile) - - tempfile = cachefile+'.tmp'+str(os.getpid()) - errfmt = "Unable to copy %s to cache. Cache file is %s" - - if not fs.isdir(cachedir): - try: - fs.makedirs(cachedir) - except EnvironmentError: - # We may have received an exception because another process - # has beaten us creating the directory. - if not fs.isdir(cachedir): - msg = errfmt % (str(target), cachefile) - raise SCons.Errors.SConsEnvironmentError(msg) - - try: - if fs.islink(t.get_internal_path()): - fs.symlink(fs.readlink(t.get_internal_path()), tempfile) - else: - fs.copy2(t.get_internal_path(), tempfile) - fs.rename(tempfile, cachefile) - st = fs.stat(t.get_internal_path()) - fs.chmod(cachefile, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) - except EnvironmentError: - # It's possible someone else tried writing the file at the - # same time we did, or else that there was some problem like - # the CacheDir being on a separate file system that's full. - # In any case, inability to push a file to cache doesn't affect - # the correctness of the build, so just print a warning. - msg = errfmt % (str(target), cachefile) - SCons.Warnings.warn(SCons.Warnings.CacheWriteErrorWarning, msg) - -CachePush = SCons.Action.Action(CachePushFunc, None) - - -class CacheDir: - - def __init__(self, path): - """ - Initialize a CacheDir object. - - The cache configuration is stored in the object. It - is read from the config file in the supplied path if - one exists, if not the config file is created and - the default config is written, as well as saved in the object. - """ - self.requests = 0 - self.hits = 0 - self.path = path - self.current_cache_debug = None - self.debugFP = None - self.config = dict() - if path is None: - return - - self._readconfig(path) - - - def _readconfig(self, path): - """ - Read the cache config. - - If directory or config file do not exist, create. Take advantage - of Py3 capability in os.makedirs() and in file open(): just try - the operation and handle failure appropriately. - - Omit the check for old cache format, assume that's old enough - there will be none of those left to worry about. - - :param path: path to the cache directory - """ - config_file = os.path.join(path, 'config') - try: - os.makedirs(path, exist_ok=True) - except FileExistsError: - pass - except OSError: - msg = "Failed to create cache directory " + path - raise SCons.Errors.SConsEnvironmentError(msg) - - try: - with open(config_file, 'x') as config: - self.config['prefix_len'] = 2 - try: - json.dump(self.config, config) - except Exception: - msg = "Failed to write cache configuration for " + path - raise SCons.Errors.SConsEnvironmentError(msg) - except FileExistsError: - try: - with open(config_file) as config: - self.config = json.load(config) - except ValueError: - msg = "Failed to read cache configuration for " + path - raise SCons.Errors.SConsEnvironmentError(msg) - - def CacheDebug(self, fmt, target, cachefile): - if cache_debug != self.current_cache_debug: - if cache_debug == '-': - self.debugFP = sys.stdout - elif cache_debug: - def debug_cleanup(debugFP): - debugFP.close() - - self.debugFP = open(cache_debug, 'w') - atexit.register(debug_cleanup, self.debugFP) - else: - self.debugFP = None - self.current_cache_debug = cache_debug - if self.debugFP: - self.debugFP.write(fmt % (target, os.path.split(cachefile)[1])) - self.debugFP.write("requests: %d, hits: %d, misses: %d, hit rate: %.2f%%\n" % - (self.requests, self.hits, self.misses, self.hit_ratio)) - - @property - def hit_ratio(self): - return (100.0 * self.hits / self.requests if self.requests > 0 else 100) - - @property - def misses(self): - return self.requests - self.hits - - def is_enabled(self): - return cache_enabled and self.path is not None - - def is_readonly(self): - return cache_readonly - - def cachepath(self, node): - """ - """ - if not self.is_enabled(): - return None, None - - sig = node.get_cachedir_bsig() - - subdir = sig[:self.config['prefix_len']].upper() - - dir = os.path.join(self.path, subdir) - return dir, os.path.join(dir, sig) - - def retrieve(self, node): - """ - This method is called from multiple threads in a parallel build, - so only do thread safe stuff here. Do thread unsafe stuff in - built(). - - Note that there's a special trick here with the execute flag - (one that's not normally done for other actions). Basically - if the user requested a no_exec (-n) build, then - SCons.Action.execute_actions is set to 0 and when any action - is called, it does its showing but then just returns zero - instead of actually calling the action execution operation. - The problem for caching is that if the file does NOT exist in - cache then the CacheRetrieveString won't return anything to - show for the task, but the Action.__call__ won't call - CacheRetrieveFunc; instead it just returns zero, which makes - the code below think that the file *was* successfully - retrieved from the cache, therefore it doesn't do any - subsequent building. However, the CacheRetrieveString didn't - print anything because it didn't actually exist in the cache, - and no more build actions will be performed, so the user just - sees nothing. The fix is to tell Action.__call__ to always - execute the CacheRetrieveFunc and then have the latter - explicitly check SCons.Action.execute_actions itself. - """ - if not self.is_enabled(): - return False - - env = node.get_build_env() - if cache_show: - if CacheRetrieveSilent(node, [], env, execute=1) == 0: - node.build(presub=0, execute=0) - return True - else: - if CacheRetrieve(node, [], env, execute=1) == 0: - return True - - return False - - def push(self, node): - if self.is_readonly() or 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) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Conftest.py b/scons/scons-local-4.1.0/SCons/Conftest.py deleted file mode 100644 index 908713c1d..000000000 --- a/scons/scons-local-4.1.0/SCons/Conftest.py +++ /dev/null @@ -1,805 +0,0 @@ -# MIT License -# -# Copyright The SCons Foundation -# Copyright (c) 2003 Stichting NLnet Labs -# Copyright (c) 2001, 2002, 2003 Steven Knight -# -# 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. - -"""Autoconf-like configuration support - -The purpose of this module is to define how a check is to be performed. - -A context class is used that defines functions for carrying out the tests, -logging and messages. The following methods and members must be present: - -context.Display(msg) - Function called to print messages that are normally displayed - for the user. Newlines are explicitly used. The text should - also be written to the logfile! - -context.Log(msg) - Function called to write to a log file. - -context.BuildProg(text, ext) - Function called to build a program, using "ext" for the file - extension. Must return an empty string for success, an error - message for failure. For reliable test results building should - be done just like an actual program would be build, using the - same command and arguments (including configure results so far). - -context.CompileProg(text, ext) - Function called to compile a program, using "ext" for the file - extension. Must return an empty string for success, an error - message for failure. For reliable test results compiling should be - done just like an actual source file would be compiled, using the - same command and arguments (including configure results so far). - -context.AppendLIBS(lib_name_list) - Append "lib_name_list" to the value of LIBS. "lib_namelist" is - a list of strings. Return the value of LIBS before changing it - (any type can be used, it is passed to SetLIBS() later.) - -context.PrependLIBS(lib_name_list) - Prepend "lib_name_list" to the value of LIBS. "lib_namelist" is - a list of strings. Return the value of LIBS before changing it - (any type can be used, it is passed to SetLIBS() later.) - -context.SetLIBS(value) - Set LIBS to "value". The type of "value" is what AppendLIBS() - returned. Return the value of LIBS before changing it (any type - can be used, it is passed to SetLIBS() later.) - -context.headerfilename - Name of file to append configure results to, usually "confdefs.h". - The file must not exist or be empty when starting. Empty or None - to skip this (some tests will not work!). - -context.config_h (may be missing). - If present, must be a string, which will be filled with the - contents of a config_h file. - -context.vardict - Dictionary holding variables used for the tests and stores results - from the tests, used for the build commands. Normally contains - "CC", "LIBS", "CPPFLAGS", etc. - -context.havedict - Dictionary holding results from the tests that are to be used - inside a program. Names often start with "HAVE_". These are zero - (feature not present) or one (feature present). Other variables - may have any value, e.g., "PERLVERSION" can be a number and - "SYSTEMNAME" a string. -""" - -import re - -# -# PUBLIC VARIABLES -# - -LogInputFiles = 1 # Set that to log the input files in case of a failed test -LogErrorMessages = 1 # Set that to log Conftest-generated error messages - -# -# PUBLIC FUNCTIONS -# - -# Generic remarks: -# - When a language is specified which is not supported the test fails. The -# message is a bit different, because not all the arguments for the normal -# message are available yet (chicken-egg problem). - - -def CheckBuilder(context, text = None, language = None): - """ - Configure check to see if the compiler works. - Note that this uses the current value of compiler and linker flags, make - sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. - "language" should be "C" or "C++" and is used to select the compiler. - Default is "C". - "text" may be used to specify the code to be build. - Returns an empty string for success, an error message for failure. - """ - lang, suffix, msg = _lang2suffix(language) - if msg: - context.Display("%s\n" % msg) - return msg - - if not text: - text = """ -int main(void) { - return 0; -} -""" - - context.Display("Checking if building a %s file works... " % lang) - ret = context.BuildProg(text, suffix) - _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(void) -{ - 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(void) -{ - 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(void) -{ - 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(void) -{ - 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 comp not in context.env 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): - """ - Configure check for a function "function_name". - "language" should be "C" or "C++" and is used to select the compiler. - Default is "C". - Optional "header" can be defined to define a function prototype, include a - header file or anything else that comes before main(). - Sets HAVE_function_name in context.havedict according to the result. - Note that this uses the current value of compiler and linker flags, make - sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. - Returns an empty string for success, an error message for failure. - """ - - # Remarks from autoconf: - # - Don't include because on OSF/1 3.0 it includes - # which includes which contains a prototype for select. - # Similarly for bzero. - # - assert.h is included to define __stub macros and hopefully few - # prototypes, which can conflict with char $1(); below. - # - Override any gcc2 internal prototype to avoid an error. - # - We use char for the function declaration because int might match the - # return type of a gcc2 builtin and then its argument prototype would - # still apply. - # - The GNU C library defines this for functions which it implements to - # always fail with ENOSYS. Some functions are actually named something - # starting with __ and the normal name is an alias. - - if context.headerfilename: - includetext = '#include "%s"' % context.headerfilename - else: - includetext = '' - if not header: - header = """ -#ifdef __cplusplus -extern "C" -#endif -char %s();""" % function_name - - lang, suffix, msg = _lang2suffix(language) - if msg: - context.Display("Cannot check for %s(): %s\n" % (function_name, msg)) - return msg - - text = """ -%(include)s -#include -%(hdr)s - -#if _MSC_VER && !__INTEL_COMPILER - #pragma function(%(name)s) -#endif - -int main(void) { -#if defined (__stub_%(name)s) || defined (__stub___%(name)s) - fail fail fail -#else - %(name)s(); -#endif - - return 0; -} -""" % { 'name': function_name, - 'include': includetext, - 'hdr': header } - - context.Display("Checking for %s function %s()... " % (lang, function_name)) - ret = context.BuildProg(text, suffix) - _YesNoResult(context, ret, "HAVE_" + function_name, text, - "Define to 1 if the system has the function `%s'." %\ - function_name) - return ret - - -def CheckHeader(context, header_name, header=None, language=None, - include_quotes=None): - """ - Configure check for a C or C++ header file "header_name". - Optional "header" can be defined to do something before including the - header file (unusual, supported for consistency). - "language" should be "C" or "C++" and is used to select the compiler. - Default is "C". - Sets HAVE_header_name in context.havedict according to the result. - Note that this uses the current value of compiler and linker flags, make - sure $CFLAGS and $CPPFLAGS are set correctly. - Returns an empty string for success, an error message for failure. - """ - # Why compile the program instead of just running the preprocessor? - # It is possible that the header file exists, but actually using it may - # fail (e.g., because it depends on other header files). Thus this test is - # more strict. It may require using the "header" argument. - # - # Use <> by default, because the check is normally used for system header - # files. SCons passes '""' to overrule this. - - # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. - if context.headerfilename: - includetext = '#include "%s"\n' % context.headerfilename - else: - includetext = '' - if not header: - header = "" - - lang, suffix, msg = _lang2suffix(language) - if msg: - context.Display("Cannot check for header file %s: %s\n" - % (header_name, msg)) - return msg - - if not include_quotes: - include_quotes = "<>" - - text = "%s%s\n#include %s%s%s\n\n" % (includetext, header, - include_quotes[0], header_name, include_quotes[1]) - - context.Display("Checking for %s header file %s... " % (lang, header_name)) - ret = context.CompileProg(text, suffix) - _YesNoResult(context, ret, "HAVE_" + header_name, text, - "Define to 1 if you have the <%s> header file." % header_name) - return ret - - -def CheckType(context, type_name, fallback = None, - header = None, language = None): - """ - Configure check for a C or C++ type "type_name". - Optional "header" can be defined to include a header file. - "language" should be "C" or "C++" and is used to select the compiler. - Default is "C". - Sets HAVE_type_name in context.havedict according to the result. - Note that this uses the current value of compiler and linker flags, make - sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. - Returns an empty string for success, an error message for failure. - """ - - # 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 header: - header = "" - - lang, suffix, msg = _lang2suffix(language) - if msg: - context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) - return msg - - # Remarks from autoconf about this test: - # - Grepping for the type in include files is not reliable (grep isn't - # portable anyway). - # - Using "TYPE my_var;" doesn't work for const qualified types in C++. - # Adding an initializer is not valid for some C++ classes. - # - Using the type as parameter to a function either fails for K&$ C or for - # C++. - # - Using "TYPE *my_var;" is valid in C for some types that are not - # declared (struct something). - # - Using "sizeof(TYPE)" is valid when TYPE is actually a variable. - # - Using the previous two together works reliably. - text = """ -%(include)s -%(header)s - -int main(void) { - if ((%(name)s *) 0) - return 0; - if (sizeof (%(name)s)) - return 0; -} -""" % { 'include': includetext, - 'header': header, - 'name': type_name } - - context.Display("Checking for %s type %s... " % (lang, type_name)) - ret = context.BuildProg(text, suffix) - _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)) - f.close() - - return ret - -def CheckTypeSize(context, type_name, header = None, language = None, expect = None): - """This check can be used to get the size of a given type, or to check whether - the type is of expected size. - - Arguments: - - type : str - the type to check - - includes : sequence - list of headers to include in the test code before testing the type - - language : str - 'C' or 'C++' - - expect : int - if given, will test wether the type has the given number of bytes. - If not given, will automatically find the size. - - Returns: - status : int - 0 if the check failed, or the found size of the type if the check 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 header: - header = "" - - lang, suffix, msg = _lang2suffix(language) - if msg: - context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) - return msg - - src = includetext + header - if expect is not None: - # Only check if the given size is the right one - context.Display('Checking %s is %d bytes... ' % (type_name, expect)) - - # test code taken from autoconf: this is a pretty clever hack to find that - # a type is of a given size using only compilation. This speeds things up - # quite a bit compared to straightforward code using TryRun - src = src + r""" -typedef %s scons_check_type; - -int main(void) -{ - static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)]; - test_array[0] = 0; - - return 0; -} -""" - - 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") - _LogFailed(context, src, st) - return 0 - else: - # Only check if the given size is the right one - context.Message('Checking size of %s ... ' % type_name) - - # We have to be careful with the program we wish to test here since - # compilation will be attempted using the current environment's flags. - # So make sure that the program will compile without any warning. For - # example using: 'int main(int argc, char** argv)' will fail with the - # '-Wall -Werror' flags since the variables argc and argv would not be - # used in the program... - # - src = src + """ -#include -#include -int main(void) { - printf("%d", (int)sizeof(""" + type_name + """)); - return 0; -} - """ - st, out = context.RunProg(src, suffix) - try: - 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 - - 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" % (symbol, msg)) - return msg - - src = includetext + includes - context.Display('Checking whether %s is declared... ' % symbol) - - src = src + r""" -int main(void) -{ -#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, - append = True): - """ - Configure check for a C or C++ libraries "libs". Searches through - the list of libraries, until one is found where the test succeeds. - Tests if "func_name" or "call" exists in the library. Note: if it exists - in another library the test succeeds anyway! - Optional "header" can be defined to include a header file. If not given a - default prototype for "func_name" is added. - Optional "extra_libs" is a list of library names to be added after - "lib_name" in the build command. To be used for libraries that "lib_name" - depends on. - Optional "call" replaces the call to "func_name" in the test code. It must - consist of complete C statements, including a trailing ";". - Both "func_name" and "call" arguments are optional, and in that case, just - linking against the libs is tested. - "language" should be "C" or "C++" and is used to select the compiler. - Default is "C". - Note that this uses the current value of compiler and linker flags, make - sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. - Returns an empty string for success, an error message for failure. - """ - # 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 header: - header = "" - - text = """ -%s -%s""" % (includetext, header) - - # Add a function declaration if needed. - if func_name and func_name != "main": - if not header: - text = text + """ -#ifdef __cplusplus -extern "C" -#endif -char %s(); -""" % func_name - - # The actual test code. - if not call: - call = "%s();" % func_name - - # if no function to test, leave main() blank - text = text + """ -int -main() { - %s -return 0; -} -""" % (call or "") - - if call: - i = call.find("\n") - if i > 0: - calltext = call[:i] + ".." - elif call[-1] == ';': - calltext = call[:-1] - else: - calltext = call - - for lib_name in libs: - - lang, suffix, msg = _lang2suffix(language) - if msg: - context.Display("Cannot check for library %s: %s\n" % (lib_name, msg)) - return msg - - # if a function was specified to run in main(), say it - if call: - context.Display("Checking for %s in %s library %s... " - % (calltext, lang, lib_name)) - # otherwise, just say the name of library and language - else: - context.Display("Checking for %s library %s... " - % (lang, lib_name)) - - if lib_name: - l = [ lib_name ] - if extra_libs: - l.extend(extra_libs) - if append: - oldLIBS = context.AppendLIBS(l) - else: - oldLIBS = context.PrependLIBS(l) - sym = "HAVE_LIB" + lib_name - else: - oldLIBS = -1 - sym = None - - ret = context.BuildProg(text, suffix) - - _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) - - if not ret: - return ret - - return ret - -def CheckProg(context, prog_name): - """ - Configure check for a specific program. - - Check whether program prog_name exists in path. If it is found, - returns the path for it, otherwise returns None. - """ - context.Display("Checking whether %s program exists..." % prog_name) - path = context.env.WhereIs(prog_name) - if path: - context.Display(path + "\n") - else: - context.Display("no\n") - return path - - -# -# END OF PUBLIC FUNCTIONS -# - -def _YesNoResult(context, ret, key, text, comment = None): - r""" - Handle the result of a test with a "yes" or "no" result. - - :Parameters: - - `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, comment) - if ret: - context.Display("no\n") - _LogFailed(context, text, ret) - else: - context.Display("yes\n") - - -def _Have(context, key, have, comment = None): - r""" - Store result of a test in context.havedict and context.headerfilename. - - :Parameters: - - `key` - is a "HAVE_abc" name. It is turned into all CAPITALS and non-alphanumerics are replaced by an underscore. - - `have` - value as it should appear in the header file, include quotes when desired and escape special characters! - - `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. - - - The value of "have" can be: - - 1 - Feature is defined, add "#define key". - - 0 - Feature is not defined, add "/\* #undef key \*/". Adding "undef" is what autoconf does. Not useful for the compiler, but it shows that the test was done. - - number - Feature is defined to this number "#define key have". Doesn't work for 0 or 1, use a string then. - - string - Feature is defined to this string "#define key have". - - - """ - key_up = key.upper() - key_up = re.sub('[^A-Z0-9_]', '_', key_up) - context.havedict[key_up] = have - if have == 1: - line = "#define %s 1\n" % key_up - elif have == 0: - line = "/* #undef %s */\n" % key_up - elif isinstance(have, int): - line = "#define %s %d\n" % (key_up, 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(lines) - f.close() - elif hasattr(context,'config_h'): - context.config_h = context.config_h + lines - - -def _LogFailed(context, text, msg): - """ - Write to the log about a failed program. - Add line numbers, so that error messages can be understood. - """ - if LogInputFiles: - context.Log("Failed program was:\n") - lines = text.split('\n') - if len(lines) and lines[-1] == '': - lines = lines[:-1] # remove trailing empty line - n = 1 - for line in lines: - context.Log("%d: %s\n" % (n, line)) - n = n + 1 - if LogErrorMessages: - context.Log("Error message: %s\n" % msg) - - -def _lang2suffix(lang): - """ - Convert a language name to a suffix. - When "lang" is empty or None C is assumed. - Returns a tuple (lang, suffix, None) when it works. - For an unrecognized language returns (None, None, msg). - - Where: - - lang = the unified language name - - suffix = the suffix, including the leading dot - - msg = an error message - """ - if not lang or lang in ["C", "c"]: - return ("C", ".c", None) - if lang in ["c++", "C++", "cpp", "CXX", "cxx"]: - return ("C++", ".cpp", None) - - return None, None, "Unsupported language: %s" % lang - - -# vim: set sw=4 et sts=4 tw=79 fo+=l: - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Debug.py b/scons/scons-local-4.1.0/SCons/Debug.py deleted file mode 100644 index f4b802e8e..000000000 --- a/scons/scons-local-4.1.0/SCons/Debug.py +++ /dev/null @@ -1,251 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Code for debugging SCons internal things. - -Shouldn't be needed by most users. Quick shortcuts: - -from SCons.Debug import caller_trace -caller_trace() -""" - -import atexit -import os -import sys -import time -import weakref -import inspect - -# Global variable that gets set to 'True' by the Main script, -# when the creation of class instances should get tracked. -track_instances = False -# List of currently tracked classes -tracked_classes = {} - -def logInstanceCreation(instance, name=None): - if name is None: - name = instance.__class__.__name__ - if name not in tracked_classes: - tracked_classes[name] = [] - if hasattr(instance, '__dict__'): - tracked_classes[name].append(weakref.ref(instance)) - else: - # weakref doesn't seem to work when the instance - # contains only slots... - tracked_classes[name].append(instance) - -def string_to_classes(s): - if s == '*': - return sorted(tracked_classes.keys()) - else: - return s.split() - -def fetchLoggedInstances(classes="*"): - classnames = string_to_classes(classes) - return [(cn, len(tracked_classes[cn])) for cn in classnames] - -def countLoggedInstances(classes, file=sys.stdout): - for classname in string_to_classes(classes): - file.write("%s: %d\n" % (classname, len(tracked_classes[classname]))) - -def listLoggedInstances(classes, file=sys.stdout): - for classname in string_to_classes(classes): - file.write('\n%s:\n' % classname) - for ref in tracked_classes[classname]: - if inspect.isclass(ref): - obj = ref() - else: - obj = ref - if obj is not None: - file.write(' %s\n' % repr(obj)) - -def dumpLoggedInstances(classes, file=sys.stdout): - for classname in string_to_classes(classes): - file.write('\n%s:\n' % classname) - for ref in tracked_classes[classname]: - obj = ref() - if obj is not None: - file.write(' %s:\n' % obj) - for key, value in obj.__dict__.items(): - file.write(' %20s : %s\n' % (key, value)) - - -if sys.platform[:5] == "linux": - # Linux doesn't actually support memory usage stats from getrusage(). - def memory(): - with open('/proc/self/stat') as f: - mstr = f.read() - mstr = mstr.split()[22] - return int(mstr) -elif sys.platform[:6] == 'darwin': - #TODO really get memory stats for OS X - def memory(): - return 0 -elif sys.platform == 'win32': - from SCons.compat.win32 import get_peak_memory_usage - memory = get_peak_memory_usage -else: - try: - import resource - except ImportError: - def memory(): - return 0 - else: - def memory(): - res = resource.getrusage(resource.RUSAGE_SELF) - return res[4] - - -def caller_stack(): - """return caller's stack""" - import traceback - tb = traceback.extract_stack() - # strip itself and the caller from the output - tb = tb[:-2] - result = [] - for back in tb: - # (filename, line number, function name, text) - key = back[:3] - result.append('%s:%d(%s)' % func_shorten(key)) - return result - -caller_bases = {} -caller_dicts = {} - -def caller_trace(back=0): - """ - Trace caller stack and save info into global dicts, which - are printed automatically at the end of SCons execution. - """ - global caller_bases, caller_dicts - 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): - leader = ' '*level - for v,c in sorted([(-v,c) for c,v in caller_dicts[key].items()]): - file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:]))) - if c in caller_dicts: - _dump_one_caller(c, file, level+1) - -# print each call tree -def dump_caller_counts(file=sys.stdout): - for k in sorted(caller_bases.keys()): - 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), - ( '/src/engine/SCons/', 1), - ( '/usr/lib/python', 0), -] - -if os.sep != '/': - shorten_list = [(t[0].replace('/', os.sep), t[1]) for t in shorten_list] - -def func_shorten(func_tuple): - f = func_tuple[0] - for t in shorten_list: - i = f.find(t[0]) - if i >= 0: - if t[1]: - i = i + len(t[0]) - return (f[i:],)+func_tuple[1:] - return func_tuple - - -TraceFP = {} -if sys.platform == 'win32': - TraceDefault = 'con' -else: - TraceDefault = '/dev/tty' -TimeStampDefault = False -StartTime = time.time() -PreviousTime = StartTime - -def Trace(msg, tracefile=None, mode='w', tstamp=False): - """Write a trace message. - - Write messages when debugging which do not interfere with stdout. - Useful in tests, which monitor stdout and would break with - unexpected output. Trace messages can go to the console (which is - opened as a file), or to a disk file; the tracefile argument persists - across calls unless overridden. - - Args: - tracefile: file to write trace message to. If omitted, - write to the previous trace file (default: console). - mode: file open mode (default: 'w') - tstamp: write relative timestamps with trace. Outputs time since - scons was started, and time since last trace (default: False) - - """ - global TraceDefault - global TimeStampDefault - global PreviousTime - - def trace_cleanup(traceFP): - traceFP.close() - - if tracefile is None: - tracefile = TraceDefault - else: - TraceDefault = tracefile - if not tstamp: - tstamp = TimeStampDefault - else: - TimeStampDefault = tstamp - try: - fp = TraceFP[tracefile] - except KeyError: - try: - fp = TraceFP[tracefile] = open(tracefile, mode) - atexit.register(trace_cleanup, fp) - except TypeError: - # Assume we were passed an open file pointer. - fp = tracefile - if tstamp: - now = time.time() - fp.write('%8.4f %8.4f: ' % (now - StartTime, now - PreviousTime)) - PreviousTime = now - fp.write(msg) - fp.flush() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Defaults.py b/scons/scons-local-4.1.0/SCons/Defaults.py deleted file mode 100644 index ab8a82541..000000000 --- a/scons/scons-local-4.1.0/SCons/Defaults.py +++ /dev/null @@ -1,644 +0,0 @@ -# MIT License -# -# Copyright 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. -# - -"""Builders and other things for the local site. - -Here's where we'll duplicate the functionality of autoconf until we -move it into the installation procedure or use something like qmconf. - -The code that reads the registry to find MSVC components was borrowed -from distutils.msvccompiler. -""" - -import errno -import os -import shutil -import stat -import sys -import time - -import SCons.Action -import SCons.Builder -import SCons.CacheDir -import SCons.Environment -import SCons.PathList -import SCons.Subst -import SCons.Tool -import SCons.Scanner.Dir - -# A placeholder for a default Environment (for fetching source files -# from source code management systems and the like). This must be -# initialized later, after the top-level directory is set by the calling -# interface. -_default_env = None - - -# Lazily instantiate the default environment so the overhead of creating -# it doesn't apply when it's not needed. -def _fetch_DefaultEnvironment(*args, **kw): - """Returns the already-created default construction environment.""" - global _default_env - return _default_env - - -def DefaultEnvironment(*args, **kw): - """ - Initial public entry point for creating the default construction - Environment. - - After creating the environment, we overwrite our name - (DefaultEnvironment) with the _fetch_DefaultEnvironment() function, - which more efficiently returns the initialized default construction - environment without checking for its existence. - - (This function still exists with its _default_check because someone - else (*cough* Script/__init__.py *cough*) may keep a reference - to this function. So we can't use the fully functional idiom of - having the name originally be a something that *only* creates the - construction environment and then overwrites the name.) - """ - global _default_env - if not _default_env: - import SCons.Util - _default_env = SCons.Environment.Environment(*args, **kw) - if SCons.Util.md5: - _default_env.Decider('MD5') - else: - _default_env.Decider('timestamp-match') - global DefaultEnvironment - DefaultEnvironment = _fetch_DefaultEnvironment - _default_env._CacheDir_path = None - return _default_env - - -# Emitters for setting the shared attribute on object files, -# and an action for checking that all of the source files -# going into a shared library are, in fact, shared. -def StaticObjectEmitter(target, source, env): - for tgt in target: - tgt.attributes.shared = None - return (target, source) - - -def SharedObjectEmitter(target, source, env): - for tgt in target: - tgt.attributes.shared = 1 - return (target, source) - - -def SharedFlagChecker(source, target, env): - same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME') - if same == '0' or same == '' or same == 'False': - for src in source: - try: - shared = src.attributes.shared - except AttributeError: - shared = None - if not shared: - raise SCons.Errors.UserError( - "Source file: %s is static and is not compatible with shared target: %s" % (src, target[0])) - - -SharedCheck = SCons.Action.Action(SharedFlagChecker, None) - -# Some people were using these variable name before we made -# SourceFileScanner part of the public interface. Don't break their -# SConscript files until we've given them some fair warning and a -# transition period. -CScan = SCons.Tool.CScanner -DScan = SCons.Tool.DScanner -LaTeXScan = SCons.Tool.LaTeXScanner -ObjSourceScan = SCons.Tool.SourceFileScanner -ProgScan = SCons.Tool.ProgramScanner - -# These aren't really tool scanners, so they don't quite belong with -# the rest of those in Tool/__init__.py, but I'm not sure where else -# they should go. Leave them here for now. - -DirScanner = SCons.Scanner.Dir.DirScanner() -DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner() - -# Actions for common languages. -CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR") -ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR") -CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR") -ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR") - -DAction = SCons.Action.Action("$DCOM", "$DCOMSTR") -ShDAction = SCons.Action.Action("$SHDCOM", "$SHDCOMSTR") - -ASAction = SCons.Action.Action("$ASCOM", "$ASCOMSTR") -ASPPAction = SCons.Action.Action("$ASPPCOM", "$ASPPCOMSTR") - -LinkAction = SCons.Action.Action("$LINKCOM", "$LINKCOMSTR") -ShLinkAction = SCons.Action.Action("$SHLINKCOM", "$SHLINKCOMSTR") - -LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR") - -# Common tasks that we allow users to perform in platform-independent -# ways by creating ActionFactory instances. -ActionFactory = SCons.Action.ActionFactory - - -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 '[' + ', '.join(elem_strs) + ']' - else: - return '"' + str(dest) + '"' - - -permission_dic = { - 'u': { - 'r': stat.S_IRUSR, - 'w': stat.S_IWUSR, - 'x': stat.S_IXUSR - }, - 'g': { - 'r': stat.S_IRGRP, - 'w': stat.S_IWGRP, - 'x': stat.S_IXGRP - }, - 'o': { - 'r': stat.S_IROTH, - 'w': stat.S_IWOTH, - 'x': stat.S_IXOTH - } -} - - -def chmod_func(dest, mode): - import SCons.Util - from string import digits - SCons.Node.FS.invalidate_node_memos(dest) - if not SCons.Util.is_List(dest): - dest = [dest] - if SCons.Util.is_String(mode) and 0 not in [i in digits for i in mode]: - mode = int(mode, 8) - if not SCons.Util.is_String(mode): - for element in dest: - os.chmod(str(element), mode) - else: - mode = str(mode) - for operation in mode.split(","): - if "=" in operation: - operator = "=" - elif "+" in operation: - operator = "+" - elif "-" in operation: - operator = "-" - else: - raise SyntaxError("Could not find +, - or =") - operation_list = operation.split(operator) - if len(operation_list) != 2: - raise SyntaxError("More than one operator found") - user = operation_list[0].strip().replace("a", "ugo") - permission = operation_list[1].strip() - new_perm = 0 - for u in user: - for p in permission: - try: - new_perm = new_perm | permission_dic[u][p] - except KeyError: - raise SyntaxError("Unrecognized user or permission format") - for element in dest: - curr_perm = os.stat(str(element)).st_mode - if operator == "=": - os.chmod(str(element), new_perm) - elif operator == "+": - os.chmod(str(element), curr_perm | new_perm) - elif operator == "-": - os.chmod(str(element), curr_perm & ~new_perm) - - -def chmod_strfunc(dest, mode): - import SCons.Util - if not SCons.Util.is_String(mode): - return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode) - else: - return 'Chmod(%s, "%s")' % (get_paths_str(dest), str(mode)) - - -Chmod = ActionFactory(chmod_func, chmod_strfunc) - - -def copy_func(dest, src, symlinks=True): - """ - If symlinks (is true), then a symbolic link will be - shallow copied and recreated as a symbolic link; otherwise, copying - a symbolic link will be equivalent to copying the symbolic link's - final target regardless of symbolic link depth. - """ - - dest = str(dest) - src = str(src) - - SCons.Node.FS.invalidate_node_memos(dest) - if SCons.Util.is_List(src) and os.path.isdir(dest): - for file in src: - shutil.copy2(file, dest) - return 0 - elif os.path.islink(src): - if symlinks: - return os.symlink(os.readlink(src), dest) - else: - return copy_func(dest, os.path.realpath(src)) - elif os.path.isfile(src): - shutil.copy2(src, dest) - return 0 - else: - shutil.copytree(src, dest, symlinks) - # copytree returns None in python2 and destination string in python3 - # A error is raised in both cases, so we can just return 0 for success - return 0 - - -Copy = ActionFactory( - copy_func, - lambda dest, src, symlinks=True: 'Copy("%s", "%s")' % (dest, src) -) - - -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) - # os.path.exists returns False with broken links that exist - entry_exists = os.path.exists(entry) or os.path.islink(entry) - if not entry_exists and not must_exist: - continue - # os.path.isdir returns True when entry is a link to a dir - if os.path.isdir(entry) and not os.path.islink(entry): - shutil.rmtree(entry, 1) - continue - os.unlink(entry) - - -def delete_strfunc(dest, must_exist=0): - return 'Delete(%s)' % get_paths_str(dest) - - -Delete = ActionFactory(delete_func, delete_strfunc) - - -def mkdir_func(dest): - SCons.Node.FS.invalidate_node_memos(dest) - if not SCons.Util.is_List(dest): - dest = [dest] - for entry in dest: - try: - os.makedirs(str(entry)) - except os.error as e: - p = str(entry) - if (e.args[0] == errno.EEXIST or - (sys.platform == 'win32' and e.args[0] == 183)) \ - and os.path.isdir(str(entry)): - pass # not an error if already exists - else: - raise - - -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) - shutil.move(src, dest) - - -Move = ActionFactory(move_func, - lambda dest, src: 'Move("%s", "%s")' % (dest, src), - convert=str) - - -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: - with open(file, 'w'): - atime = mtime - os.utime(file, (atime, mtime)) - - -Touch = ActionFactory(touch_func, - lambda file: 'Touch(%s)' % get_paths_str(file)) - - -# Internal utility functions - - -def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None): - """ - Creates a new list from 'list' by first interpolating each element - in the list using the 'env' dictionary and then calling f on the - list, and finally calling _concat_ixes to concatenate 'prefix' and - 'suffix' onto each element of the list. - """ - if not list: - return list - - l = f(SCons.PathList.PathList(list).subst_path(env, target, source)) - if l is not None: - list = l - - return _concat_ixes(prefix, list, suffix, env) - - -def _concat_ixes(prefix, list, suffix, env): - """ - Creates a new list from 'list' by concatenating the 'prefix' and - 'suffix' arguments onto each element of the list. A trailing space - on 'prefix' or leading space on 'suffix' will cause them to be put - into separate list elements rather than being concatenated. - """ - - result = [] - - # ensure that prefix and suffix are strings - prefix = str(env.subst(prefix, SCons.Subst.SUBST_RAW)) - suffix = str(env.subst(suffix, SCons.Subst.SUBST_RAW)) - - for x in list: - if isinstance(x, SCons.Node.FS.File): - result.append(x) - continue - x = str(x) - if x: - - if prefix: - if prefix[-1] == ' ': - result.append(prefix[:-1]) - elif x[:len(prefix)] != prefix: - x = prefix + x - - result.append(x) - - if suffix: - if suffix[0] == ' ': - result.append(suffix[1:]) - elif x[-len(suffix):] != suffix: - result[-1] = result[-1] + suffix - - return result - - -def _stripixes(prefix, itms, 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 items and strips them - where it finds them. This is used by tools (like the GNU linker) - that need to turn something like 'libfoo.a' into '-lfoo'. - """ - - if not itms: - return itms - - if not callable(c): - env_c = env['_concat'] - if env_c != _concat and callable(env_c): - # There's a custom _concat() method in the construction - # environment, and we've allowed people to set that in - # the past (see test/custom-concat.py), so preserve the - # backwards compatibility. - c = env_c - else: - c = _concat_ixes - - stripprefixes = list(map(env.subst, SCons.Util.flatten(stripprefixes))) - stripsuffixes = list(map(env.subst, SCons.Util.flatten(stripsuffixes))) - - stripped = [] - for l in SCons.PathList.PathList(itms).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) - - 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) - - -def processDefines(defs): - """process defines, resolving strings, lists, dictionaries, into a list of - strings - """ - if SCons.Util.is_List(defs): - l = [] - for d in defs: - if d is None: - continue - elif SCons.Util.is_List(d) or isinstance(d, tuple): - if len(d) >= 2: - l.append(str(d[0]) + '=' + str(d[1])) - else: - l.append(str(d[0])) - elif SCons.Util.is_Dict(d): - for macro, value in d.items(): - if value is not None: - l.append(str(macro) + '=' + str(value)) - else: - l.append(str(macro)) - elif SCons.Util.is_String(d): - l.append(str(d)) - else: - raise SCons.Errors.UserError("DEFINE %s is not a list, dict, string or None." % repr(d)) - elif SCons.Util.is_Dict(defs): - # The items in a dictionary are stored in random order, but - # if the order of the command-line options changes from - # invocation to invocation, then the signature of the command - # line will change and we'll get random unnecessary rebuilds. - # Consequently, we have to sort the keys to ensure a - # consistent order... - l = [] - for k, v in sorted(defs.items()): - if v is None: - l.append(str(k)) - else: - l.append(str(k) + '=' + str(v)) - else: - l = [str(defs)] - return l - - -def _defines(prefix, defs, suffix, env, c=_concat_ixes): - """A wrapper around _concat_ixes that turns a list or string - into a list of C preprocessor command-line definitions. - """ - - return c(prefix, env.subst_path(processDefines(defs)), suffix, env) - - -class NullCmdGenerator: - """This is a callable class that can be used in place of other - command generators if you don't want them to do anything. - - The __call__ method for this class simply returns the thing - you instantiated it with. - - Example usage: - env["DO_NOTHING"] = NullCmdGenerator - env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}" - """ - - def __init__(self, cmd): - self.cmd = cmd - - def __call__(self, target, source, env, for_signature=None): - return self.cmd - - -class Variable_Method_Caller: - """A class for finding a construction variable on the stack and - calling one of its methods. - - We use this to support "construction variables" in our string - eval()s that actually stand in for methods--specifically, use - of "RDirs" in call to _concat that should actually execute the - "TARGET.RDirs" method. (We used to support this by creating a little - "build dictionary" that mapped RDirs to the method, but this got in - the way of Memoizing construction environments, because we had to - create new environment objects to hold the variables.) - """ - - def __init__(self, variable, method): - self.variable = variable - self.method = method - - def __call__(self, *args, **kw): - try: - 1 // 0 - 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 variable in frame.f_locals: - v = frame.f_locals[variable] - if v: - method = getattr(v, self.method) - return method(*args, **kw) - frame = frame.f_back - return None - - -def __libversionflags(env, version_var, flags_var): - """ - if version_var is not empty, returns env[flags_var], otherwise returns None - :param env: - :param version_var: - :param flags_var: - :return: - """ - try: - if env.subst('$' + version_var): - return env[flags_var] - except KeyError: - pass - return None - - -def __lib_either_version_flag(env, version_var1, version_var2, flags_var): - """ - if $version_var1 or $version_var2 is not empty, returns env[flags_var], otherwise returns None - :param env: - :param version_var1: - :param version_var2: - :param flags_var: - :return: - """ - try: - if env.subst('$' + version_var1) or env.subst('$' + version_var2): - return env[flags_var] - except KeyError: - pass - return None - - -ConstructionEnvironment = { - 'BUILDERS': {}, - 'SCANNERS': [SCons.Tool.SourceFileScanner], - 'CONFIGUREDIR': '#/.sconf_temp', - 'CONFIGURELOG': '#/config.log', - 'CPPSUFFIXES': SCons.Tool.CSuffixes, - 'DSUFFIXES': SCons.Tool.DSuffixes, - 'ENV': {}, - 'IDLSUFFIXES': SCons.Tool.IDLSuffixes, - '_concat': _concat, - '_defines': _defines, - '_stripixes': _stripixes, - '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', - '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', - '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', - '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}', - - '__libversionflags': __libversionflags, - '__SHLIBVERSIONFLAGS': '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', - '__LDMODULEVERSIONFLAGS': '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', - '__DSHLIBVERSIONFLAGS': '${__libversionflags(__env__,"DSHLIBVERSION","_DSHLIBVERSIONFLAGS")}', - '__lib_either_version_flag': __lib_either_version_flag, - - 'TEMPFILE': NullCmdGenerator, - 'TEMPFILEARGJOIN': ' ', - 'Dir': Variable_Method_Caller('TARGET', 'Dir'), - 'Dirs': Variable_Method_Caller('TARGET', 'Dirs'), - 'File': Variable_Method_Caller('TARGET', 'File'), - 'RDirs': Variable_Method_Caller('TARGET', 'RDirs'), -} - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Environment.py b/scons/scons-local-4.1.0/SCons/Environment.py deleted file mode 100644 index 9e2870c04..000000000 --- a/scons/scons-local-4.1.0/SCons/Environment.py +++ /dev/null @@ -1,2555 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Base class for construction Environments. - -These are the primary objects used to communicate dependency and -construction information to the build engine. - -Keyword arguments supplied when the construction Environment is created -are construction variables used to initialize the Environment. -""" - -import copy -import os -import sys -import re -import shlex -from collections import UserDict - -import SCons.Action -import SCons.Builder -import SCons.Debug -from SCons.Debug import logInstanceCreation -import SCons.Defaults -from SCons.Errors import UserError, BuildError -import SCons.Memoize -import SCons.Node -import SCons.Node.Alias -import SCons.Node.FS -import SCons.Node.Python -import SCons.Platform -import SCons.SConf -import SCons.SConsign -import SCons.Subst -import SCons.Tool -import SCons.Warnings -from SCons.Util import ( - AppendPath, - CLVar, - LogicalLines, - MethodWrapper, - PrependPath, - Split, - WhereIs, - flatten, - is_Dict, - is_List, - is_Sequence, - is_String, - is_Tuple, - md5, - semi_deepcopy, - semi_deepcopy_dict, - to_String_for_subst, - uniquer_hashables, -) - -class _Null: - pass - -_null = _Null - -_warn_copy_deprecated = True -_warn_source_signatures_deprecated = True -_warn_target_signatures_deprecated = True - -CleanTargets = {} -CalculatorArgs = {} - -def alias_builder(env, target, source): - pass - -AliasBuilder = SCons.Builder.Builder( - action=alias_builder, - target_factory=SCons.Node.Alias.default_ans.Alias, - source_factory=SCons.Node.FS.Entry, - multi=True, - is_explicit=None, - name='AliasBuilder', -) - -def apply_tools(env, tools, toolpath): - # Store the toolpath in the Environment. - if toolpath is not None: - env['toolpath'] = toolpath - - if not tools: - return - # Filter out null tools from the list. - for tool in [_f for _f in tools if _f]: - if is_List(tool) or isinstance(tool, tuple): - toolname = tool[0] - toolargs = tool[1] # should be a dict of kw args - tool = env.Tool(toolname, **toolargs) - else: - env.Tool(tool) - -# 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 = [ - 'CHANGED_SOURCES', - 'CHANGED_TARGETS', - 'SOURCE', - 'SOURCES', - 'TARGET', - 'TARGETS', - 'UNCHANGED_SOURCES', - 'UNCHANGED_TARGETS', -] - -future_reserved_construction_var_names = [ - #'HOST_OS', - #'HOST_ARCH', - #'HOST_CPU', - ] - -def copy_non_reserved_keywords(dict): - result = semi_deepcopy(dict) - for k in result.copy().keys(): - if k in reserved_construction_var_names: - 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'" - 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: - bd = env._dict[key] - for k in bd.copy().keys(): - del bd[k] - except KeyError: - bd = BuilderDict(bd, env) - env._dict[key] = bd - for k, v in value.items(): - if not SCons.Builder.is_a_Builder(v): - raise UserError('%s is not a Builder.' % repr(v)) - bd.update(value) - -def _del_SCANNERS(env, key): - del env._dict[key] - env.scanner_map_delete() - -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=set() - result=[] - if keep_last: # reverse in & out, then keep first - l.reverse() - for i in l: - try: - if i not in seen: - result.append(i) - seen.add(i) - 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 -# Shannon at the following page (there called the "transplant" class): -# -# ASPN : Python Cookbook : Dynamically added methods to a class -# https://code.activestate.com/recipes/81732/ -# -# We had independently been using the idiom as BuilderWrapper, but -# factoring out the common parts into this base class, and making -# BuilderWrapper a subclass that overrides __call__() to enforce specific -# Builder calling conventions, simplified some of our higher-layer code. -# -# Note: MethodWrapper moved to SCons.Util as it was needed there -# and otherwise we had a circular import problem. - -class BuilderWrapper(MethodWrapper): - """ - A MethodWrapper subclass that that associates an environment with - a Builder. - - This mainly exists to wrap the __call__() function so that all calls - to Builders can have their argument lists massaged in the same way - (treat a lone argument as the source, treat two arguments as target - then source, make sure both target and source are lists) without - having to have cut-and-paste code to do it. - - As a bit of obsessive backwards compatibility, we also intercept - attempts to get or set the "env" or "builder" attributes, which were - the names we used before we put the common functionality into the - MethodWrapper base class. We'll keep this around for a while in case - people shipped Tool modules that reached into the wrapper (like the - Tool/qt.py module does, or did). There shouldn't be a lot attribute - fetching or setting on these, so a little extra work shouldn't hurt. - """ - def __call__(self, target=None, source=_null, *args, **kw): - if source is _null: - source = target - target = None - if target is not None and not is_List(target): - target = [target] - if source is not None and not is_List(source): - source = [source] - return super().__call__(target, source, *args, **kw) - - def __repr__(self): - return '' % repr(self.name) - - def __str__(self): - return self.__repr__() - - def __getattr__(self, name): - if name == 'env': - return self.object - elif name == 'builder': - return self.method - else: - raise AttributeError(name) - - def __setattr__(self, name, value): - if name == 'env': - self.object = value - elif name == 'builder': - self.method = value - else: - self.__dict__[name] = value - - # This allows a Builder to be executed directly - # through the Environment to which it's attached. - # In practice, we shouldn't need this, because - # builders actually get executed through a Node. - # But we do have a unit test for this, and can't - # yet rule out that it would be useful in the - # future, so leave it for now. - #def execute(self, **kw): - # kw['env'] = self.env - # self.builder.execute(**kw) - -class BuilderDict(UserDict): - """This is a dictionary-like class used by an Environment to hold - the Builders. We need to do this because every time someone changes - the Builders in the Environment's BUILDERS dictionary, we must - update the Environment's attributes.""" - def __init__(self, dict, env): - # Set self.env before calling the superclass initialization, - # because it will end up calling our other methods, which will - # need to point the values in this dictionary to self.env. - self.env = env - UserDict.__init__(self, dict) - - def __semi_deepcopy__(self): - # These cannot be copied since they would both modify the same builder object, and indeed - # just copying would modify the original builder - raise TypeError( 'cannot semi_deepcopy a BuilderDict' ) - - def __setitem__(self, item, val): - try: - method = getattr(self.env, item).method - except AttributeError: - pass - else: - self.env.RemoveMethod(method) - UserDict.__setitem__(self, item, val) - BuilderWrapper(self.env, val, item) - - def __delitem__(self, item): - UserDict.__delitem__(self, item) - delattr(self.env, item) - - def update(self, dict): - 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. - - This class contains a minimal set of methods that handle construction - variable expansion and conversion of strings to Nodes, which may or - may not be actually useful as a stand-alone class. Which methods - ended up in this class is pretty arbitrary right now. They're - basically the ones which we've empirically determined are common to - the different construction environment subclasses, and most of the - others that use or touch the underlying dictionary of construction - variables. - - Eventually, this class should contain all the methods that we - determine are necessary for a "minimal" interface to the build engine. - A full "native Python" SCons environment has gotten pretty heavyweight - with all of the methods and Tools and construction variables we've - jammed in there, so it would be nice to have a lighter weight - alternative for interfaces that don't need all of the bells and - whistles. (At some point, we'll also probably rename this class - "Base," since that more reflects what we want this class to become, - but because we've released comments that tell people to subclass - Environment.Base to create their own flavors of construction - environment, we'll save that for a future refactoring when this - class actually becomes useful.) - """ - - def __init__(self, **kw): - """Initialization of an underlying SubstitutionEnvironment class. - """ - if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.SubstitutionEnvironment') - self.fs = SCons.Node.FS.get_default_fs() - self.ans = SCons.Node.Alias.default_ans - self.lookup_list = SCons.Node.arg2nodes_lookups - self._dict = kw.copy() - self._init_special() - self.added_methods = [] - #self._memo = {} - - def _init_special(self): - """Initial the dispatch tables for special handling of - special construction variables.""" - self._special_del = {} - self._special_del['SCANNERS'] = _del_SCANNERS - - 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 = list(self._special_set.keys()) - - def __eq__(self, other): - return self._dict == other._dict - - def __delitem__(self, key): - special = self._special_del.get(key) - if special: - special(self, key) - else: - del self._dict[key] - - def __getitem__(self, key): - return self._dict[key] - - def __setitem__(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 than 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 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 key not in self._dict and not _is_valid_var.match(key): - raise UserError("Illegal construction variable `%s'" % key) - self._dict[key] = value - - def get(self, key, default=None): - """Emulates the get() method of dictionaries.""" - return self._dict.get(key, default) - - def has_key(self, key): - """Emulates the has_key() method of dictionaries.""" - return key in self._dict - - def __contains__(self, key): - return self._dict.__contains__(key) - - def keys(self): - """Emulates the keys() method of dictionaries.""" - return self._dict.keys() - - def values(self): - """Emulates the values() method of dictionaries.""" - return self._dict.values() - - def items(self): - """Emulates the items() method of dictionaries.""" - return self._dict.items() - - def setdefault(self, key, default=None): - """Emulates the setdefault() method of dictionaries.""" - return self._dict.setdefault(key, default) - - def arg2nodes(self, args, node_factory=_null, lookup_list=_null, **kw): - if node_factory is _null: - node_factory = self.fs.File - if lookup_list is _null: - lookup_list = self.lookup_list - - if not args: - return [] - - args = flatten(args) - - nodes = [] - for v in args: - if is_String(v): - n = None - for l in lookup_list: - n = l(v) - if n is not None: - break - if n is not None: - if is_String(n): - # n = self.subst(n, raw=1, **kw) - kw['raw'] = 1 - n = self.subst(n, **kw) - if node_factory: - n = node_factory(n) - if is_List(n): - nodes.extend(n) - else: - nodes.append(n) - elif node_factory: - # v = node_factory(self.subst(v, raw=1, **kw)) - kw['raw'] = 1 - v = node_factory(self.subst(v, **kw)) - if is_List(v): - nodes.extend(v) - else: - nodes.append(v) - else: - nodes.append(v) - - return nodes - - def gvars(self): - return self._dict - - def lvars(self): - return {} - - def subst(self, string, raw=0, target=None, source=None, conv=None, executor=None): - """Recursively interpolates construction variables from the - Environment into the specified string, returning the expanded - result. Construction variables are specified by a $ prefix - in the string and begin with an initial underscore or - alphabetic character followed by any number of underscores - or alphanumeric characters. The construction variable names - may be surrounded by curly braces to separate the name from - trailing characters. - """ - gvars = self.gvars() - lvars = self.lvars() - lvars['__env__'] = self - if executor: - lvars.update(executor.get_lvars()) - return SCons.Subst.scons_subst(string, self, raw, target, source, gvars, lvars, conv) - - def subst_kw(self, kw, raw=0, target=None, source=None): - nkw = {} - for k, v in kw.items(): - k = self.subst(k, raw, target, source) - if is_String(v): - v = self.subst(v, raw, target, source) - nkw[k] = v - return nkw - - def subst_list(self, string, raw=0, target=None, source=None, conv=None, executor=None): - """Calls through to SCons.Subst.scons_subst_list(). See - the documentation for that function.""" - gvars = self.gvars() - lvars = self.lvars() - lvars['__env__'] = self - if executor: - lvars.update(executor.get_lvars()) - return SCons.Subst.scons_subst_list(string, self, raw, target, source, gvars, lvars, conv) - - def subst_path(self, path, target=None, source=None): - """Substitute a path list, turning EntryProxies into Nodes - and leaving Nodes (and other objects) as-is.""" - - if not is_List(path): - path = [path] - - def s(obj): - """This is the "string conversion" routine that we have our - substitutions use to return Nodes, not strings. This relies - on the fact that an EntryProxy object has a get() method that - returns the underlying Node that it wraps, which is a bit of - architectural dependence that we might need to break or modify - in the future in response to additional requirements.""" - try: - get = obj.get - except AttributeError: - obj = to_String_for_subst(obj) - else: - obj = get() - return obj - - r = [] - for p in path: - if is_String(p): - p = self.subst(p, target=target, source=source, conv=s) - if is_List(p): - if len(p) == 1: - p = p[0] - else: - # 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 = ''.join(map(to_String_for_subst, p)) - else: - p = s(p) - r.append(p) - return r - - subst_target_source = subst - - def backtick(self, command): - import subprocess - # 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 is_List(command): kw['shell'] = True - # run constructed command - p = SCons.Action._subproc(self, command, **kw) - out,err = p.communicate() - status = p.wait() - if err: - sys.stderr.write("" + err) - if status: - raise OSError("'%s' exited %d" % (command, status)) - return out - - def AddMethod(self, function, name=None): - """ - Adds the specified function as a method of this construction - environment with the specified name. If the name is omitted, - the default name is the name of the function itself. - """ - method = MethodWrapper(self, function, name) - self.added_methods.append(method) - - def RemoveMethod(self, function): - """ - Removes the specified function's MethodWrapper from the - added_methods list, so we don't re-bind it when making a clone. - """ - self.added_methods = [dm for dm in self.added_methods if dm.method is not function] - - def Override(self, overrides): - """ - Produce a modified environment whose variables are overridden by - the overrides dictionaries. "overrides" is a dictionary that - will override the variables of this environment. - - This function is much more efficient than Clone() or creating - a new Environment because it doesn't copy the construction - environment dictionary, it just wraps the underlying construction - environment, and doesn't even create a wrapper object if there - are no overrides. - """ - 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) - env = OverrideEnvironment(self, overrides) - if merges: - env.MergeFlags(merges) - return env - - def ParseFlags(self, *flags): - """Return a dict of parsed flags. - - Parse ``flags`` and return a dict with the flags distributed into - the appropriate construction variable names. The flags are treated - as a typical set of command-line flags for a GNU-like toolchain, - such as might have been generated by one of the {foo}-config scripts, - and used to populate the entries based on knowledge embedded in - this method - the choices are not expected to be portable to other - toolchains. - - If one of the ``flags`` strings begins with a bang (exclamation mark), - it is assumed to be a command and the rest of the string is executed; - the result of that evaluation is then added to the dict. - """ - dict = { - 'ASFLAGS' : CLVar(''), - 'CFLAGS' : CLVar(''), - 'CCFLAGS' : CLVar(''), - 'CXXFLAGS' : CLVar(''), - 'CPPDEFINES' : [], - 'CPPFLAGS' : CLVar(''), - 'CPPPATH' : [], - 'FRAMEWORKPATH' : CLVar(''), - 'FRAMEWORKS' : CLVar(''), - 'LIBPATH' : [], - 'LIBS' : [], - 'LINKFLAGS' : CLVar(''), - 'RPATH' : [], - } - - def do_parse(arg): - # if arg is a sequence, recurse with each element - if not arg: - return - - if not is_String(arg): - for t in arg: do_parse(t) - return - - # if arg is a command, execute it - if arg[0] == '!': - arg = self.backtick(arg[1:]) - - # utility function to deal with -D option - def append_define(name, dict = dict): - t = name.split('=') - if len(t) == 1: - dict['CPPDEFINES'].append(name) - else: - dict['CPPDEFINES'].append([t[0], '='.join(t[1:])]) - - # Loop through the flags and add them to the appropriate option. - # This tries to strike a balance between checking for all possible - # flags and keeping the logic to a finite size, so it doesn't - # check for some that don't occur often. It particular, if the - # flag is not known to occur in a config script and there's a way - # of passing the flag to the right place (by wrapping it in a -W - # flag, for example) we don't check for it. Note that most - # preprocessor options are not handled, since unhandled options - # are placed in CCFLAGS, so unless the preprocessor is invoked - # separately, these flags will still get to the preprocessor. - # Other options not currently handled: - # -iqoutedir (preprocessor search path) - # -u symbol (linker undefined symbol) - # -s (linker strip files) - # -static* (linker static binding) - # -shared* (linker dynamic binding) - # -symbolic (linker global binding) - # -R dir (deprecated linker rpath) - # IBM compilers may also accept -qframeworkdir=foo - - params = shlex.split(arg) - append_next_arg_to = None # for multi-word args - for arg in params: - if append_next_arg_to: - if append_next_arg_to == 'CPPDEFINES': - append_define(arg) - elif append_next_arg_to == '-include': - t = ('-include', self.fs.File(arg)) - dict['CCFLAGS'].append(t) - elif append_next_arg_to == '-imacros': - t = ('-imacros', self.fs.File(arg)) - dict['CCFLAGS'].append(t) - elif append_next_arg_to == '-isysroot': - t = ('-isysroot', arg) - dict['CCFLAGS'].append(t) - dict['LINKFLAGS'].append(t) - elif append_next_arg_to == '-isystem': - t = ('-isystem', arg) - dict['CCFLAGS'].append(t) - elif append_next_arg_to == '-iquote': - t = ('-iquote', arg) - dict['CCFLAGS'].append(t) - elif append_next_arg_to == '-idirafter': - t = ('-idirafter', arg) - dict['CCFLAGS'].append(t) - elif append_next_arg_to == '-arch': - t = ('-arch', arg) - dict['CCFLAGS'].append(t) - dict['LINKFLAGS'].append(t) - elif append_next_arg_to == '--param': - t = ('--param', arg) - dict['CCFLAGS'].append(t) - else: - dict[append_next_arg_to].append(arg) - append_next_arg_to = None - elif not arg[0] in ['-', '+']: - dict['LIBS'].append(self.fs.File(arg)) - elif arg == '-dylib_file': - dict['LINKFLAGS'].append(arg) - append_next_arg_to = 'LINKFLAGS' - elif arg[:2] == '-L': - if arg[2:]: - dict['LIBPATH'].append(arg[2:]) - else: - append_next_arg_to = 'LIBPATH' - elif arg[:2] == '-l': - if arg[2:]: - dict['LIBS'].append(arg[2:]) - else: - append_next_arg_to = 'LIBS' - elif arg[:2] == '-I': - if arg[2:]: - dict['CPPPATH'].append(arg[2:]) - else: - append_next_arg_to = 'CPPPATH' - elif arg[:4] == '-Wa,': - dict['ASFLAGS'].append(arg[4:]) - dict['CCFLAGS'].append(arg) - elif arg[:4] == '-Wl,': - if arg[:11] == '-Wl,-rpath=': - dict['RPATH'].append(arg[11:]) - elif arg[:7] == '-Wl,-R,': - dict['RPATH'].append(arg[7:]) - elif arg[:6] == '-Wl,-R': - dict['RPATH'].append(arg[6:]) - else: - dict['LINKFLAGS'].append(arg) - elif arg[:4] == '-Wp,': - dict['CPPFLAGS'].append(arg) - elif arg[:2] == '-D': - if arg[2:]: - append_define(arg[2:]) - else: - append_next_arg_to = 'CPPDEFINES' - elif arg == '-framework': - append_next_arg_to = 'FRAMEWORKS' - elif arg[:14] == '-frameworkdir=': - dict['FRAMEWORKPATH'].append(arg[14:]) - elif arg[:2] == '-F': - if arg[2:]: - dict['FRAMEWORKPATH'].append(arg[2:]) - else: - append_next_arg_to = 'FRAMEWORKPATH' - elif arg in [ - '-mno-cygwin', - '-pthread', - '-openmp', - '-fmerge-all-constants', - '-fopenmp', - ]: - dict['CCFLAGS'].append(arg) - dict['LINKFLAGS'].append(arg) - elif arg == '-mwindows': - dict['LINKFLAGS'].append(arg) - elif arg[:5] == '-std=': - if '++' in arg[5:]: - key='CXXFLAGS' - else: - key='CFLAGS' - dict[key].append(arg) - elif arg[0] == '+': - dict['CCFLAGS'].append(arg) - dict['LINKFLAGS'].append(arg) - elif arg in [ - '-include', - '-imacros', - '-isysroot', - '-isystem', - '-iquote', - '-idirafter', - '-arch', - '--param', - ]: - append_next_arg_to = arg - else: - dict['CCFLAGS'].append(arg) - - for arg in flags: - do_parse(arg) - return dict - - def MergeFlags(self, args, unique=True): - """Merge flags into construction variables. - - Merges the flags from ``args`` into this construction environent. - If ``args`` is not a dict, it is first converted to a dictionary with - flags distributed into appropriate construction variables. - See :meth:`ParseFlags`. - - Args: - args: flags to merge - unique: merge flags rather than appending (default: True) - - """ - if not is_Dict(args): - args = self.ParseFlags(args) - - if not unique: - self.Append(**args) - return - - for key, value in args.items(): - if not value: - continue - value = Split(value) - try: - orig = self[key] - except KeyError: - orig = value - else: - if not orig: - orig = value - elif value: - # Add orig and value. The logic here was lifted from - # part of env.Append() (see there for a lot of comments - # about the order in which things are tried) and is - # used mainly to handle coercion of strings to CLVar to - # "do the right thing" given (e.g.) an original CCFLAGS - # string variable like '-pipe -Wall'. - try: - orig = orig + value - except (KeyError, TypeError): - try: - add_to_orig = orig.append - except AttributeError: - value.insert(0, orig) - orig = value - else: - add_to_orig(value) - t = [] - if key[-4:] == 'PATH': - ### keep left-most occurence - for v in orig: - if v not in t: - t.append(v) - else: - ### keep right-most occurence - for v in orig[::-1]: - if v not in t: - t.insert(0, v) - self[key] = t - - -def default_decide_source(dependency, target, prev_ni, repo_node=None): - f = SCons.Defaults.DefaultEnvironment().decide_source - return f(dependency, target, prev_ni, repo_node) - - -def default_decide_target(dependency, target, prev_ni, repo_node=None): - f = SCons.Defaults.DefaultEnvironment().decide_target - return f(dependency, target, prev_ni, repo_node) - - -def default_copy_from_cache(src, dst): - f = SCons.Defaults.DefaultEnvironment().copy_from_cache - return f(src, dst) - - -class Base(SubstitutionEnvironment): - """Base class for "real" construction Environments. - - These are the primary objects used to communicate dependency - and construction information to the build engine. - - Keyword arguments supplied when the construction Environment - is created are construction variables used to initialize the - Environment. - """ - - ####################################################################### - # This is THE class for interacting with the SCons build engine, - # and it contains a lot of stuff, so we're going to try to keep this - # a little organized by grouping the methods. - ####################################################################### - - ####################################################################### - # Methods that make an Environment act like a dictionary. These have - # the expected standard names for Python mapping objects. Note that - # we don't actually make an Environment a subclass of UserDict for - # performance reasons. Note also that we only supply methods for - # dictionary functionality that we actually need and use. - ####################################################################### - - def __init__( - self, - platform=None, - tools=None, - toolpath=None, - variables=None, - parse_flags=None, - **kw - ): - """Initialization of a basic SCons construction environment. - - Sets up special construction variables like BUILDER, - PLATFORM, etc., and searches for and applies available Tools. - - Note that we do *not* call the underlying base class - (SubsitutionEnvironment) initialization, because we need to - initialize things in a very specific order that doesn't work - with the much simpler base class initialization. - """ - if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.Base') - self._memo = {} - self.fs = SCons.Node.FS.get_default_fs() - self.ans = SCons.Node.Alias.default_ans - self.lookup_list = SCons.Node.arg2nodes_lookups - self._dict = semi_deepcopy(SCons.Defaults.ConstructionEnvironment) - self._init_special() - self.added_methods = [] - - # We don't use AddMethod, or define these as methods in this - # class, because we *don't* want these functions to be bound - # methods. They need to operate independently so that the - # settings will work properly regardless of whether a given - # target ends up being built with a Base environment or an - # OverrideEnvironment or what have you. - self.decide_target = default_decide_target - self.decide_source = default_decide_source - - self.copy_from_cache = default_copy_from_cache - - self._dict['BUILDERS'] = BuilderDict(self._dict['BUILDERS'], self) - - if platform is None: - platform = self._dict.get('PLATFORM', None) - if platform is None: - platform = SCons.Platform.Platform() - if is_String(platform): - platform = SCons.Platform.Platform(platform) - self._dict['PLATFORM'] = str(platform) - platform(self) - - self._dict['HOST_OS'] = self._dict.get('HOST_OS',None) - self._dict['HOST_ARCH'] = self._dict.get('HOST_ARCH',None) - - # Now set defaults for TARGET_{OS|ARCH} - self._dict['TARGET_OS'] = self._dict.get('TARGET_OS',None) - self._dict['TARGET_ARCH'] = self._dict.get('TARGET_ARCH',None) - - - # Apply the passed-in and customizable variables to the - # environment before calling the tools, because they may use - # some of them during initialization. - if 'options' in kw: - # Backwards compatibility: they may stll be using the - # old "options" keyword. - variables = kw['options'] - del kw['options'] - self.Replace(**kw) - keys = list(kw.keys()) - if variables: - keys = keys + list(variables.keys()) - variables.Update(self) - - save = {} - for k in keys: - try: - save[k] = self._dict[k] - except KeyError: - # No value may have been set if they tried to pass in a - # reserved variable name like TARGETS. - pass - - SCons.Tool.Initializers(self) - - if tools is None: - tools = self._dict.get('TOOLS', None) - if tools is None: - tools = ['default'] - apply_tools(self, tools, toolpath) - - # 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. - ####################################################################### - - def get_builder(self, name): - """Fetch the builder with the specified name from the environment. - """ - try: - return self._dict['BUILDERS'][name] - except KeyError: - return None - - def get_CacheDir(self): - try: - path = self._CacheDir_path - except AttributeError: - 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 - construction environment. - """ - name = default - try: - is_node = issubclass(factory, SCons.Node.FS.Base) - except TypeError: - # The specified factory isn't a Node itself--it's - # most likely None, or possibly a callable. - pass - else: - if is_node: - # The specified factory is a Node (sub)class. Try to - # return the FS method that corresponds to the Node's - # name--that is, we return self.fs.Dir if they want a Dir, - # self.fs.File for a File, etc. - try: name = factory.__name__ - except AttributeError: pass - else: factory = None - if not factory: - # They passed us None, or we picked up a name from a specified - # class, so return the FS method. (Note that we *don't* - # use our own self.{Dir,File} methods because that would - # cause env.subst() to be called twice on the file name, - # interfering with files that have $$ in them.) - factory = getattr(self.fs, name) - return factory - - @SCons.Memoize.CountMethodCall - def _gsm(self): - try: - return self._memo['_gsm'] - except KeyError: - pass - - result = {} - - try: - scanners = self._dict['SCANNERS'] - except KeyError: - pass - else: - # Reverse the scanner list so that, if multiple scanners - # claim they can scan the same suffix, earlier scanners - # in the list will overwrite later scanners, so that - # the result looks like a "first match" to the user. - if not is_List(scanners): - scanners = [scanners] - else: - scanners = scanners[:] # copy so reverse() doesn't mod original - scanners.reverse() - for scanner in scanners: - for k in scanner.get_skeys(self): - if k and self['PLATFORM'] == 'win32': - k = k.lower() - result[k] = scanner - - self._memo['_gsm'] = result - - return result - - def get_scanner(self, skey): - """Find the appropriate scanner given a key (usually a file suffix). - """ - if skey and self['PLATFORM'] == 'win32': - skey = skey.lower() - return self._gsm().get(skey) - - def scanner_map_delete(self, kw=None): - """Delete the cached scanner map (if we need to). - """ - try: - del self._memo['_gsm'] - except KeyError: - pass - - def _update(self, other): - """Private method to update an environment's consvar dict directly. - - Bypasses the normal checks that occur when users try to set items. - """ - self._dict.update(other) - - def _update_onlynew(self, other): - """Private method to add new items to an environment's consvar dict. - - Only adds items from `other` whose keys do not already appear in - the existing dict; values from `other` are not used for replacement. - Bypasses the normal checks that occur when users try to set items. - """ - for k, v in other.items(): - if k not in self._dict: - self._dict[k] = v - - - def get_src_sig_type(self): - try: - return self.src_sig_type - except AttributeError: - t = SCons.Defaults.DefaultEnvironment().src_sig_type - self.src_sig_type = t - return t - - def get_tgt_sig_type(self): - try: - return self.tgt_sig_type - except AttributeError: - t = SCons.Defaults.DefaultEnvironment().tgt_sig_type - self.tgt_sig_type = t - return t - - ####################################################################### - # Public methods for manipulating an Environment. These begin with - # upper-case letters. The essential characteristic of methods in - # this section is that they do *not* have corresponding same-named - # global functions. For example, a stand-alone Append() function - # makes no sense, because Append() is all about appending values to - # an Environment's construction variables. - ####################################################################### - - def Append(self, **kw): - """Append values to construction variables in an Environment. - - The variable is created if it is not already present. - """ - - kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): - try: - if key == 'CPPDEFINES' and is_String(self._dict[key]): - self._dict[key] = [self._dict[key]] - orig = self._dict[key] - except KeyError: - # No existing var in the environment, so set to the new value. - if key == 'CPPDEFINES' and is_String(val): - self._dict[key] = [val] - else: - self._dict[key] = val - continue - - try: - # Check if the original looks like a dict: has .update? - update_dict = orig.update - except AttributeError: - try: - # Just try to add them together. This will work - # in most cases, when the original and new values - # are compatible types. - self._dict[key] = orig + val - except (KeyError, TypeError): - try: - # Check if the original is a list: has .append? - add_to_orig = orig.append - except AttributeError: - # The original isn't a list, but the new - # value is (by process of elimination), - # so insert the original in the new value - # (if there's one to insert) and replace - # the variable with it. - if orig: - val.insert(0, orig) - self._dict[key] = val - else: - # The original is a list, so append the new - # value to it (if there's a value to append). - if val: - add_to_orig(val) - continue - - # The original looks like a dictionary, so update it - # based on what we think the value looks like. - # We can't just try adding the value because - # dictionaries don't have __add__() methods, and - # things like UserList will incorrectly coerce the - # original dict to a list (which we don't want). - if is_List(val): - if key == 'CPPDEFINES': - tmp = [] - for (k, v) in orig.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - orig = tmp - orig += val - self._dict[key] = orig - else: - for v in val: - orig[v] = None - else: - try: - update_dict(val) - except (AttributeError, TypeError, ValueError): - if is_Dict(val): - for k, v in val.items(): - orig[k] = v - else: - orig[val] = None - - self.scanner_map_delete(kw) - - def _canonicalize(self, path): - """Allow Dirs and strings beginning with # for top-relative. - - Note this uses the current env's fs (in self). - """ - if not is_String(path): # typically a Dir - path = str(path) - if path and path[0] == '#': - path = str(self.fs.Dir(path)) - return path - - def AppendENVPath(self, name, newpath, envname = 'ENV', - sep = os.pathsep, delete_existing=0): - """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 envname in self._dict and name in self._dict[envname]: - orig = self._dict[envname][name] - - nv = AppendPath(orig, newpath, sep, delete_existing, canonicalize=self._canonicalize) - - if envname not in self._dict: - self._dict[envname] = {} - - self._dict[envname][name] = nv - - 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 is_List(val): - val = _delete_duplicates(val, delete_existing) - if key not in self._dict or self._dict[key] in ('', None): - self._dict[key] = val - elif is_Dict(self._dict[key]) and is_Dict(val): - self._dict[key].update(val) - elif is_List(val): - dk = self._dict[key] - if key == 'CPPDEFINES': - tmp = [] - for i in val: - if is_List(i): - if len(i) >= 2: - tmp.append((i[0], i[1])) - else: - tmp.append((i[0],)) - elif is_Tuple(i): - tmp.append(i) - else: - tmp.append((i,)) - val = tmp - # Construct a list of (key, value) tuples. - if is_Dict(dk): - tmp = [] - for (k, v) in dk.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - dk = tmp - elif is_String(dk): - dk = [(dk,)] - else: - tmp = [] - for i in dk: - if is_List(i): - if len(i) >= 2: - tmp.append((i[0], i[1])) - else: - tmp.append((i[0],)) - elif is_Tuple(i): - tmp.append(i) - else: - tmp.append((i,)) - dk = tmp - else: - if not is_List(dk): - dk = [dk] - if delete_existing: - dk = [x for x in dk if x not in val] - else: - val = [x for x in val if x not in dk] - self._dict[key] = dk + val - else: - dk = self._dict[key] - if is_List(dk): - if key == 'CPPDEFINES': - tmp = [] - for i in dk: - if is_List(i): - if len(i) >= 2: - tmp.append((i[0], i[1])) - else: - tmp.append((i[0],)) - elif is_Tuple(i): - tmp.append(i) - else: - tmp.append((i,)) - dk = tmp - # Construct a list of (key, value) tuples. - if is_Dict(val): - tmp = [] - for (k, v) in val.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - val = tmp - elif is_String(val): - val = [(val,)] - if delete_existing: - dk = list(filter(lambda x, val=val: x not in val, dk)) - self._dict[key] = dk + val - else: - dk = [x for x in dk if x not in val] - self._dict[key] = dk + val - else: - # By elimination, val is not a list. Since dk is a - # list, wrap val in a list first. - if delete_existing: - dk = list(filter(lambda x, val=val: x not in val, dk)) - self._dict[key] = dk + [val] - else: - if val not in dk: - self._dict[key] = dk + [val] - else: - if key == 'CPPDEFINES': - if is_String(dk): - dk = [dk] - elif is_Dict(dk): - tmp = [] - for (k, v) in dk.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - dk = tmp - if is_String(val): - if val in dk: - val = [] - else: - val = [val] - elif is_Dict(val): - tmp = [] - for i,j in val.items(): - if j is not None: - tmp.append((i,j)) - else: - tmp.append(i) - val = tmp - if delete_existing: - dk = [x for x in dk if x not in val] - self._dict[key] = dk + val - self.scanner_map_delete(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 - a reference is copied when an object is not deep-copyable - (like a function). There are no references to any mutable - objects in the original Environment. - """ - - builders = self._dict.get('BUILDERS', {}) - - clone = copy.copy(self) - # BUILDERS is not safe to do a simple copy - clone._dict = semi_deepcopy_dict(self._dict, ['BUILDERS']) - clone._dict['BUILDERS'] = BuilderDict(builders, 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: - if mw == getattr(self, mw.name): - clone.added_methods.append(mw.clone(clone)) - - clone._memo = {} - - # Apply passed-in variables before the tools - # so the tools can use the new variables - kw = copy_non_reserved_keywords(kw) - new = {} - for key, value in kw.items(): - new[key] = SCons.Subst.scons_subst_once(value, self, key) - clone.Replace(**new) - - apply_tools(clone, tools, toolpath) - - # apply them again in case the tools overwrote them - clone.Replace(**new) - - # Finally, apply any flags to be merged in - if parse_flags: - clone.MergeFlags(parse_flags) - - if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.EnvironmentClone') - return clone - - def _changed_build(self, dependency, target, prev_ni, repo_node=None): - if dependency.changed_state(target, prev_ni, repo_node): - return 1 - return self.decide_source(dependency, target, prev_ni, repo_node) - - def _changed_content(self, dependency, target, prev_ni, repo_node=None): - return dependency.changed_content(target, prev_ni, repo_node) - - def _changed_source(self, dependency, target, prev_ni, repo_node=None): - target_env = dependency.get_build_env() - type = target_env.get_tgt_sig_type() - if type == 'source': - return target_env.decide_source(dependency, target, prev_ni, repo_node) - else: - return target_env.decide_target(dependency, target, prev_ni, repo_node) - - def _changed_timestamp_then_content(self, dependency, target, prev_ni, repo_node=None): - return dependency.changed_timestamp_then_content(target, prev_ni, repo_node) - - def _changed_timestamp_newer(self, dependency, target, prev_ni, repo_node=None): - return dependency.changed_timestamp_newer(target, prev_ni, repo_node) - - def _changed_timestamp_match(self, dependency, target, prev_ni, repo_node=None): - return dependency.changed_timestamp_match(target, prev_ni, repo_node) - - def _copy_from_cache(self, src, dst): - return self.fs.copy(src, dst) - - def _copy2_from_cache(self, src, dst): - return self.fs.copy2(src, dst) - - def Decider(self, function): - copy_function = self._copy2_from_cache - if function in ('MD5', 'content'): - if not md5: - raise UserError("MD5 signatures are not available in this version of Python.") - function = self._changed_content - elif function == 'MD5-timestamp': - function = self._changed_timestamp_then_content - elif function in ('timestamp-newer', 'make'): - function = self._changed_timestamp_newer - copy_function = self._copy_from_cache - elif function == 'timestamp-match': - function = self._changed_timestamp_match - elif not callable(function): - raise UserError("Unknown Decider value %s" % repr(function)) - - # We don't use AddMethod because we don't want to turn the - # function, which only expects three arguments, into a bound - # method, which would add self as an initial, fourth argument. - self.decide_target = function - self.decide_source = function - self.copy_from_cache = copy_function - - - def Detect(self, progs): - """Return the first available program from one or more possibilities. - - Args: - progs (str or list): one or more command names to check for - - """ - if not is_List(progs): - progs = [progs] - for prog in progs: - path = self.WhereIs(prog) - if path: return prog - return None - - - def Dictionary(self, *args): - r"""Return construction variables from an environment. - - Args: - \*args (optional): variable names to look up - - Returns: - If `args` omitted, the dictionary of all construction variables. - If one arg, the corresponding value is returned. - If more than one arg, a list of values is returned. - - Raises: - KeyError: if any of `args` is not in the construction environment. - - """ - if not args: - return self._dict - dlist = [self._dict[x] for x in args] - if len(dlist) == 1: - dlist = dlist[0] - return dlist - - - def Dump(self, key=None, format='pretty'): - """ Return construction variables serialized to a string. - - Args: - key (optional): if None, format the whole dict of variables. - Else format the value of `key` (Default value = None) - format (str, optional): specify the format to serialize to. - `"pretty"` generates a pretty-printed string, - `"json"` a JSON-formatted string. - (Default value = `"pretty"`) - - """ - if key: - cvars = self.Dictionary(key) - else: - cvars = self.Dictionary() - - fmt = format.lower() - - if fmt == 'pretty': - import pprint - pp = pprint.PrettyPrinter(indent=2) - - # TODO: pprint doesn't do a nice job on path-style values - # if the paths contain spaces (i.e. Windows), because the - # algorithm tries to break lines on spaces, while breaking - # on the path-separator would be more "natural". Is there - # a better way to format those? - return pp.pformat(cvars) - - elif fmt == 'json': - import json - def non_serializable(obj): - return str(type(obj).__qualname__) - return json.dumps(cvars, indent=4, default=non_serializable) - else: - raise ValueError("Unsupported serialization format: %s." % fmt) - - - def FindIxes(self, paths, prefix, suffix): - """Search a list of paths for something that matches the prefix and suffix. - - Args: - paths: the list of paths or nodes. - prefix: construction variable for the prefix. - suffix: construction variable for the suffix. - - Returns: the matched path or None - - """ - - suffix = self.subst('$'+suffix) - prefix = self.subst('$'+prefix) - - for path in paths: - name = os.path.basename(str(path)) - if name[:len(prefix)] == prefix and name[-len(suffix):] == suffix: - return path - - def ParseConfig(self, command, function=None, unique=True): - """ - Use the specified function to parse the output of the command - in order to modify the current environment. The 'command' can - be a string or a list of strings representing a command and - its arguments. 'Function' is an optional argument that takes - the environment, the output of the command, and the unique flag. - If no function is specified, MergeFlags, which treats the output - as the result of a typical 'X-config' command (i.e. gtk-config), - will merge the output into the appropriate variables. - """ - if function is None: - def parse_conf(env, cmd, unique=unique): - return env.MergeFlags(cmd, unique) - function = parse_conf - if is_List(command): - command = ' '.join(command) - command = self.subst(command) - return function(self, self.backtick(command)) - - def ParseDepends(self, filename, must_exist=None, only_one=False): - """ - Parse a mkdep-style file for explicit dependencies. This is - completely abusable, and should be unnecessary in the "normal" - case of proper SCons configuration, but it may help make - the transition from a Make hierarchy easier for some people - to swallow. It can also be genuinely useful when using a tool - that can write a .d file, but for which writing a scanner would - be too complicated. - """ - filename = self.subst(filename) - try: - with open(filename, 'r') as fp: - lines = LogicalLines(fp).readlines() - except IOError: - if must_exist: - raise - return - lines = [l for l in lines if l[0] != '#'] - tdlist = [] - for line in lines: - try: - target, depends = line.split(':', 1) - except (AttributeError, ValueError): - # Throws AttributeError if line isn't a string. Can throw - # ValueError if line doesn't split into two or more elements. - pass - else: - tdlist.append((target.split(), depends.split())) - if only_one: - targets = [] - for td in tdlist: - targets.extend(td[0]) - if len(targets) > 1: - raise UserError( - "More than one dependency target found in `%s': %s" - % (filename, targets)) - for target, depends in tdlist: - self.Depends(target, depends) - - def Platform(self, platform): - platform = self.subst(platform) - return SCons.Platform.Platform(platform)(self) - - def Prepend(self, **kw): - """Prepend values to construction variables in an Environment. - - The variable is created if it is not already present. - """ - - kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): - try: - orig = self._dict[key] - except KeyError: - # No existing var in the environment so set to the new value. - self._dict[key] = val - continue - - try: - # Check if the original looks like a dict: has .update? - update_dict = orig.update - except AttributeError: - try: - # Just try to add them together. This will work - # in most cases, when the original and new values - # are compatible types. - self._dict[key] = val + orig - except (KeyError, TypeError): - try: - # Check if the added value is a list: has .append? - add_to_val = val.append - except AttributeError: - # The added value isn't a list, but the - # original is (by process of elimination), - # so insert the the new value in the original - # (if there's one to insert). - if val: - orig.insert(0, val) - else: - # The added value is a list, so append - # the original to it (if there's a value - # to append) and replace the original. - if orig: - add_to_val(orig) - self._dict[key] = val - continue - - # The original looks like a dictionary, so update it - # based on what we think the value looks like. - # We can't just try adding the value because - # dictionaries don't have __add__() methods, and - # things like UserList will incorrectly coerce the - # original dict to a list (which we don't want). - if is_List(val): - for v in val: - orig[v] = None - else: - try: - update_dict(val) - except (AttributeError, TypeError, ValueError): - if is_Dict(val): - for k, v in val.items(): - orig[k] = v - else: - orig[val] = None - - self.scanner_map_delete(kw) - - 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 envname in self._dict and name in self._dict[envname]: - orig = self._dict[envname][name] - - nv = PrependPath(orig, newpath, sep, delete_existing, - canonicalize=self._canonicalize) - - if envname not in self._dict: - self._dict[envname] = {} - - self._dict[envname][name] = nv - - 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 is_List(val): - val = _delete_duplicates(val, not delete_existing) - if key not in self._dict or self._dict[key] in ('', None): - self._dict[key] = val - elif is_Dict(self._dict[key]) and is_Dict(val): - self._dict[key].update(val) - elif is_List(val): - dk = self._dict[key] - if not is_List(dk): - dk = [dk] - if delete_existing: - dk = [x for x in dk if x not in val] - else: - val = [x for x in val if x not in dk] - self._dict[key] = val + dk - else: - dk = self._dict[key] - if is_List(dk): - # By elimination, val is not a list. Since dk is a - # list, wrap val in a list first. - if delete_existing: - dk = [x for x in dk if x not in val] - self._dict[key] = [val] + dk - else: - if val not in dk: - self._dict[key] = [val] + dk - else: - if delete_existing: - dk = [x for x in dk if x not in val] - self._dict[key] = val + dk - self.scanner_map_delete(kw) - - def Replace(self, **kw): - """Replace existing construction variables in an Environment - with new construction variables and/or values. - """ - try: - kwbd = kw['BUILDERS'] - except KeyError: - pass - else: - kwbd = BuilderDict(kwbd,self) - del kw['BUILDERS'] - self.__setitem__('BUILDERS', kwbd) - kw = copy_non_reserved_keywords(kw) - self._update(semi_deepcopy(kw)) - self.scanner_map_delete(kw) - - def ReplaceIxes(self, path, old_prefix, old_suffix, new_prefix, new_suffix): - """ - Replace old_prefix with new_prefix and old_suffix with new_suffix. - - env - Environment used to interpolate variables. - path - the path that will be modified. - old_prefix - construction variable for the old prefix. - old_suffix - construction variable for the old suffix. - new_prefix - construction variable for the new prefix. - new_suffix - construction variable for the new suffix. - """ - old_prefix = self.subst('$'+old_prefix) - old_suffix = self.subst('$'+old_suffix) - - new_prefix = self.subst('$'+new_prefix) - new_suffix = self.subst('$'+new_suffix) - - dir,name = os.path.split(str(path)) - if name[:len(old_prefix)] == old_prefix: - name = name[len(old_prefix):] - if name[-len(old_suffix):] == old_suffix: - name = name[:-len(old_suffix)] - return os.path.join(dir, new_prefix+name+new_suffix) - - def SetDefault(self, **kw): - for k in list(kw.keys()): - if k in self._dict: - del kw[k] - self.Replace(**kw) - - def _find_toolpath_dir(self, tp): - return self.fs.Dir(self.subst(tp)).srcnode().get_abspath() - - def Tool(self, tool, toolpath=None, **kw): - if is_String(tool): - tool = self.subst(tool) - if toolpath is None: - toolpath = self.get('toolpath', []) - toolpath = list(map(self._find_toolpath_dir, toolpath)) - tool = SCons.Tool.Tool(tool, toolpath, **kw) - tool(self) - - def WhereIs(self, prog, path=None, pathext=None, reject=[]): - """Find prog in the path. - """ - if path is None: - try: - path = self['ENV']['PATH'] - except KeyError: - pass - elif is_String(path): - path = self.subst(path) - if pathext is None: - try: - pathext = self['ENV']['PATHEXT'] - except KeyError: - pass - elif is_String(pathext): - pathext = self.subst(pathext) - prog = CLVar(self.subst(prog)) # support "program --with-args" - path = WhereIs(prog[0], path, pathext, reject) - if path: return path - return None - - ####################################################################### - # Public methods for doing real "SCons stuff" (manipulating - # dependencies, setting attributes on targets, etc.). These begin - # with upper-case letters. The essential characteristic of methods - # in this section is that they all *should* have corresponding - # same-named global functions. - ####################################################################### - - def Action(self, *args, **kw): - def subst_string(a, self=self): - if is_String(a): - a = self.subst(a) - return a - nargs = list(map(subst_string, args)) - nkw = self.subst_kw(kw) - return SCons.Action.Action(*nargs, **nkw) - - def AddPreAction(self, files, action): - nodes = self.arg2nodes(files, self.fs.Entry) - action = SCons.Action.Action(action) - uniq = {} - for executor in [n.get_executor() for n in nodes]: - uniq[executor] = 1 - for executor in uniq.keys(): - executor.add_pre_action(action) - return nodes - - def AddPostAction(self, files, action): - nodes = self.arg2nodes(files, self.fs.Entry) - action = SCons.Action.Action(action) - uniq = {} - for executor in [n.get_executor() for n in nodes]: - uniq[executor] = 1 - for executor in uniq.keys(): - executor.add_post_action(action) - return nodes - - def Alias(self, target, source=[], action=None, **kw): - tlist = self.arg2nodes(target, self.ans.Alias) - if not is_List(source): - source = [source] - source = [_f for _f in source if _f] - - if not action: - if not source: - # There are no source files and no action, so just - # return a target list of classic Alias Nodes, without - # any builder. The externally visible effect is that - # this will make the wrapping Script.BuildTask class - # say that there's "Nothing to be done" for this Alias, - # instead of that it's "up to date." - return tlist - - # No action, but there are sources. Re-call all the target - # builders to add the sources to each target. - result = [] - for t in tlist: - bld = t.get_builder(AliasBuilder) - result.extend(bld(self, t, source)) - return result - - nkw = self.subst_kw(kw) - nkw.update({ - 'action' : SCons.Action.Action(action), - 'source_factory' : self.fs.Entry, - 'multi' : 1, - 'is_explicit' : None, - }) - bld = SCons.Builder.Builder(**nkw) - - # Apply the Builder separately to each target so that the Aliases - # stay separate. If we did one "normal" Builder call with the - # whole target list, then all of the target Aliases would be - # associated under a single Executor. - result = [] - for t in tlist: - # Calling the convert() method will cause a new Executor to be - # created from scratch, so we have to explicitly initialize - # it with the target's existing sources, plus our new ones, - # so nothing gets lost. - b = t.get_builder() - if b is None or b is AliasBuilder: - b = bld - else: - nkw['action'] = b.action + action - b = SCons.Builder.Builder(**nkw) - t.convert() - result.extend(b(self, t, t.sources + source)) - return result - - def AlwaysBuild(self, *targets): - tlist = [] - for t in targets: - tlist.extend(self.arg2nodes(t, self.fs.Entry)) - for t in tlist: - t.set_always_build() - return tlist - - def Builder(self, **kw): - nkw = self.subst_kw(kw) - return SCons.Builder.Builder(**nkw) - - def CacheDir(self, path): - if path is not None: - path = self.subst(path) - self._CacheDir_path = path - - if SCons.Action.execute_actions: - # Only initialize the CacheDir if -n/-no_exec was NOT specified. - # Now initialized the CacheDir and prevent a race condition which can - # happen when there's no existing cache dir and you are building with - # multiple threads, but initializing it before the task walk starts - self.get_CacheDir() - - def Clean(self, targets, files): - global CleanTargets - tlist = self.arg2nodes(targets, self.fs.Entry) - flist = self.arg2nodes(files, self.fs.Entry) - for t in tlist: - try: - CleanTargets[t].extend(flist) - except KeyError: - CleanTargets[t] = flist - - def Configure(self, *args, **kw): - nargs = [self] - if args: - nargs = nargs + self.subst_list(args)[0] - nkw = self.subst_kw(kw) - nkw['_depth'] = kw.get('_depth', 0) + 1 - try: - nkw['custom_tests'] = self.subst_kw(nkw['custom_tests']) - except KeyError: - pass - return SCons.SConf.SConf(*nargs, **nkw) - - def Command(self, target, source, action, **kw): - """Builds the supplied target files from the supplied - source files using the supplied action. Action may - be any type that the Builder constructor will accept - for an action.""" - bkw = { - 'action': action, - 'target_factory': self.fs.Entry, - 'source_factory': self.fs.Entry, - } - # source scanner - try: - bkw['source_scanner'] = kw['source_scanner'] - except KeyError: - pass - else: - del kw['source_scanner'] - - # target scanner - try: - bkw['target_scanner'] = kw['target_scanner'] - except KeyError: - pass - else: - del kw['target_scanner'] - - # source factory - try: - bkw['source_factory'] = kw['source_factory'] - except KeyError: - pass - else: - del kw['source_factory'] - - # target factory - try: - bkw['target_factory'] = kw['target_factory'] - except KeyError: - pass - else: - del kw['target_factory'] - - bld = SCons.Builder.Builder(**bkw) - return bld(self, target, source, **kw) - - def Depends(self, target, dependency): - """Explicity specify that 'target's depend on 'dependency'.""" - tlist = self.arg2nodes(target, self.fs.Entry) - dlist = self.arg2nodes(dependency, self.fs.Entry) - for t in tlist: - t.add_dependency(dlist) - return tlist - - def Dir(self, name, *args, **kw): - """ - """ - s = self.subst(name) - if is_Sequence(s): - result=[] - for e in s: - result.append(self.fs.Dir(e, *args, **kw)) - return result - return self.fs.Dir(s, *args, **kw) - - def PyPackageDir(self, modulename): - s = self.subst(modulename) - if is_Sequence(s): - result=[] - for e in s: - result.append(self.fs.PyPackageDir(e)) - return result - return self.fs.PyPackageDir(s) - - def NoClean(self, *targets): - """Tags a target so that it will not be cleaned by -c""" - tlist = [] - for t in targets: - tlist.extend(self.arg2nodes(t, self.fs.Entry)) - for t in tlist: - t.set_noclean() - return tlist - - def NoCache(self, *targets): - """Tags a target so that it will not be cached""" - tlist = [] - for t in targets: - tlist.extend(self.arg2nodes(t, self.fs.Entry)) - for t in tlist: - t.set_nocache() - return tlist - - def Entry(self, name, *args, **kw): - """ - """ - s = self.subst(name) - if is_Sequence(s): - result=[] - for e in s: - result.append(self.fs.Entry(e, *args, **kw)) - return result - return self.fs.Entry(s, *args, **kw) - - def Environment(self, **kw): - return SCons.Environment.Environment(**self.subst_kw(kw)) - - def Execute(self, action, *args, **kw): - """Directly execute an action through an Environment - """ - action = self.Action(action, *args, **kw) - result = action([], [], self) - if isinstance(result, BuildError): - errstr = result.errstr - if result.filename: - errstr = result.filename + ': ' + errstr - sys.stderr.write("scons: *** %s\n" % errstr) - return result.status - else: - return result - - def File(self, name, *args, **kw): - """ - """ - s = self.subst(name) - if is_Sequence(s): - result=[] - for e in s: - result.append(self.fs.File(e, *args, **kw)) - return result - return self.fs.File(s, *args, **kw) - - def FindFile(self, file, dirs): - file = self.subst(file) - nodes = self.arg2nodes(dirs, self.fs.Dir) - return SCons.Node.FS.find_file(file, tuple(nodes)) - - def Flatten(self, sequence): - return flatten(sequence) - - def GetBuildPath(self, files): - result = list(map(str, self.arg2nodes(files, self.fs.Entry))) - if is_List(files): - return result - else: - return result[0] - - def Glob(self, pattern, ondisk=True, source=False, strings=False, exclude=None): - return self.fs.Glob(self.subst(pattern), ondisk, source, strings, exclude) - - def Ignore(self, target, dependency): - """Ignore a dependency.""" - tlist = self.arg2nodes(target, self.fs.Entry) - dlist = self.arg2nodes(dependency, self.fs.Entry) - for t in tlist: - t.add_ignore(dlist) - return tlist - - def Literal(self, string): - return SCons.Subst.Literal(string) - - def Local(self, *targets): - ret = [] - for targ in targets: - if isinstance(targ, SCons.Node.Node): - targ.set_local() - ret.append(targ) - else: - for t in self.arg2nodes(targ, self.fs.Entry): - t.set_local() - ret.append(t) - return ret - - def Precious(self, *targets): - tlist = [] - for t in targets: - tlist.extend(self.arg2nodes(t, self.fs.Entry)) - for t in tlist: - t.set_precious() - return tlist - - def Pseudo(self, *targets): - tlist = [] - for t in targets: - tlist.extend(self.arg2nodes(t, self.fs.Entry)) - for t in tlist: - t.set_pseudo() - return tlist - - def Repository(self, *dirs, **kw): - dirs = self.arg2nodes(list(dirs), self.fs.Dir) - self.fs.Repository(*dirs, **kw) - - def Requires(self, target, prerequisite): - """Specify that 'prerequisite' must be built before 'target', - (but 'target' does not actually depend on 'prerequisite' - and need not be rebuilt if it changes).""" - tlist = self.arg2nodes(target, self.fs.Entry) - plist = self.arg2nodes(prerequisite, self.fs.Entry) - for t in tlist: - t.add_prerequisite(plist) - return tlist - - def Scanner(self, *args, **kw): - nargs = [] - for arg in args: - if is_String(arg): - arg = self.subst(arg) - nargs.append(arg) - nkw = self.subst_kw(kw) - return SCons.Scanner.Base(*nargs, **nkw) - - def SConsignFile(self, name=".sconsign", dbm_module=None): - if name is not None: - 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): - """Tell scons that side_effects are built as side - effects of building targets.""" - side_effects = self.arg2nodes(side_effect, self.fs.Entry) - targets = self.arg2nodes(target, self.fs.Entry) - - added_side_effects = [] - for side_effect in side_effects: - if side_effect.multiple_side_effect_has_builder(): - raise UserError("Multiple ways to build the same target were specified for: %s" % str(side_effect)) - side_effect.add_source(targets) - side_effect.side_effect = 1 - self.Precious(side_effect) - added = False - for target in targets: - if side_effect not in target.side_effects: - target.side_effects.append(side_effect) - added = True - if added: - added_side_effects.append(side_effect) - return added_side_effects - - def Split(self, arg): - """This function converts a string or list into a list of strings - or Nodes. This makes things easier for users by allowing files to - be specified as a white-space separated list to be split. - - The input rules are: - - A single string containing names separated by spaces. These will be - split apart at the spaces. - - A single Node instance - - A list containing either strings or Node instances. Any strings - in the list are not split at spaces. - - In all cases, the function returns a list of Nodes and strings.""" - - if is_List(arg): - return list(map(self.subst, arg)) - elif is_String(arg): - return self.subst(arg).split() - else: - return [self.subst(arg)] - - def Value(self, value, built_value=None, name=None): - """ - """ - return SCons.Node.Python.ValueWithMemo(value, built_value, name) - - 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. - """ - node = self.arg2nodes(node, self.fs.Entry)[0] - - sources = [] - def build_source(ss): - for s in ss: - if isinstance(s, SCons.Node.FS.Dir): - build_source(s.all_children()) - elif s.has_builder(): - build_source(s.sources) - elif isinstance(s.disambiguate(), SCons.Node.FS.File): - sources.append(s) - build_source(node.all_children()) - - def final_source(node): - while node != node.srcnode(): - node = node.srcnode() - return node - sources = list(map(final_source, sources)) - # remove duplicates - return list(set(sources)) - - def FindInstalledFiles(self): - """ returns the list of all targets of the Install and InstallAs Builder. - """ - from SCons.Tool import install - if install._UNIQUE_INSTALLED_FILES is None: - install._UNIQUE_INSTALLED_FILES = uniquer_hashables(install._INSTALLED_FILES) - return install._UNIQUE_INSTALLED_FILES - - -class OverrideEnvironment(Base): - """A proxy that overrides variables in a wrapped construction - environment by returning values from an overrides dictionary in - preference to values from the underlying subject environment. - - This is a lightweight (I hope) proxy that passes through most use of - attributes to the underlying Environment.Base class, but has just - enough additional methods defined to act like a real construction - environment with overridden values. It can wrap either a Base - construction environment, or another OverrideEnvironment, which - can in turn nest arbitrary OverrideEnvironments... - - Note that we do *not* call the underlying base class - (SubsitutionEnvironment) initialization, because we get most of those - from proxying the attributes of the subject construction environment. - But because we subclass SubstitutionEnvironment, this class also - has inherited arg2nodes() and subst*() methods; those methods can't - be proxied because they need *this* object's methods to fetch the - values from the overrides dictionary. - """ - - def __init__(self, subject, overrides=None): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.OverrideEnvironment') - self.__dict__['__subject'] = subject - if overrides is None: - self.__dict__['overrides'] = dict() - else: - self.__dict__['overrides'] = overrides - - # Methods that make this class act like a proxy. - def __getattr__(self, name): - attr = getattr(self.__dict__['__subject'], name) - # Here we check if attr is one of the Wrapper classes. For - # example when a pseudo-builder is being called from an - # OverrideEnvironment. - # - # These wrappers when they're constructed capture the - # Environment they are being constructed with and so will not - # have access to overrided values. So we rebuild them with the - # OverrideEnvironment so they have access to overrided values. - if isinstance(attr, MethodWrapper): - return attr.clone(self) - else: - return attr - - def __setattr__(self, name, value): - setattr(self.__dict__['__subject'], name, value) - - # Methods that make this class act like a dictionary. - def __getitem__(self, key): - try: - return self.__dict__['overrides'][key] - except KeyError: - return self.__dict__['__subject'].__getitem__(key) - - def __setitem__(self, key, value): - if not is_valid_construction_var(key): - raise UserError("Illegal construction variable `%s'" % key) - self.__dict__['overrides'][key] = value - - def __delitem__(self, key): - try: - del self.__dict__['overrides'][key] - except KeyError: - deleted = 0 - else: - deleted = 1 - try: - result = self.__dict__['__subject'].__delitem__(key) - except KeyError: - if not deleted: - raise - result = None - return result - - def get(self, key, default=None): - """Emulates the get() method of dictionaries.""" - try: - return self.__dict__['overrides'][key] - except KeyError: - return self.__dict__['__subject'].get(key, default) - - def has_key(self, key): - """Emulates the has_key() method of dictionaries.""" - try: - self.__dict__['overrides'][key] - return 1 - except KeyError: - return key in self.__dict__['__subject'] - - def __contains__(self, key): - if self.__dict__['overrides'].__contains__(key): - return 1 - return self.__dict__['__subject'].__contains__(key) - - def Dictionary(self, *args): - d = self.__dict__['__subject'].Dictionary().copy() - d.update(self.__dict__['overrides']) - if not args: - return d - dlist = [d[x] for x in args] - if len(dlist) == 1: - dlist = dlist[0] - return dlist - - def items(self): - """Emulates the items() method of dictionaries.""" - return self.Dictionary().items() - - def keys(self): - """Emulates the keys() method of dictionaries.""" - return self.Dictionary().keys() - - def values(self): - """Emulates the values() method of dictionaries.""" - return self.Dictionary().values() - - def setdefault(self, key, default=None): - """Emulates the setdefault() method of dictionaries.""" - try: - return self.__getitem__(key) - except KeyError: - self.__dict__['overrides'][key] = default - return default - - # Overridden private construction environment methods. - def _update(self, other): - self.__dict__['overrides'].update(other) - - def _update_onlynew(self, other): - for k, v in other.items(): - if k not in self.__dict__['overrides']: - self.__dict__['overrides'][k] = v - - def gvars(self): - return self.__dict__['__subject'].gvars() - - def lvars(self): - lvars = self.__dict__['__subject'].lvars() - lvars.update(self.__dict__['overrides']) - return lvars - - # Overridden public construction environment methods. - def Replace(self, **kw): - kw = copy_non_reserved_keywords(kw) - self.__dict__['overrides'].update(semi_deepcopy(kw)) - - -# The entry point that will be used by the external world -# to refer to a construction environment. This allows the wrapper -# interface to extend a construction environment for its own purposes -# by subclassing SCons.Environment.Base and then assigning the -# class to SCons.Environment.Environment. - -Environment = Base - - -def NoSubstitutionProxy(subject): - """ - An entry point for returning a proxy subclass instance that overrides - the subst*() methods so they don't actually perform construction - variable substitution. This is specifically intended to be the shim - layer in between global function calls (which don't want construction - variable substitution) and the DefaultEnvironment() (which would - substitute variables if left to its own devices). - - We have to wrap this in a function that allows us to delay definition of - the class until it's necessary, so that when it subclasses Environment - it will pick up whatever Environment subclass the wrapper interface - might have assigned to SCons.Environment.Environment. - """ - class _NoSubstitutionProxy(Environment): - def __init__(self, subject): - self.__dict__['__subject'] = subject - def __getattr__(self, name): - return getattr(self.__dict__['__subject'], name) - def __setattr__(self, name, value): - return setattr(self.__dict__['__subject'], name, value) - def executor_to_lvars(self, kwdict): - if 'executor' in kwdict: - kwdict['lvars'] = kwdict['executor'].get_lvars() - del kwdict['executor'] - else: - kwdict['lvars'] = {} - def raw_to_mode(self, dict): - try: - raw = dict['raw'] - except KeyError: - pass - else: - del dict['raw'] - dict['mode'] = raw - def subst(self, string, *args, **kwargs): - return string - def subst_kw(self, kw, *args, **kwargs): - return kw - def subst_list(self, string, *args, **kwargs): - nargs = (string, self,) + args - nkw = kwargs.copy() - nkw['gvars'] = {} - self.executor_to_lvars(nkw) - self.raw_to_mode(nkw) - return SCons.Subst.scons_subst_list(*nargs, **nkw) - def subst_target_source(self, string, *args, **kwargs): - nargs = (string, self,) + args - nkw = kwargs.copy() - nkw['gvars'] = {} - self.executor_to_lvars(nkw) - self.raw_to_mode(nkw) - return SCons.Subst.scons_subst(*nargs, **nkw) - return _NoSubstitutionProxy(subject) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/EnvironmentValues.py b/scons/scons-local-4.1.0/SCons/EnvironmentValues.py deleted file mode 100644 index c5eb972c2..000000000 --- a/scons/scons-local-4.1.0/SCons/EnvironmentValues.py +++ /dev/null @@ -1,119 +0,0 @@ -# MIT License -# -# Copyright 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. - -import re - -_is_valid_var = re.compile(r'[_a-zA-Z]\w*$') - -_rm = re.compile(r'\$[()]') -_remove = re.compile(r'\$\([^$]*(\$[^)][^$]*)*\$\)') - -# Regular expressions for splitting strings and handling substitutions, -# for use by the scons_subst() and scons_subst_list() functions: -# -# The first expression compiled matches all of the $-introduced tokens -# that we need to process in some way, and is used for substitutions. -# The expressions it matches are: -# -# "$$" -# "$(" -# "$)" -# "$variable" [must begin with alphabetic or underscore] -# "${any stuff}" -# -# The second expression compiled is used for splitting strings into tokens -# to be processed, and it matches all of the tokens listed above, plus -# the following that affect how arguments do or don't get joined together: -# -# " " [white space] -# "non-white-space" [without any dollar signs] -# "$" [single dollar sign] -# -_dollar_exps_str = r'\$[\$\(\)]|\$[_a-zA-Z][\.\w]*|\${[^}]*}' -_dollar_exps = re.compile(r'(%s)' % _dollar_exps_str) -_separate_args = re.compile(r'(%s|\s+|[^\s$]+|\$)' % _dollar_exps_str) - -# This regular expression is used to replace strings of multiple white -# space characters in the string result from the scons_subst() function. -_space_sep = re.compile(r'[\t ]+(?![^{]*})') - -class ValueTypes: - """ - Enum to store what type of value the variable holds. - """ - UNKNOWN = 0 - STRING = 1 - CALLABLE = 2 - VARIABLE = 3 - - -class EnvironmentValue: - """ - Hold a single value. We're going to cache parsed version of the file - We're going to keep track of variables which feed into this values evaluation - """ - def __init__(self, value): - self.value = value - self.var_type = ValueTypes.UNKNOWN - - if callable(self.value): - self.var_type = ValueTypes.CALLABLE - else: - self.parse_value() - - - def parse_value(self): - """ - Scan the string and break into component values - """ - - try: - if '$' not in self.value: - self._parsed = self.value - self.var_type = ValueTypes.STRING - else: - # Now we need to parse the specified string - result = _dollar_exps.sub(sub_match, args) - print(result) - except TypeError: - # likely callable? either way we don't parse - self._parsed = self.value - - def parse_trial(self): - """ - Try alternate parsing methods. - :return: - """ - parts = [] - for c in self.value: - pass - - -class EnvironmentValues: - """ - A class to hold all the environment variables - """ - def __init__(self, **kw): - self._dict = {} - for k in kw: - self._dict[k] = EnvironmentValue(kw[k]) diff --git a/scons/scons-local-4.1.0/SCons/EnvironmentValuesTest.py b/scons/scons-local-4.1.0/SCons/EnvironmentValuesTest.py deleted file mode 100644 index 074aa85ca..000000000 --- a/scons/scons-local-4.1.0/SCons/EnvironmentValuesTest.py +++ /dev/null @@ -1,39 +0,0 @@ -# MIT License -# -# Copyright 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. - -import unittest - -from SCons.EnvironmentValues import EnvironmentValues - -class MyTestCase(unittest.TestCase): - def test_simple_environmentValues(self): - """Test comparing SubstitutionEnvironments - """ - - env1 = EnvironmentValues(XXX='x') - env2 = EnvironmentValues(XXX='x',XX="$X", X1="${X}", X2="$($X$)") - - - -if __name__ == '__main__': - unittest.main() diff --git a/scons/scons-local-4.1.0/SCons/Errors.py b/scons/scons-local-4.1.0/SCons/Errors.py deleted file mode 100644 index 42db0728c..000000000 --- a/scons/scons-local-4.1.0/SCons/Errors.py +++ /dev/null @@ -1,222 +0,0 @@ -# MIT License -# -# Copyright 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 exception classes. - -Used to handle internal and user errors in SCons. - -""" - -import shutil -import SCons.Util - - -class BuildError(Exception): - """SCons Errors that can occur while building. - - 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 what caused the build error : - - node: the error occurred 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)): - - # py3: errstr should be string and not bytes. - - self.errstr = SCons.Util.to_String(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 SConsEnvironmentError(Exception): - pass - -class MSVCError(IOError): - pass - -class ExplicitExit(Exception): - def __init__(self, node=None, status=None, *args): - self.node = node - self.status = status - self.exitstatus = status - Exception.__init__(self, *args) - -def convert_to_BuildError(status, exc_info=None): - """Convert a return code to a BuildError Exception. - - The `buildError.status` we set here will normally be - used as the exit status of the "scons" process. - - Args: - status: can either be a return code or an Exception. - exc_info (tuple, optional): explicit exception information. - - """ - - 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) - elif isinstance(status, (StopError, UserError)): - buildError = BuildError( - errstr=str(status), - status=2, - exitstatus=2, - exc_info=exc_info) - elif isinstance(status, shutil.SameFileError): - # PY3 has a exception for when copying file to itself - # It's object provides info differently than below - try: - filename = status.filename - except AttributeError: - filename = None - - buildError = BuildError( - errstr=status.args[0], - status=status.errno, - exitstatus=2, - filename=filename, - exc_info=exc_info) - - elif isinstance(status, (SConsEnvironmentError, OSError, IOError)): - # 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). - filename = getattr(status, 'filename', None) - strerror = getattr(status, 'strerror', str(status)) - errno = getattr(status, 'errno', 2) - - buildError = BuildError( - errstr=strerror, - 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)\n"%(status,buildError.errstr, buildError.status)) - return buildError - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Executor.py b/scons/scons-local-4.1.0/SCons/Executor.py deleted file mode 100644 index 005906fbb..000000000 --- a/scons/scons-local-4.1.0/SCons/Executor.py +++ /dev/null @@ -1,666 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Execute actions with specific lists of target and source Nodes.""" - -import collections - -import SCons.Debug -from SCons.Debug import logInstanceCreation -import SCons.Errors -import SCons.Memoize -import SCons.Util -from SCons.compat import NoSlotsPyPy - -class Batch: - """Remembers exact association between targets - and sources of executor.""" - - __slots__ = ('targets', - 'sources') - - def __init__(self, targets=[], sources=[]): - self.targets = targets - self.sources = sources - - - -class TSList(collections.UserList): - """A class that implements $TARGETS or $SOURCES expansions by wrapping - an executor Method. This class is used in the Executor.lvars() - to delay creation of NodeList objects until they're needed. - - Note that we subclass collections.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 - collections.UserList methods in practice. - """ - def __init__(self, func): - self.func = func - def __getattr__(self, attr): - nl = self.func() - return getattr(nl, attr) - def __getitem__(self, i): - nl = self.func() - return nl[i] - def __getslice__(self, i, j): - nl = self.func() - i, j = max(i, 0), max(j, 0) - return nl[i:j] - def __str__(self): - nl = self.func() - return str(nl) - def __repr__(self): - nl = self.func() - return repr(nl) - -class TSObject: - """A class that implements $TARGET or $SOURCE expansions by wrapping - an Executor method. - """ - def __init__(self, func): - self.func = func - def __getattr__(self, attr): - n = self.func() - return getattr(n, attr) - def __str__(self): - n = self.func() - if n: - return str(n) - return '' - def __repr__(self): - n = self.func() - if n: - return repr(n) - return '' - -def rfile(node): - """ - A function to return the results of a Node's rfile() method, - if it exists, and the Node itself otherwise (if it's a Value - Node, e.g.). - """ - try: - rfile = node.rfile - except AttributeError: - return node - else: - return rfile() - - -def execute_nothing(obj, target, kw): - return 0 - -def execute_action_list(obj, target, kw): - """Actually execute the action list.""" - env = obj.get_build_env() - kw = obj.get_kw(kw) - status = 0 - for act in obj.get_action_list(): - args = ([], [], env) - status = act(*args, **kw) - if isinstance(status, SCons.Errors.BuildError): - status.executor = obj - raise status # TODO pylint E0702: raising int not allowed - elif status: - msg = "Error %s" % status - raise SCons.Errors.BuildError( - errstr=msg, - node=obj.batches[0].targets, - executor=obj, - action=act) - return status - -_do_execute_map = {0 : execute_nothing, - 1 : execute_action_list} - - -def execute_actions_str(obj): - env = obj.get_build_env() - return "\n".join([action.genstring(obj.get_all_targets(), - obj.get_all_sources(), - env) - for action in obj.get_action_list()]) - -def execute_null_str(obj): - return '' - -_execute_str_map = {0 : execute_null_str, - 1 : execute_actions_str} - - -class Executor(object, metaclass=NoSlotsPyPy): - """A class for controlling instances of executing an action. - - This largely exists to hold a single association of an action, - environment, list of environment override dictionaries, targets - and sources for later processing as needed. - """ - - __slots__ = ('pre_actions', - 'post_actions', - 'env', - 'overridelist', - 'batches', - 'builder_kw', - '_memo', - 'lvars', - '_changed_sources_list', - '_changed_targets_list', - '_unchanged_sources_list', - '_unchanged_targets_list', - 'action_list', - '_do_execute', - '_execute_str') - - def __init__(self, action, env=None, overridelist=[{}], - targets=[], sources=[], builder_kw={}): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Executor.Executor') - self.set_action_list(action) - self.pre_actions = [] - self.post_actions = [] - self.env = env - self.overridelist = overridelist - if targets or sources: - self.batches = [Batch(targets[:], sources[:])] - else: - self.batches = [] - self.builder_kw = builder_kw - self._do_execute = 1 - self._execute_str = 1 - self._memo = {} - - def get_lvars(self): - try: - return self.lvars - except AttributeError: - self.lvars = { - 'CHANGED_SOURCES' : TSList(self._get_changed_sources), - 'CHANGED_TARGETS' : TSList(self._get_changed_targets), - 'SOURCE' : TSObject(self._get_source), - 'SOURCES' : TSList(self._get_sources), - 'TARGET' : TSObject(self._get_target), - 'TARGETS' : TSList(self._get_targets), - 'UNCHANGED_SOURCES' : TSList(self._get_unchanged_sources), - 'UNCHANGED_TARGETS' : TSList(self._get_unchanged_targets), - } - return self.lvars - - def _get_changes(self): - cs = [] - ct = [] - us = [] - ut = [] - for b in self.batches: - # don't add targets marked always build to unchanged lists - # add to changed list as they always need to build - if not b.targets[0].always_build and b.targets[0].is_up_to_date(): - us.extend(list(map(rfile, b.sources))) - ut.extend(b.targets) - else: - cs.extend(list(map(rfile, b.sources))) - ct.extend(b.targets) - self._changed_sources_list = SCons.Util.NodeList(cs) - self._changed_targets_list = SCons.Util.NodeList(ct) - self._unchanged_sources_list = SCons.Util.NodeList(us) - self._unchanged_targets_list = SCons.Util.NodeList(ut) - - def _get_changed_sources(self, *args, **kw): - try: - return self._changed_sources_list - except AttributeError: - self._get_changes() - return self._changed_sources_list - - def _get_changed_targets(self, *args, **kw): - try: - return self._changed_targets_list - except AttributeError: - self._get_changes() - return self._changed_targets_list - - def _get_source(self, *args, **kw): - return rfile(self.batches[0].sources[0]).get_subst_proxy() - - def _get_sources(self, *args, **kw): - return SCons.Util.NodeList([rfile(n).get_subst_proxy() for n in self.get_all_sources()]) - - def _get_target(self, *args, **kw): - return self.batches[0].targets[0].get_subst_proxy() - - def _get_targets(self, *args, **kw): - return SCons.Util.NodeList([n.get_subst_proxy() for n in self.get_all_targets()]) - - def _get_unchanged_sources(self, *args, **kw): - try: - return self._unchanged_sources_list - except AttributeError: - self._get_changes() - return self._unchanged_sources_list - - def _get_unchanged_targets(self, *args, **kw): - try: - return self._unchanged_targets_list - except AttributeError: - self._get_changes() - return self._unchanged_targets_list - - def get_action_targets(self): - if not self.action_list: - return [] - targets_string = self.action_list[0].get_targets(self.env, self) - if targets_string[0] == '$': - targets_string = targets_string[1:] - return self.get_lvars()[targets_string] - - def set_action_list(self, action): - import SCons.Util - if not SCons.Util.is_List(action): - if not action: - import SCons.Errors - raise SCons.Errors.UserError("Executor must have an action.") - action = [action] - self.action_list = action - - def get_action_list(self): - if self.action_list is None: - return [] - return self.pre_actions + self.action_list + self.post_actions - - def get_all_targets(self): - """Returns all targets for all batches of this Executor.""" - result = [] - for batch in self.batches: - result.extend(batch.targets) - return result - - def get_all_sources(self): - """Returns all sources for all batches of this Executor.""" - result = [] - for batch in self.batches: - result.extend(batch.sources) - return result - - def get_all_children(self): - """Returns all unique children (dependencies) for all batches - of this Executor. - - The Taskmaster can recognize when it's already evaluated a - Node, so we don't have to make this list unique for its intended - canonical use case, but we expect there to be a lot of redundancy - (long lists of batched .cc files #including the same .h files - over and over), so removing the duplicates once up front should - save the Taskmaster a lot of work. - """ - result = SCons.Util.UniqueList([]) - for target in self.get_all_targets(): - result.extend(target.children()) - return result - - def get_all_prerequisites(self): - """Returns all unique (order-only) prerequisites for all batches - of this Executor. - """ - result = SCons.Util.UniqueList([]) - for target in self.get_all_targets(): - if target.prerequisites is not None: - result.extend(target.prerequisites) - return result - - def get_action_side_effects(self): - - """Returns all side effects for all batches of this - Executor used by the underlying Action. - """ - result = SCons.Util.UniqueList([]) - for target in self.get_action_targets(): - result.extend(target.side_effects) - return result - - @SCons.Memoize.CountMethodCall - def get_build_env(self): - """Fetch or create the appropriate build Environment - for this Executor. - """ - try: - return self._memo['get_build_env'] - except KeyError: - pass - - # Create the build environment instance with appropriate - # overrides. These get evaluated against the current - # environment's construction variables so that users can - # add to existing values by referencing the variable in - # the expansion. - overrides = {} - for odict in self.overridelist: - overrides.update(odict) - - import SCons.Defaults - env = self.env or SCons.Defaults.DefaultEnvironment() - build_env = env.Override(overrides) - - self._memo['get_build_env'] = build_env - - return build_env - - def get_build_scanner_path(self, scanner): - """Fetch the scanner path for this executor's targets and sources. - """ - env = self.get_build_env() - try: - cwd = self.batches[0].targets[0].cwd - except (IndexError, AttributeError): - cwd = None - return scanner.path(env, cwd, - self.get_all_targets(), - self.get_all_sources()) - - def get_kw(self, kw={}): - result = self.builder_kw.copy() - result.update(kw) - result['executor'] = self - return result - - # use extra indirection because with new-style objects (Python 2.2 - # and above) we can't override special methods, and nullify() needs - # to be able to do this. - - def __call__(self, target, **kw): - return _do_execute_map[self._do_execute](self, target, kw) - - def cleanup(self): - self._memo = {} - - def add_sources(self, sources): - """Add source files to this Executor's list. This is necessary - for "multi" Builders that can be called repeatedly to build up - a source file list for a given target.""" - # TODO(batch): extend to multiple batches - assert (len(self.batches) == 1) - # TODO(batch): remove duplicates? - sources = [x for x in sources if x not in self.batches[0].sources] - self.batches[0].sources.extend(sources) - - def get_sources(self): - return self.batches[0].sources - - def add_batch(self, targets, sources): - """Add pair of associated target and source to this Executor's list. - This is necessary for "batch" Builders that can be called repeatedly - to build up a list of matching target and source files that will be - used in order to update multiple target files at once from multiple - corresponding source files, for tools like MSVC that support it.""" - self.batches.append(Batch(targets, sources)) - - def prepare(self): - """ - Preparatory checks for whether this Executor can go ahead - and (try to) build its targets. - """ - for s in self.get_all_sources(): - if s.missing(): - msg = "Source `%s' not found, needed by target `%s'." - raise SCons.Errors.StopError(msg % (s, self.batches[0].targets[0])) - - def add_pre_action(self, action): - self.pre_actions.append(action) - - def add_post_action(self, action): - self.post_actions.append(action) - - # another extra indirection for new-style objects and nullify... - - def __str__(self): - return _execute_str_map[self._execute_str](self) - - def nullify(self): - self.cleanup() - self._do_execute = 0 - self._execute_str = 0 - - @SCons.Memoize.CountMethodCall - def get_contents(self): - """Fetch the signature contents. This is the main reason this - class exists, so we can compute this once and cache it regardless - of how many target or source Nodes there are. - - Returns bytes - """ - try: - return self._memo['get_contents'] - except KeyError: - pass - env = self.get_build_env() - - action_list = self.get_action_list() - all_targets = self.get_all_targets() - all_sources = self.get_all_sources() - - result = bytearray("",'utf-8').join([action.get_contents(all_targets, - all_sources, - env) - for action in action_list]) - - self._memo['get_contents'] = result - return result - - def get_timestamp(self): - """Fetch a time stamp for this Executor. We don't have one, of - course (only files do), but this is the interface used by the - timestamp module. - """ - return 0 - - def scan_targets(self, scanner): - # TODO(batch): scan by batches - self.scan(scanner, self.get_all_targets()) - - def scan_sources(self, scanner): - # TODO(batch): scan by batches - if self.batches[0].sources: - self.scan(scanner, self.get_all_sources()) - - def scan(self, scanner, node_list): - """Scan a list of this Executor's files (targets or sources) for - implicit dependencies and update all of the targets with them. - This essentially short-circuits an N*M scan of the sources for - each individual target, which is a hell of a lot more efficient. - """ - env = self.get_build_env() - path = self.get_build_scanner_path - kw = self.get_kw() - - # TODO(batch): scan by batches) - deps = [] - - for node in node_list: - node.disambiguate() - deps.extend(node.get_implicit_deps(env, scanner, path, kw)) - - deps.extend(self.get_implicit_deps()) - - for tgt in self.get_all_targets(): - tgt.add_to_implicit(deps) - - def _get_unignored_sources_key(self, node, ignore=()): - return (node,) + tuple(ignore) - - @SCons.Memoize.CountDictCall(_get_unignored_sources_key) - def get_unignored_sources(self, node, ignore=()): - key = (node,) + tuple(ignore) - try: - memo_dict = self._memo['get_unignored_sources'] - except KeyError: - memo_dict = {} - self._memo['get_unignored_sources'] = memo_dict - else: - try: - return memo_dict[key] - except KeyError: - pass - - if node: - # TODO: better way to do this (it's a linear search, - # but it may not be critical path)? - sourcelist = [] - for b in self.batches: - if node in b.targets: - sourcelist = b.sources - break - else: - sourcelist = self.get_all_sources() - if ignore: - idict = {} - for i in ignore: - idict[i] = 1 - sourcelist = [s for s in sourcelist if s not in idict] - - memo_dict[key] = sourcelist - - return sourcelist - - def get_implicit_deps(self): - """Return the executor's implicit dependencies, i.e. the nodes of - the commands to be executed.""" - result = [] - build_env = self.get_build_env() - for act in self.get_action_list(): - deps = act.get_implicit_deps(self.get_all_targets(), - self.get_all_sources(), - build_env) - result.extend(deps) - return result - - - -_batch_executors = {} - -def GetBatchExecutor(key): - return _batch_executors[key] - -def AddBatchExecutor(key, executor): - assert key not in _batch_executors - _batch_executors[key] = executor - -nullenv = None - - -class NullEnvironment(SCons.Util.Null): - import SCons.CacheDir - _CacheDir_path = None - _CacheDir = SCons.CacheDir.CacheDir(None) - def get_CacheDir(self): - return self._CacheDir - - -def get_NullEnvironment(): - """Use singleton pattern for Null Environments.""" - global nullenv - - if nullenv is None: - nullenv = NullEnvironment() - return nullenv - -class Null(object, metaclass=NoSlotsPyPy): - """A null Executor, with a null build Environment, that does - nothing when the rest of the methods call it. - - This might be able to disappear when we refactor things to - disassociate Builders from Nodes entirely, so we're not - going to worry about unit tests for this--at least for now. - """ - - __slots__ = ('pre_actions', - 'post_actions', - 'env', - 'overridelist', - 'batches', - 'builder_kw', - '_memo', - 'lvars', - '_changed_sources_list', - '_changed_targets_list', - '_unchanged_sources_list', - '_unchanged_targets_list', - 'action_list', - '_do_execute', - '_execute_str') - - def __init__(self, *args, **kw): - if SCons.Debug.track_instances: - logInstanceCreation(self, 'Executor.Null') - self.batches = [Batch(kw['targets'][:], [])] - def get_build_env(self): - 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_targets(self): - return [] - def get_action_list(self): - return [] - def get_all_targets(self): - return self.batches[0].targets - def get_all_sources(self): - return self.batches[0].targets[0].sources - def get_all_children(self): - return self.batches[0].targets[0].children() - def get_all_prerequisites(self): - return [] - def get_action_side_effects(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.""" - batches = self.batches - self.__class__ = Executor - self.__init__([]) - self.batches = batches - - # 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) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Job.py b/scons/scons-local-4.1.0/SCons/Job.py deleted file mode 100644 index f87a3bbfe..000000000 --- a/scons/scons-local-4.1.0/SCons/Job.py +++ /dev/null @@ -1,431 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Serial and Parallel classes to execute build tasks. - -The Jobs class provides a higher level interface to start, -stop, and wait on jobs. -""" - -import SCons.compat - -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 - - -class Jobs: - """An instance of this class initializes N jobs, and provides - methods for starting, stopping, and waiting on all N jobs. - """ - - def __init__(self, num, taskmaster): - """ - Create 'num' jobs using the given taskmaster. - - If 'num' is 1 or less, then a serial job will be used, - otherwise a parallel job with 'num' worker threads will - be used. - - The 'num_jobs' attribute will be set to the actual number of jobs - allocated. If more than one job is requested but the Parallel - class can't do it, it gets reset to 1. Wrapping interfaces that - care should check the value of 'num_jobs' after initialization. - """ - - 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, stack_size) - self.num_jobs = num - except NameError: - pass - if self.job is None: - self.job = Serial(taskmaster) - self.num_jobs = 1 - - 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() - finally: - postfunc() - self._reset_sig_handler() - - 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's very difficult to stop the build process - by throwing asynchronously an exception such as - KeyboardInterrupt. For example, the python Condition - variables (threading.Condition) and queues do not seem to be - 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 - than Parallel, but is only appropriate for non-parallel builds. Only - one instance of this class should be in existence at a time. - - This class is not thread safe. - """ - - def __init__(self, taskmaster): - """Create a new serial job given a taskmaster. - - The taskmaster's next_task() method should return the next task - that needs to be executed, or None if there are no more tasks. The - taskmaster's executed() method will be called for each task when it - is successfully executed, or failed() will be called if it failed to - 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 - and executing them, and return when there are no more tasks. If a task - fails to execute (i.e. execute() raises an exception), then the job will - stop.""" - - while True: - task = self.taskmaster.next_task() - - if task is None: - break - - try: - task.prepare() - if task.needs_execute(): - task.execute() - except Exception: - 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() - else: - task.executed() - - task.postprocess() - self.taskmaster.cleanup() - - -# Trap import failure so that everything in the Job module but the -# Parallel class (and its dependent classes) will work if the interpreter -# doesn't support threads. -try: - import queue - import threading -except ImportError: - pass -else: - class Worker(threading.Thread): - """A worker thread waits on a task to be posted to its request queue, - 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, interrupted): - threading.Thread.__init__(self) - self.setDaemon(1) - self.requestQueue = requestQueue - self.resultsQueue = resultsQueue - self.interrupted = interrupted - self.start() - - def run(self): - while True: - task = self.requestQueue.get() - - 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: - task.exception_set() - ok = False - else: - ok = True - - self.resultsQueue.put((task, ok)) - - class ThreadPool: - """This class is responsible for spawning and managing 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 as e: - # Only print a warning if the stack size has been - # explicitly set. - if explicit_stack_size is not 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 as 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, interrupted) - self.workers.append(worker) - - if 'prev_size' in locals(): - threading.stack_size(prev_size) - - def put(self, task): - """Put task into request queue.""" - self.requestQueue.put(task) - - def get(self): - """Remove and return a result tuple from the results queue.""" - return self.resultsQueue.get() - - def preparation_failed(self, task): - self.resultsQueue.put((task, False)) - - def cleanup(self): - """ - Shuts down the thread pool, giving each worker thread a - chance to shut down gracefully. - """ - # For each worker thread, put a sentinel "None" value - # on the requestQueue (indicating that there's no work - # to be done) so that each worker thread will get one and - # terminate gracefully. - for _ in self.workers: - self.requestQueue.put(None) - - # Wait for all of the workers to terminate. - # - # If we don't do this, later Python versions (2.4, 2.5) often - # seem to raise exceptions during shutdown. This happens - # in requestQueue.get(), as an assertion failure that - # requestQueue.not_full is notified while not acquired, - # seemingly because the main thread has shut down (or is - # in the process of doing so) while the workers are still - # trying to pull sentinels off the requestQueue. - # - # Normally these terminations should happen fairly quickly, - # but we'll stick a one-second timeout on here just in case - # someone gets hung. - for worker in self.workers: - worker.join(1.0) - self.workers = [] - - class Parallel: - """This class is used to execute tasks in parallel, and is somewhat - less efficient than Serial, but is appropriate for parallel builds. - - This class is thread safe. - """ - - 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 - task that needs to be executed, or None if there are no more - tasks. The taskmaster's executed() method will be called - for each task when it is successfully executed, or failed() - will be called if the task failed to execute (i.e. execute() - raised an exception). - - Note: calls to taskmaster are serialized, but calls to - execute() on distinct tasks are not serialized, because - that is the whole point of parallel jobs: they can execute - multiple tasks simultaneously. """ - - self.taskmaster = taskmaster - self.interrupted = InterruptState() - self.tp = ThreadPool(num, stack_size, self.interrupted) - - self.maxjobs = num - - def start(self): - """Start the job. This will begin pulling tasks from the - taskmaster and executing them, and return when there are no - more tasks. If a task fails to execute (i.e. execute() raises - an exception), then the job will stop.""" - - jobs = 0 - - while True: - # Start up as many available tasks as we're - # allowed to. - while jobs < self.maxjobs: - task = self.taskmaster.next_task() - if task is None: - break - - try: - # prepare task for execution - task.prepare() - except: - task.exception_set() - 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 - - # Let any/all completed tasks finish up before we go - # back and put the next batch of tasks on the queue. - while True: - 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() - - if self.tp.resultsQueue.empty(): - break - - self.tp.cleanup() - self.taskmaster.cleanup() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Memoize.py b/scons/scons-local-4.1.0/SCons/Memoize.py deleted file mode 100644 index 8c3303f02..000000000 --- a/scons/scons-local-4.1.0/SCons/Memoize.py +++ /dev/null @@ -1,242 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Decorator-based memoizer to count caching stats. - -A decorator-based implementation to count hits and misses of the computed -values that various methods cache in memory. - -Use of this modules assumes that wrapped methods be coded to cache their -values in a consistent way. In particular, it requires that the class uses a -dictionary named "_memo" to store the cached values. - -Here is an example of wrapping a method that returns a computed value, -with no input parameters:: - - @SCons.Memoize.CountMethodCall - def foo(self): - - try: # Memoization - return self._memo['foo'] # Memoization - except KeyError: # Memoization - pass # Memoization - - result = self.compute_foo_value() - - self._memo['foo'] = result # Memoization - - return result - -Here is an example of wrapping a method that will return different values -based on one or more input arguments:: - - def _bar_key(self, argument): # Memoization - return argument # Memoization - - @SCons.Memoize.CountDictCall(_bar_key) - def bar(self, argument): - - memo_key = argument # Memoization - try: # Memoization - memo_dict = self._memo['bar'] # Memoization - except KeyError: # Memoization - memo_dict = {} # Memoization - self._memo['dict'] = memo_dict # Memoization - else: # Memoization - try: # Memoization - return memo_dict[memo_key] # Memoization - except KeyError: # Memoization - pass # Memoization - - result = self.compute_bar_value(argument) - - memo_dict[memo_key] = result # Memoization - - return result - -Deciding what to cache is tricky, because different configurations -can have radically different performance tradeoffs, and because the -tradeoffs involved are often so non-obvious. Consequently, deciding -whether or not to cache a given method will likely be more of an art than -a science, but should still be based on available data from this module. -Here are some VERY GENERAL guidelines about deciding whether or not to -cache return values from a method that's being called a lot: - - -- The first question to ask is, "Can we change the calling code - so this method isn't called so often?" Sometimes this can be - done by changing the algorithm. Sometimes the *caller* should - be memoized, not the method you're looking at. - - -- The memoized function should be timed with multiple configurations - to make sure it doesn't inadvertently slow down some other - configuration. - - -- When memoizing values based on a dictionary key composed of - input arguments, you don't need to use all of the arguments - if some of them don't affect the return values. - -""" - -# A flag controlling whether or not we actually use memoization. -use_memoizer = None - -# Global list of counter objects -CounterList = {} - -class Counter: - """ - Base class for counting memoization hits and misses. - - We expect that the initialization in a matching decorator will - fill in the correct class name and method name that represents - the name of the function being counted. - """ - def __init__(self, cls_name, method_name): - """ - """ - self.cls_name = cls_name - self.method_name = method_name - self.hit = 0 - self.miss = 0 - def key(self): - return self.cls_name+'.'+self.method_name - def display(self): - print(" {:7d} hits {:7d} misses {}()".format(self.hit, self.miss, self.key())) - def __eq__(self, other): - try: - return self.key() == other.key() - except AttributeError: - return True - -class CountValue(Counter): - """ - A counter class for simple, atomic memoized values. - - A CountValue object should be instantiated in a decorator for each of - the class's methods that memoizes its return value by simply storing - the return value in its _memo dictionary. - """ - def count(self, *args, **kw): - """ Counts whether the memoized value has already been - set (a hit) or not (a miss). - """ - obj = args[0] - if self.method_name in obj._memo: - self.hit = self.hit + 1 - else: - self.miss = self.miss + 1 - -class CountDict(Counter): - """ - A counter class for memoized values stored in a dictionary, with - keys based on the method's input arguments. - - A CountDict object is instantiated in a decorator for each of the - class's methods that memoizes its return value in a dictionary, - indexed by some key that can be computed from one or more of - its input arguments. - """ - def __init__(self, cls_name, method_name, keymaker): - """ - """ - Counter.__init__(self, cls_name, method_name) - self.keymaker = keymaker - def count(self, *args, **kw): - """ Counts whether the computed key value is already present - in the memoization dictionary (a hit) or not (a miss). - """ - obj = args[0] - try: - memo_dict = obj._memo[self.method_name] - except KeyError: - self.miss = self.miss + 1 - else: - key = self.keymaker(*args, **kw) - if key in memo_dict: - self.hit = self.hit + 1 - else: - self.miss = self.miss + 1 - -def Dump(title=None): - """ Dump the hit/miss count for all the counters - collected so far. - """ - if title: - print(title) - for counter in sorted(CounterList): - CounterList[counter].display() - -def EnableMemoization(): - global use_memoizer - use_memoizer = 1 - -def CountMethodCall(fn): - """ Decorator for counting memoizer hits/misses while retrieving - a simple value in a class method. It wraps the given method - fn and uses a CountValue object to keep track of the - caching statistics. - Wrapping gets enabled by calling EnableMemoization(). - """ - if use_memoizer: - def wrapper(self, *args, **kwargs): - global CounterList - key = self.__class__.__name__+'.'+fn.__name__ - if key not in CounterList: - CounterList[key] = CountValue(self.__class__.__name__, fn.__name__) - CounterList[key].count(self, *args, **kwargs) - return fn(self, *args, **kwargs) - wrapper.__name__= fn.__name__ - return wrapper - else: - return fn - -def CountDictCall(keyfunc): - """ Decorator for counting memoizer hits/misses while accessing - dictionary values with a key-generating function. Like - CountMethodCall above, it wraps the given method - fn and uses a CountDict object to keep track of the - caching statistics. The dict-key function keyfunc has to - get passed in the decorator call and gets stored in the - CountDict instance. - Wrapping gets enabled by calling EnableMemoization(). - """ - def decorator(fn): - if use_memoizer: - def wrapper(self, *args, **kwargs): - global CounterList - key = self.__class__.__name__+'.'+fn.__name__ - if key not in CounterList: - CounterList[key] = CountDict(self.__class__.__name__, fn.__name__, keyfunc) - CounterList[key].count(self, *args, **kwargs) - return fn(self, *args, **kwargs) - wrapper.__name__= fn.__name__ - return wrapper - else: - return fn - return decorator - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Node/Alias.py b/scons/scons-local-4.1.0/SCons/Node/Alias.py deleted file mode 100644 index 64054d2d7..000000000 --- a/scons/scons-local-4.1.0/SCons/Node/Alias.py +++ /dev/null @@ -1,176 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Alias nodes. - -This creates a hash of global Aliases (dummy targets). -""" - -import collections - -import SCons.Errors -import SCons.Node -import SCons.Util -from SCons.Util import MD5signature - -class AliasNameSpace(collections.UserDict): - def Alias(self, name, **kw): - if isinstance(name, SCons.Node.Alias.Alias): - return name - try: - a = self[name] - except KeyError: - a = SCons.Node.Alias.Alias(name, **kw) - self[name] = a - return a - - def lookup(self, name, **kw): - try: - return self[name] - except KeyError: - return None - -class AliasNodeInfo(SCons.Node.NodeInfoBase): - __slots__ = ('csig',) - current_version_id = 2 - field_list = ['csig'] - def str_to_node(self, s): - return default_ans.Alias(s) - - def __getstate__(self): - """ - Return all fields that shall be pickled. Walk the slots in the class - hierarchy and add those to the state dictionary. If a '__dict__' slot is - available, copy all entries to the dictionary. Also include the version - id, which is fixed for all instances of a class. - """ - state = getattr(self, '__dict__', {}).copy() - for obj in type(self).mro(): - for name in getattr(obj,'__slots__',()): - if hasattr(self, name): - state[name] = getattr(self, name) - - state['_version_id'] = self.current_version_id - try: - del state['__weakref__'] - except KeyError: - pass - - return state - - def __setstate__(self, state): - """ - Restore the attributes from a pickled state. - """ - # TODO check or discard version - del state['_version_id'] - for key, value in state.items(): - if key not in ('__weakref__',): - setattr(self, key, value) - - -class AliasBuildInfo(SCons.Node.BuildInfoBase): - __slots__ = () - current_version_id = 2 - -class Alias(SCons.Node.Node): - - NodeInfo = AliasNodeInfo - BuildInfo = AliasBuildInfo - - def __init__(self, name): - SCons.Node.Node.__init__(self) - self.name = name - self.changed_since_last_build = 1 - self.store_info = 0 - - def str_for_display(self): - return '"' + self.__str__() + '"' - - def __str__(self): - return self.name - - def make_ready(self): - self.get_csig() - - really_build = SCons.Node.Node.build - is_up_to_date = SCons.Node.Node.children_are_up_to_date - - def is_under(self, dir): - # Make Alias nodes get built regardless of - # what directory scons was run from. Alias nodes - # are outside the filesystem: - return 1 - - def get_contents(self): - """The contents of an alias is the concatenation - of the content signatures of all its sources.""" - childsigs = [n.get_csig() for n in self.children()] - return ''.join(childsigs) - - def sconsign(self): - """An Alias is not recorded in .sconsign files""" - pass - - # - # - # - - def build(self): - """A "builder" for aliases.""" - pass - - def convert(self): - try: del self.builder - except AttributeError: pass - self.reset_executor() - self.build = self.really_build - - def get_csig(self): - """ - Generate a node's content signature, the digested signature - of its content. - - node - the node - cache - alternate node to use for the signature cache - returns - the content signature - """ - try: - return self.ninfo.csig - except AttributeError: - pass - - contents = self.get_contents() - csig = MD5signature(contents) - self.get_ninfo().csig = csig - return csig - -default_ans = AliasNameSpace() - -SCons.Node.arg2nodes_lookups.append(default_ans.lookup) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Node/FS.py b/scons/scons-local-4.1.0/SCons/Node/FS.py deleted file mode 100644 index 290fcb3cc..000000000 --- a/scons/scons-local-4.1.0/SCons/Node/FS.py +++ /dev/null @@ -1,3820 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""File system nodes. - -These Nodes represent the canonical external objects that people think -of when they think of building software: files and directories. - -This holds a "default_fs" variable that should be initialized with an FS -that can be used by scripts or modules looking for the canonical default. -""" - -import fnmatch -import os -import re -import shutil -import stat -import sys -import time -import codecs -from itertools import chain -import importlib.util - -import SCons.Action -import SCons.Debug -from SCons.Debug import logInstanceCreation, Trace -import SCons.Errors -import SCons.Memoize -import SCons.Node -import SCons.Node.Alias -import SCons.Subst -import SCons.Util -from SCons.Util import MD5signature, MD5filesignature, MD5collect -import SCons.Warnings - -print_duplicate = 0 - -MD5_TIMESTAMP_DEBUG = False - - -def sconsign_none(node): - raise NotImplementedError - -def sconsign_dir(node): - """Return the .sconsign file info for this directory, - creating it first if necessary.""" - if not node._sconsign: - import SCons.SConsign - node._sconsign = SCons.SConsign.ForDirectory(node) - return node._sconsign - -_sconsign_map = {0 : sconsign_none, - 1 : sconsign_dir} - -class FileBuildInfoFileToCsigMappingError(Exception): - pass - -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 - -# -# We stringify these file system Nodes a lot. Turning a file system Node -# into a string is non-trivial, because the final string representation -# can depend on a lot of factors: whether it's a derived target or not, -# whether it's linked to a repository or source directory, and whether -# there's duplication going on. The normal technique for optimizing -# calculations like this is to memoize (cache) the string value, so you -# only have to do the calculation once. -# -# 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 -# 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 VariantDir and the other stuff, -# to let this module know it can start returning saved string values -# for Nodes. -# -Save_Strings = None - -def save_strings(val): - global Save_Strings - Save_Strings = val - -# -# Avoid unnecessary function calls by recording a Boolean value that -# tells us whether or not os.path.splitdrive() actually does anything -# on this system, and therefore whether we need to bother calling it -# when looking up path names in various methods below. -# - -do_splitdrive = None -_my_splitdrive =None - -def initialize_do_splitdrive(): - global do_splitdrive - global has_unc - drive, path = os.path.splitdrive('X:/foo') - # splitunc is removed from python 3.7 and newer - # so we can also just test if splitdrive works with UNC - has_unc = (hasattr(os.path, 'splitunc') - or os.path.splitdrive(r'\\split\drive\test')[0] == r'\\split\drive') - - do_splitdrive = not not drive or has_unc - - global _my_splitdrive - if has_unc: - def splitdrive(p): - if p[1:2] == ':': - return p[:2], p[2:] - if p[0:2] == '//': - # Note that we leave a leading slash in the path - # because UNC paths are always absolute. - return '//', p[1:] - return '', p - else: - def splitdrive(p): - if p[1:2] == ':': - return p[:2], p[2:] - return '', p - _my_splitdrive = splitdrive - - # Keep some commonly used values in global variables to skip to - # module look-up costs. - global OS_SEP - global UNC_PREFIX - global os_sep_is_slash - - OS_SEP = os.sep - UNC_PREFIX = OS_SEP + OS_SEP - os_sep_is_slash = OS_SEP == '/' - -initialize_do_splitdrive() - -# Used to avoid invoking os.path.normpath if not necessary. -needs_normpath_check = re.compile( - r''' - # We need to renormalize the path if it contains any consecutive - # '/' characters. - .*// | - - # We need to renormalize the path if it contains a '..' directory. - # Note that we check for all the following cases: - # - # a) The path is a single '..' - # b) The path starts with '..'. E.g. '../' or '../moredirs' - # but we not match '..abc/'. - # c) The path ends with '..'. E.g. '/..' or 'dirs/..' - # d) The path contains a '..' in the middle. - # E.g. dirs/../moredirs - - (.*/)?\.\.(?:/|$) | - - # We need to renormalize the path if it contains a '.' - # directory, but NOT if it is a single '.' '/' characters. We - # do not want to match a single '.' because this case is checked - # for explicitly since this is common enough case. - # - # Note that we check for all the following cases: - # - # a) We don't match a single '.' - # b) We match if the path starts with '.'. E.g. './' or - # './moredirs' but we not match '.abc/'. - # c) We match if the path ends with '.'. E.g. '/.' or - # 'dirs/.' - # d) We match if the path contains a '.' in the middle. - # E.g. dirs/./moredirs - - \./|.*/\.(?:/|$) - - ''', - re.VERBOSE - ) -needs_normpath_match = needs_normpath_check.match - -# -# SCons.Action objects for interacting with the outside world. -# -# The Node.FS methods in this module should use these actions to -# create and/or remove files and directories; they should *not* use -# os.{link,symlink,unlink,mkdir}(), etc., directly. -# -# Using these SCons.Action objects ensures that descriptions of these -# external activities are properly displayed, that the displays are -# suppressed when the -s (silent) option is used, and (most importantly) -# the actions are disabled when the the -n option is used, in which case -# there should be *no* changes to the external file system(s)... -# - -# For Now disable hard & softlinks for win32 -# PY3 supports them, but the rest of SCons is not ready for this -# in some cases user permissions may be required. -# TODO: See if theres a reasonable way to enable using links on win32/64 - -if hasattr(os, 'link') and sys.platform != 'win32': - def _hardlink_func(fs, src, dst): - # If the source is a symlink, we can't just hard-link to it - # because a relative symlink may point somewhere completely - # different. We must disambiguate the symlink and then - # hard-link the final destination file. - while fs.islink(src): - link = fs.readlink(src) - if not os.path.isabs(link): - src = link - else: - src = os.path.join(os.path.dirname(src), link) - fs.link(src, dst) -else: - _hardlink_func = None - -if hasattr(os, 'symlink') and sys.platform != 'win32': - def _softlink_func(fs, src, dst): - fs.symlink(src, dst) -else: - _softlink_func = None - -def _copy_func(fs, src, dest): - shutil.copy2(src, dest) - st = fs.stat(src) - fs.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) - - -Valid_Duplicates = ['hard-soft-copy', 'soft-hard-copy', - 'hard-copy', 'soft-copy', 'copy'] - -Link_Funcs = [] # contains the callables of the specified duplication style - -def set_duplicate(duplicate): - # Fill in the Link_Funcs list according to the argument - # (discarding those not available on the platform). - - # Set up the dictionary that maps the argument names to the - # underlying implementations. We do this inside this function, - # not in the top-level module code, so that we can remap os.link - # and os.symlink for testing purposes. - link_dict = { - 'hard' : _hardlink_func, - 'soft' : _softlink_func, - 'copy' : _copy_func - } - - if duplicate not in Valid_Duplicates: - raise SCons.Errors.InternalError("The argument of set_duplicate " - "should be in Valid_Duplicates") - global Link_Funcs - Link_Funcs = [] - for func in duplicate.split('-'): - if link_dict[func]: - Link_Funcs.append(link_dict[func]) - -def LinkFunc(target, source, env): - """ - Relative paths cause problems with symbolic links, so - we use absolute paths, which may be a problem for people - who want to move their soft-linked src-trees around. Those - people should use the 'hard-copy' mode, softlinks cannot be - used for that; at least I have no idea how ... - """ - src = source[0].get_abspath() - dest = target[0].get_abspath() - dir, file = os.path.split(dest) - if dir and not target[0].fs.isdir(dir): - os.makedirs(dir) - if not Link_Funcs: - # Set a default order of link functions. - set_duplicate('hard-soft-copy') - fs = source[0].fs - # Now link the files with the previously specified order. - for func in Link_Funcs: - try: - func(fs, src, dest) - break - except (IOError, OSError): - # An OSError indicates something happened like a permissions - # problem or an attempt to symlink across file-system - # boundaries. An IOError indicates something like the file - # not existing. In either case, keeping trying additional - # functions in the list and only raise an error if the last - # one failed. - if func == Link_Funcs[-1]: - # exception of the last link method (copy) are fatal - raise - return 0 - -Link = SCons.Action.Action(LinkFunc, None) -def LocalString(target, source, env): - return 'Local copy of %s from %s' % (target[0], source[0]) - -LocalCopy = SCons.Action.Action(LinkFunc, LocalString) - -def UnlinkFunc(target, source, env): - t = target[0] - t.fs.unlink(t.get_abspath()) - return 0 - -Unlink = SCons.Action.Action(UnlinkFunc, None) - -def MkdirFunc(target, source, env): - t = target[0] - # This os.path.exists test looks redundant, but it's possible - # when using Install() to install multiple dirs outside the - # source tree to get a case where t.exists() is true but - # the path does already exist, so this prevents spurious - # build failures in that case. See test/Install/multi-dir. - if not t.exists() and not os.path.exists(t.get_abspath()): - t.fs.mkdir(t.get_abspath()) - return 0 - -Mkdir = SCons.Action.Action(MkdirFunc, None, presub=None) - -MkdirBuilder = None - -def get_MkdirBuilder(): - global MkdirBuilder - if MkdirBuilder is None: - import SCons.Builder - import SCons.Defaults - # "env" will get filled in by Executor.get_build_env() - # calling SCons.Defaults.DefaultEnvironment() when necessary. - MkdirBuilder = SCons.Builder.Builder(action = Mkdir, - env = None, - explain = None, - is_explicit = None, - target_scanner = SCons.Defaults.DirEntryScanner, - name = "MkdirBuilder") - return MkdirBuilder - -class _Null: - pass - -_null = _Null() - -# Cygwin's os.path.normcase pretends it's on a case-sensitive filesystem. -_is_cygwin = sys.platform == "cygwin" -if os.path.normcase("TeSt") == os.path.normpath("TeSt") and not _is_cygwin: - def _my_normcase(x): - return x -else: - def _my_normcase(x): - return x.upper() - - - -class DiskChecker: - def __init__(self, type, do, ignore): - self.type = type - self.do = do - self.ignore = ignore - self.func = do - def __call__(self, *args, **kw): - return self.func(*args, **kw) - def set(self, list): - if self.type in list: - self.func = self.do - else: - self.func = self.ignore - -def do_diskcheck_match(node, predicate, errorfmt): - result = predicate() - try: - # If calling the predicate() cached a None value from stat(), - # remove it so it doesn't interfere with later attempts to - # build this Node as we walk the DAG. (This isn't a great way - # to do this, we're reaching into an interface that doesn't - # really belong to us, but it's all about performance, so - # for now we'll just document the dependency...) - if node._memo['stat'] is None: - del node._memo['stat'] - except (AttributeError, KeyError): - pass - if result: - raise TypeError(errorfmt % node.get_abspath()) - -def ignore_diskcheck_match(node, predicate, errorfmt): - pass - - - -diskcheck_match = DiskChecker('match', do_diskcheck_match, ignore_diskcheck_match) - -diskcheckers = [ - diskcheck_match, -] - -def set_diskcheck(list): - for dc in diskcheckers: - dc.set(list) - -def diskcheck_types(): - return [dc.type for dc in diskcheckers] - - - -class EntryProxy(SCons.Util.Proxy): - - __str__ = SCons.Util.Delegate('__str__') - - # In PY3 if a class defines __eq__, then it must explicitly provide - # __hash__. Since SCons.Util.Proxy provides __eq__ we need the following - # see: https://docs.python.org/3/reference/datamodel.html#object.__hash__ - __hash__ = SCons.Util.Delegate('__hash__') - - def __get_abspath(self): - entry = self.get() - return SCons.Subst.SpecialAttrWrapper(entry.get_abspath(), - entry.name + "_abspath") - - def __get_filebase(self): - name = self.get().name - return SCons.Subst.SpecialAttrWrapper(SCons.Util.splitext(name)[0], - name + "_filebase") - - def __get_suffix(self): - name = self.get().name - return SCons.Subst.SpecialAttrWrapper(SCons.Util.splitext(name)[1], - name + "_suffix") - - def __get_file(self): - name = self.get().name - return SCons.Subst.SpecialAttrWrapper(name, name + "_file") - - def __get_base_path(self): - """Return the file's directory and file name, with the - suffix stripped.""" - entry = self.get() - return SCons.Subst.SpecialAttrWrapper(SCons.Util.splitext(entry.get_path())[0], - entry.name + "_base") - - def __get_posix_path(self): - """Return the path with / as the path separator, - regardless of platform.""" - if os_sep_is_slash: - return self - else: - entry = self.get() - r = entry.get_path().replace(OS_SEP, '/') - return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_posix") - - def __get_windows_path(self): - r"""Return the path with \ as the path separator, - regardless of platform.""" - if OS_SEP == '\\': - return self - else: - entry = self.get() - r = entry.get_path().replace(OS_SEP, '\\') - return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_windows") - - def __get_srcnode(self): - return EntryProxy(self.get().srcnode()) - - def __get_srcdir(self): - """Returns the directory containing the source node linked to this - node via VariantDir(), or the directory of this node if not linked.""" - return EntryProxy(self.get().srcnode().dir) - - def __get_rsrcnode(self): - return EntryProxy(self.get().srcnode().rfile()) - - def __get_rsrcdir(self): - """Returns the directory containing the source node linked to this - node via VariantDir(), or the directory of this node if not linked.""" - return EntryProxy(self.get().srcnode().rfile().dir) - - def __get_dir(self): - return EntryProxy(self.get().dir) - - dictSpecialAttrs = { "base" : __get_base_path, - "posix" : __get_posix_path, - "windows" : __get_windows_path, - "win32" : __get_windows_path, - "srcpath" : __get_srcnode, - "srcdir" : __get_srcdir, - "dir" : __get_dir, - "abspath" : __get_abspath, - "filebase" : __get_filebase, - "suffix" : __get_suffix, - "file" : __get_file, - "rsrcpath" : __get_rsrcnode, - "rsrcdir" : __get_rsrcdir, - } - - def __getattr__(self, name): - # This is how we implement the "special" attributes - # such as base, posix, srcdir, etc. - try: - attr_function = self.dictSpecialAttrs[name] - except KeyError: - try: - attr = SCons.Util.Proxy.__getattr__(self, name) - except AttributeError: - # 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) - - -class Base(SCons.Node.Node): - """A generic class for file system entries. This class is for - when we don't know yet whether the entry being looked up is a file - or a directory. Instances of this class can morph into either - Dir or File objects by a later, more precise lookup. - - Note: this class does not define __cmp__ and __hash__ for - efficiency reasons. SCons does a lot of comparing of - Node.FS.{Base,Entry,File,Dir} objects, so those operations must be - as fast as possible, which means we want to use Python's built-in - object identity comparisons. - """ - - __slots__ = ['name', - 'fs', - '_abspath', - '_labspath', - '_path', - '_tpath', - '_path_elements', - 'dir', - 'cwd', - 'duplicate', - '_local', - 'sbuilder', - '_proxy', - '_func_sconsign'] - - def __init__(self, name, directory, fs): - """Initialize a generic Node.FS.Base object. - - Call the superclass initialization, take care of setting up - our relative and absolute paths, identify our parent - directory, and indicate that this node should use - signatures.""" - - if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Base') - SCons.Node.Node.__init__(self) - - # Filenames and paths are probably reused and are intern'ed to save some memory. - # Filename with extension as it was specified when the object was - # created; to obtain filesystem path, use Python str() function - self.name = SCons.Util.silent_intern(name) - self.fs = fs #: Reference to parent Node.FS object - - assert directory, "A directory must be provided" - - self._abspath = None - self._labspath = None - self._path = None - self._tpath = None - self._path_elements = None - - self.dir = directory - self.cwd = None # will hold the SConscript directory for target nodes - self.duplicate = directory.duplicate - self.changed_since_last_build = 2 - self._func_sconsign = 0 - self._func_exists = 2 - self._func_rexists = 2 - self._func_get_contents = 0 - self._func_target_from_source = 1 - self.store_info = 1 - - 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 - specified klass. Raise an exception if it isn't. - """ - if isinstance(self, klass) or klass is Entry: - return - raise TypeError("Tried to lookup %s '%s' as a %s." %\ - (self.__class__.__name__, self.get_internal_path(), klass.__name__)) - - def get_dir(self): - return self.dir - - def get_suffix(self): - return SCons.Util.splitext(self.name)[1] - - def rfile(self): - return self - - def __getattr__(self, attr): - """ Together with the node_bwcomp dict defined below, - this method provides a simple backward compatibility - layer for the Node attributes 'abspath', 'labspath', - 'path', 'tpath', 'suffix' and 'path_elements'. These Node - attributes used to be directly available in v2.3 and earlier, but - have been replaced by getter methods that initialize the - single variables lazily when required, in order to save memory. - The redirection to the getters lets older Tools and - SConstruct continue to work without any additional changes, - fully transparent to the user. - Note, that __getattr__ is only called as fallback when the - requested attribute can't be found, so there should be no - speed performance penalty involved for standard builds. - """ - if attr in node_bwcomp: - return node_bwcomp[attr](self) - - raise AttributeError("%r object has no attribute %r" % - (self.__class__, attr)) - - def __str__(self): - """A Node.FS.Base object's string representation is its path - name.""" - global Save_Strings - if Save_Strings: - return self._save_str() - return self._get_str() - - def __lt__(self, other): - """ less than operator used by sorting on py3""" - return str(self) < str(other) - - @SCons.Memoize.CountMethodCall - def _save_str(self): - try: - return self._memo['_save_str'] - except KeyError: - pass - result = SCons.Util.silent_intern(self._get_str()) - self._memo['_save_str'] = result - return result - - def _get_str(self): - global Save_Strings - if self.duplicate or self.is_derived(): - return self.get_path() - srcnode = self.srcnode() - if srcnode.stat() is None and self.stat() is not None: - result = self.get_path() - else: - result = srcnode.get_path() - if not Save_Strings: - # We're not at the point where we're saving the string - # representations of FS Nodes (because we haven't finished - # reading the SConscript files and need to have str() return - # things relative to them). That also means we can't yet - # cache values returned (or not returned) by stat(), since - # Python code in the SConscript files might still create - # or otherwise affect the on-disk file. So get rid of the - # values that the underlying stat() method saved. - try: del self._memo['stat'] - except KeyError: pass - if self is not srcnode: - try: del srcnode._memo['stat'] - except KeyError: pass - return result - - rstr = __str__ - - @SCons.Memoize.CountMethodCall - def stat(self): - try: - return self._memo['stat'] - except KeyError: - pass - try: - result = self.fs.stat(self.get_abspath()) - except os.error: - result = None - - self._memo['stat'] = result - return result - - @SCons.Memoize.CountMethodCall - def lstat(self): - try: - return self._memo['lstat'] - except KeyError: - pass - try: - result = self.fs.lstat(self.get_abspath()) - except os.error: - result = None - - self._memo['lstat'] = result - return result - - def exists(self): - return SCons.Node._exists_map[self._func_exists](self) - - def rexists(self): - return SCons.Node._rexists_map[self._func_rexists](self) - - def getmtime(self): - if self.islink(): - st = self.lstat() - else: - st = self.stat() - - if st: - return st[stat.ST_MTIME] - else: - return None - - def getsize(self): - if self.islink(): - st = self.lstat() - else: - st = self.stat() - - if st: - return st[stat.ST_SIZE] - else: - return None - - def isdir(self): - st = self.stat() - return st is not None and stat.S_ISDIR(st[stat.ST_MODE]) - - def isfile(self): - st = self.stat() - return st is not None and stat.S_ISREG(st[stat.ST_MODE]) - - if hasattr(os, 'symlink'): - def islink(self): - try: st = self.fs.lstat(self.get_abspath()) - except os.error: return 0 - return stat.S_ISLNK(st[stat.ST_MODE]) - else: - def islink(self): - return 0 # no symlinks - - def is_under(self, dir): - if self is dir: - return 1 - else: - return self.dir.is_under(dir) - - def set_local(self): - self._local = 1 - - def srcnode(self): - """If this node is in a build path, return the node - corresponding to its source file. Otherwise, return - ourself. - """ - srcdir_list = self.dir.srcdir_list() - if srcdir_list: - srcnode = srcdir_list[0].Entry(self.name) - srcnode.must_be_same(self.__class__) - return srcnode - return self - - def get_path(self, dir=None): - """Return path relative to the current working directory of the - Node.FS.Base object that owns us.""" - if not dir: - dir = self.fs.getcwd() - if self == dir: - return '.' - path_elems = self.get_path_elements() - pathname = '' - try: i = path_elems.index(dir) - except ValueError: - for p in path_elems[:-1]: - pathname += p.dirname - else: - for p in path_elems[i+1:-1]: - pathname += p.dirname - return pathname + path_elems[-1].name - - def set_src_builder(self, builder): - """Set the source code builder for this node.""" - self.sbuilder = builder - if not self.has_builder(): - self.builder_set(builder) - - def src_builder(self): - """Fetch the source code builder for this node. - - If there isn't one, we cache the source code builder specified - for the directory (which in turn will cache the value from its - parent directory, and so on up to the file system root). - """ - try: - scb = self.sbuilder - except AttributeError: - scb = self.dir.src_builder() - self.sbuilder = scb - return scb - - def get_abspath(self): - """Get the absolute path of the file.""" - return self.dir.entry_abspath(self.name) - - def get_labspath(self): - """Get the absolute path of the file.""" - return self.dir.entry_labspath(self.name) - - def get_internal_path(self): - if self.dir._path == '.': - return self.name - else: - return self.dir.entry_path(self.name) - - def get_tpath(self): - if self.dir._tpath == '.': - return self.name - else: - return self.dir.entry_tpath(self.name) - - def get_path_elements(self): - return self.dir._path_elements + [self] - - def for_signature(self): - # Return just our name. Even an absolute path would not work, - # because that can change thanks to symlinks or remapped network - # paths. - return self.name - - def get_subst_proxy(self): - try: - return self._proxy - except AttributeError: - ret = EntryProxy(self) - self._proxy = ret - return ret - - def target_from_source(self, prefix, suffix, splitext=SCons.Util.splitext): - """ - - Generates a target entry that corresponds to this entry (usually - a source file) with the specified prefix and suffix. - - Note that this method can be overridden dynamically for generated - files that need different behavior. See Tool/swig.py for - an example. - """ - return SCons.Node._target_from_source_map[self._func_target_from_source](self, prefix, suffix, splitext) - - def _Rfindalldirs_key(self, pathlist): - return pathlist - - @SCons.Memoize.CountDictCall(_Rfindalldirs_key) - def Rfindalldirs(self, pathlist): - """ - Return all of the directories for a given path list, including - corresponding "backing" directories in any repositories. - - The Node lookups are relative to this Node (typically a - directory), so memoizing result saves cycles from looking - up the same path for each target in a given directory. - """ - try: - memo_dict = self._memo['Rfindalldirs'] - except KeyError: - memo_dict = {} - self._memo['Rfindalldirs'] = memo_dict - else: - try: - return memo_dict[pathlist] - except KeyError: - pass - - create_dir_relative_to_self = self.Dir - result = [] - for path in pathlist: - if isinstance(path, SCons.Node.Node): - result.append(path) - else: - dir = create_dir_relative_to_self(path) - result.extend(dir.get_all_rdirs()) - - memo_dict[pathlist] = result - - return result - - def RDirs(self, pathlist): - """Search for a list of directories in the Repository list.""" - cwd = self.cwd or self.fs._cwd - return cwd.Rfindalldirs(pathlist) - - @SCons.Memoize.CountMethodCall - def rentry(self): - try: - return self._memo['rentry'] - except KeyError: - pass - result = self - if not self.exists(): - norm_name = _my_normcase(self.name) - for dir in self.dir.get_all_rdirs(): - try: - node = dir.entries[norm_name] - except KeyError: - if dir.entry_exists_on_disk(self.name): - result = dir.Entry(self.name) - break - self._memo['rentry'] = result - return result - - def _glob1(self, pattern, ondisk=True, source=False, strings=False): - return [] - -# Dict that provides a simple backward compatibility -# layer for the Node attributes 'abspath', 'labspath', -# 'path', 'tpath' and 'path_elements'. -# @see Base.__getattr__ above -node_bwcomp = {'abspath' : Base.get_abspath, - 'labspath' : Base.get_labspath, - 'path' : Base.get_internal_path, - 'tpath' : Base.get_tpath, - 'path_elements' : Base.get_path_elements, - 'suffix' : Base.get_suffix} - -class Entry(Base): - """This is the class for generic Node.FS entries--that is, things - that could be a File or a Dir, but we're just not sure yet. - Consequently, the methods in this class really exist just to - transform their associated object into the right class when the - time comes, and then call the same-named method in the transformed - class.""" - - __slots__ = ['scanner_paths', - 'cachedir_csig', - 'cachesig', - 'repositories', - 'srcdir', - 'entries', - 'searched', - '_sconsign', - 'variant_dirs', - 'root', - 'dirname', - 'on_disk_entries', - 'released_target_info', - 'contentsig'] - - def __init__(self, name, directory, fs): - Base.__init__(self, name, directory, fs) - self._func_exists = 3 - self._func_get_contents = 1 - - def diskcheck_match(self): - pass - - def disambiguate(self, must_exist=None): - """ - """ - if self.isfile(): - self.__class__ = File - self._morph() - self.clear() - elif self.isdir(): - self.__class__ = Dir - self._morph() - else: - # There was nothing on-disk at this location, so look in - # the src directory. - # - # We can't just use self.srcnode() straight away because - # that would create an actual Node for this file in the src - # directory, and there might not be one. Instead, use the - # dir_on_disk() method to see if there's something on-disk - # with that name, in which case we can go ahead and call - # self.srcnode() to create the right type of entry. - srcdir = self.dir.srcnode() - if srcdir != self.dir and \ - srcdir.entry_exists_on_disk(self.name) and \ - self.srcnode().isdir(): - self.__class__ = Dir - self._morph() - elif must_exist: - msg = "No such file or directory: '%s'" % self.get_abspath() - raise SCons.Errors.UserError(msg) - else: - self.__class__ = File - self._morph() - self.clear() - return self - - def rfile(self): - """We're a generic Entry, but the caller is actually looking for - a File at this point, so morph into one.""" - self.__class__ = File - self._morph() - self.clear() - return File.rfile(self) - - def scanner_key(self): - return self.get_suffix() - - def get_contents(self): - """Fetch the contents of the entry. Returns the exact binary - contents of the file.""" - return SCons.Node._get_contents_map[self._func_get_contents](self) - - def get_text_contents(self): - """Fetch the decoded text contents of a Unicode encoded Entry. - - Since this should return the text contents from the file - system, we check to see into what sort of subclass we should - morph this Entry.""" - try: - self = self.disambiguate(must_exist=1) - except SCons.Errors.UserError: - # There was nothing on disk with which to disambiguate - # this entry. Leave it as an Entry, but return a null - # string so calls to get_text_contents() in emitters and - # the like (e.g. in qt.py) don't have to disambiguate by - # hand or catch the exception. - return '' - else: - return self.get_text_contents() - - 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 self.__class__ is not klass: - self.__class__ = klass - self._morph() - self.clear() - - # The following methods can get called before the Taskmaster has - # had a chance to call disambiguate() directly to see if this Entry - # should really be a Dir or a File. We therefore use these to call - # disambiguate() transparently (from our caller's point of view). - # - # Right now, this minimal set of methods has been derived by just - # looking at some of the methods that will obviously be called early - # in any of the various Taskmasters' calling sequences, and then - # empirically figuring out which additional methods are necessary - # to make various tests pass. - - def exists(self): - return SCons.Node._exists_map[self._func_exists](self) - - def rel_path(self, other): - d = self.disambiguate() - if d.__class__ is Entry: - raise Exception("rel_path() could not disambiguate File/Dir") - return d.rel_path(other) - - def new_ninfo(self): - return self.disambiguate().new_ninfo() - - def _glob1(self, pattern, ondisk=True, source=False, strings=False): - return self.disambiguate()._glob1(pattern, ondisk, source, strings) - - def get_subst_proxy(self): - return self.disambiguate().get_subst_proxy() - -# This is for later so we can differentiate between Entry the class and Entry -# the method of the FS class. -_classEntry = Entry - - -class LocalFS: - """ - This class implements an abstraction layer for operations involving - a local file system. Essentially, this wraps any function in - the os, os.path or shutil modules that we use to actually go do - anything with or to the local file system. - - Note that there's a very good chance we'll refactor this part of - the architecture in some way as we really implement the interface(s) - for remote file system Nodes. For example, the right architecture - might be to have this be a subclass instead of a base class. - Nevertheless, we're using this as a first step in that direction. - - We're not using chdir() yet because the calling subclass method - needs to use os.chdir() directly to avoid recursion. Will we - really need this one? - """ - #def chdir(self, path): - # return os.chdir(path) - def chmod(self, path, mode): - return os.chmod(path, mode) - def copy(self, src, dst): - return shutil.copy(src, dst) - def copy2(self, src, dst): - return shutil.copy2(src, dst) - def exists(self, path): - return os.path.exists(path) - def getmtime(self, path): - return os.path.getmtime(path) - def getsize(self, path): - return os.path.getsize(path) - def isdir(self, path): - return os.path.isdir(path) - def isfile(self, path): - return os.path.isfile(path) - def link(self, src, dst): - return os.link(src, dst) - def lstat(self, path): - return os.lstat(path) - def listdir(self, path): - return os.listdir(path) - def makedirs(self, path): - return os.makedirs(path) - def mkdir(self, path): - return os.mkdir(path) - def rename(self, old, new): - return os.rename(old, new) - def stat(self, path): - return os.stat(path) - def symlink(self, src, dst): - return os.symlink(src, dst) - def open(self, path): - return open(path) - def unlink(self, path): - return os.unlink(path) - - if hasattr(os, 'symlink'): - def islink(self, path): - return os.path.islink(path) - else: - def islink(self, path): - return 0 # no symlinks - - if hasattr(os, 'readlink'): - def readlink(self, file): - return os.readlink(file) - else: - def readlink(self, file): - return '' - - -class FS(LocalFS): - - def __init__(self, path = None): - """Initialize the Node.FS subsystem. - - The supplied path is the top of the source tree, where we - expect to find the top-level build file. If no path is - supplied, the current directory is the default. - - The path argument must be a valid absolute path. - """ - if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS') - - self._memo = {} - - self.Root = {} - self.SConstruct_dir = None - self.max_drift = default_max_drift - - self.Top = None - if path is None: - self.pathTop = os.getcwd() - else: - self.pathTop = path - self.defaultDrive = _my_normcase(_my_splitdrive(self.pathTop)[0]) - - self.Top = self.Dir(self.pathTop) - self.Top._path = '.' - self.Top._tpath = '.' - self._cwd = self.Top - - DirNodeInfo.fs = self - FileNodeInfo.fs = self - - def set_SConstruct_dir(self, dir): - self.SConstruct_dir = dir - - def get_max_drift(self): - return self.max_drift - - def set_max_drift(self, max_drift): - self.max_drift = max_drift - - def getcwd(self): - if hasattr(self, "_cwd"): - return self._cwd - else: - return "" - - def chdir(self, dir, change_os_dir=0): - """Change the current working directory for lookups. - If change_os_dir is true, we will also change the "real" cwd - to match. - """ - curr=self._cwd - try: - if dir is not None: - self._cwd = dir - if change_os_dir: - os.chdir(dir.get_abspath()) - except OSError: - self._cwd = curr - raise - - def get_root(self, drive): - """ - Returns the root directory for the specified drive, creating - it if necessary. - """ - drive = _my_normcase(drive) - try: - return self.Root[drive] - except KeyError: - root = RootDir(drive, self) - self.Root[drive] = root - if not drive: - self.Root[self.defaultDrive] = root - elif drive == self.defaultDrive: - self.Root[''] = root - return root - - def _lookup(self, p, directory, fsclass, create=1): - """ - The generic entry point for Node lookup with user-supplied data. - - This translates arbitrary input into a canonical Node.FS object - of the specified fsclass. The general approach for strings is - to turn it into a fully normalized absolute path and then call - the root directory's lookup_abs() method for the heavy lifting. - - If the path name begins with '#', it is unconditionally - interpreted relative to the top-level directory of this FS. '#' - is treated as a synonym for the top-level SConstruct directory, - much like '~' is treated as a synonym for the user's home - directory in a UNIX shell. So both '#foo' and '#/foo' refer - to the 'foo' subdirectory underneath the top-level SConstruct - directory. - - If the path name is relative, then the path is looked up relative - to the specified directory, or the current directory (self._cwd, - typically the SConscript directory) if the specified directory - is None. - """ - if isinstance(p, Base): - # It's already a Node.FS object. Make sure it's the right - # class and return. - p.must_be_same(fsclass) - return p - # str(p) in case it's something like a proxy object - p = str(p) - - if not os_sep_is_slash: - p = p.replace(OS_SEP, '/') - - if p[0:1] == '#': - # There was an initial '#', so we strip it and override - # whatever directory they may have specified with the - # top-level SConstruct directory. - p = p[1:] - directory = self.Top - - # There might be a drive letter following the - # '#'. Although it is not described in the SCons man page, - # the regression test suite explicitly tests for that - # syntax. It seems to mean the following thing: - # - # Assuming the the SCons top dir is in C:/xxx/yyy, - # '#X:/toto' means X:/xxx/yyy/toto. - # - # i.e. it assumes that the X: drive has a directory - # structure similar to the one found on drive C:. - if do_splitdrive: - drive, p = _my_splitdrive(p) - if drive: - root = self.get_root(drive) - else: - root = directory.root - else: - root = directory.root - - # We can only strip trailing after splitting the drive - # since the drive might the UNC '//' prefix. - p = p.strip('/') - - needs_normpath = needs_normpath_match(p) - - # The path is relative to the top-level SCons directory. - if p in ('', '.'): - p = directory.get_labspath() - else: - p = directory.get_labspath() + '/' + p - else: - if do_splitdrive: - drive, p = _my_splitdrive(p) - if drive and not p: - # This causes a naked drive letter to be treated - # as a synonym for the root directory on that - # drive. - p = '/' - else: - drive = '' - - # We can only strip trailing '/' since the drive might the - # UNC '//' prefix. - if p != '/': - p = p.rstrip('/') - - needs_normpath = needs_normpath_match(p) - - if p[0:1] == '/': - # Absolute path - root = self.get_root(drive) - else: - # This is a relative lookup or to the current directory - # (the path name is not absolute). Add the string to the - # appropriate directory lookup path, after which the whole - # thing gets normalized. - if directory: - if not isinstance(directory, Dir): - directory = self.Dir(directory) - else: - directory = self._cwd - - if p in ('', '.'): - p = directory.get_labspath() - else: - p = directory.get_labspath() + '/' + p - - if drive: - root = self.get_root(drive) - else: - root = directory.root - - if needs_normpath is not None: - # Normalize a pathname. Will return the same result for - # equivalent paths. - # - # We take advantage of the fact that we have an absolute - # path here for sure. In addition, we know that the - # components of lookup path are separated by slashes at - # this point. Because of this, this code is about 2X - # faster than calling os.path.normpath() followed by - # replacing os.sep with '/' again. - ins = p.split('/')[1:] - outs = [] - for d in ins: - if d == '..': - try: - outs.pop() - except IndexError: - pass - elif d not in ('', '.'): - outs.append(d) - p = '/' + '/'.join(outs) - - return root._lookup_abs(p, fsclass, create) - - def Entry(self, name, directory = None, create = 1): - """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 - construction time) if no directory is supplied. - """ - return self._lookup(name, directory, Entry, create) - - def File(self, name, directory = None, create = 1): - """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 - time) if no directory is supplied. - - This method will raise TypeError if a directory is found at the - specified path. - """ - return self._lookup(name, directory, File, create) - - def Dir(self, name, directory = None, create = True): - """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 - time) if no directory is supplied. - - This method will raise TypeError if a normal file is found at the - specified path. - """ - return self._lookup(name, directory, Dir, create) - - 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(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'."%(variant_dir, variant_dir.srcdir)) - variant_dir.link(src_dir, duplicate) - - def Repository(self, *dirs): - """Specify Repository directories to search.""" - for d in dirs: - if not isinstance(d, SCons.Node.Node): - d = self.Dir(d) - self.Top.addRepository(d) - - def PyPackageDir(self, modulename): - r"""Locate the directory of a given python module name - - For example scons might resolve to - Windows: C:\Python27\Lib\site-packages\scons-2.5.1 - Linux: /usr/lib/scons - - This can be useful when we want to determine a toolpath based on a python module name""" - - dirpath = '' - - # Python3 Code - modspec = importlib.util.find_spec(modulename) - dirpath = os.path.dirname(modspec.origin) - return self._lookup(dirpath, None, Dir, True) - - - 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 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 - the command-line targets. - """ - targets = [] - message = None - fmt = "building associated VariantDir targets: %s" - start_dir = dir - while dir: - 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) - p = os.path.join(bd._path, *tail) - targets.append(self.Entry(p)) - tail = [dir.name] + tail - dir = dir.up() - if targets: - message = fmt % ' '.join(map(str, targets)) - return targets, message - - def Glob(self, pathname, ondisk=True, source=True, strings=False, exclude=None, cwd=None): - """ - Globs - - This is mainly a shim layer - """ - if cwd is None: - cwd = self.getcwd() - return cwd.glob(pathname, ondisk, source, strings, exclude) - -class DirNodeInfo(SCons.Node.NodeInfoBase): - __slots__ = () - # This should get reset by the FS initialization. - current_version_id = 2 - - fs = None - - def str_to_node(self, s): - top = self.fs.Top - root = top.root - if do_splitdrive: - drive, s = _my_splitdrive(s) - if drive: - root = self.fs.get_root(drive) - if not os.path.isabs(s): - s = top.get_labspath() + '/' + s - return root._lookup_abs(s, Entry) - -class DirBuildInfo(SCons.Node.BuildInfoBase): - __slots__ = () - current_version_id = 2 - -glob_magic_check = re.compile('[*?[]') - -def has_glob_magic(s): - return glob_magic_check.search(s) is not None - -class Dir(Base): - """A class for directories in a file system. - """ - - __slots__ = ['scanner_paths', - 'cachedir_csig', - 'cachesig', - 'repositories', - 'srcdir', - 'entries', - 'searched', - '_sconsign', - 'variant_dirs', - 'root', - 'dirname', - 'on_disk_entries', - 'released_target_info', - 'contentsig'] - - NodeInfo = DirNodeInfo - BuildInfo = DirBuildInfo - - def __init__(self, name, directory, fs): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Dir') - Base.__init__(self, name, directory, fs) - self._morph() - - def _morph(self): - """Turn a file system Node (either a freshly initialized directory - object or a separate Entry object) into a proper directory object. - - Set up this directory's entries and hook it into the file - system tree. Specify that directories (this Node) don't use - signatures for calculating whether they're current. - """ - - self.repositories = [] - self.srcdir = None - - self.entries = {'.': self, '..': self.dir} - self.cwd = self - self.searched = 0 - self._sconsign = None - self.variant_dirs = [] - self.root = self.dir.root - self.changed_since_last_build = 3 - self._func_sconsign = 1 - self._func_exists = 2 - self._func_get_contents = 2 - - self._abspath = SCons.Util.silent_intern(self.dir.entry_abspath(self.name)) - self._labspath = SCons.Util.silent_intern(self.dir.entry_labspath(self.name)) - if self.dir._path == '.': - self._path = SCons.Util.silent_intern(self.name) - else: - self._path = SCons.Util.silent_intern(self.dir.entry_path(self.name)) - if self.dir._tpath == '.': - self._tpath = SCons.Util.silent_intern(self.name) - else: - self._tpath = SCons.Util.silent_intern(self.dir.entry_tpath(self.name)) - self._path_elements = self.dir._path_elements + [self] - - # For directories, we make a difference between the directory - # 'name' and the directory 'dirname'. The 'name' attribute is - # used when we need to print the 'name' of the directory or - # when we it is used as the last part of a path. The 'dirname' - # is used when the directory is not the last element of the - # path. The main reason for making that distinction is that - # for RoorDir's the dirname can not be easily inferred from - # the name. For example, we have to add a '/' after a drive - # letter but not after a UNC path prefix ('//'). - self.dirname = self.name + OS_SEP - - # Don't just reset the executor, replace its action list, - # because it might have some pre-or post-actions that need to - # be preserved. - # - # But don't reset the executor if there is a non-null executor - # attached already. The existing executor might have other - # targets, in which case replacing the action list with a - # Mkdir action is a big mistake. - if not hasattr(self, 'executor'): - self.builder = get_MkdirBuilder() - self.get_executor().set_action_list(self.builder.action) - else: - # Prepend MkdirBuilder action to existing action list - l = self.get_executor().action_list - a = get_MkdirBuilder().action - l.insert(0, a) - self.get_executor().set_action_list(l) - - def diskcheck_match(self): - diskcheck_match(self, self.isfile, - "File %s found where directory expected.") - - def __clearRepositoryCache(self, duplicate=None): - """Called when we change the repository(ies) for a directory. - This clears any cached information that is invalidated by changing - the repository.""" - - for node in self.entries.values(): - if node != self.dir: - if node != self and isinstance(node, Dir): - node.__clearRepositoryCache(duplicate) - else: - node.clear() - try: - del node._srcreps - except AttributeError: - pass - if duplicate is not None: - node.duplicate = duplicate - - def __resetDuplicate(self, node): - if node != self: - node.duplicate = node.get_dir().duplicate - - def Entry(self, name): - """ - Looks up or creates an entry node named 'name' relative to - this directory. - """ - return self.fs.Entry(name, self) - - def Dir(self, name, create=True): - """ - Looks up or creates a directory node named 'name' relative to - this directory. - """ - return self.fs.Dir(name, self, create) - - def File(self, name): - """ - Looks up or creates a file node named 'name' relative to - this directory. - """ - return self.fs.File(name, self) - - def link(self, srcdir, duplicate): - """Set this directory as the variant directory for the - supplied source directory.""" - self.srcdir = srcdir - self.duplicate = duplicate - self.__clearRepositoryCache(duplicate) - srcdir.variant_dirs.append(self) - - def getRepositories(self): - """Returns a list of repositories for this directory. - """ - if self.srcdir and not self.duplicate: - return self.srcdir.get_all_rdirs() + self.repositories - return self.repositories - - @SCons.Memoize.CountMethodCall - def get_all_rdirs(self): - try: - return list(self._memo['get_all_rdirs']) - except KeyError: - pass - - result = [self] - fname = '.' - dir = self - while dir: - for rep in dir.getRepositories(): - result.append(rep.Dir(fname)) - if fname == '.': - fname = dir.name - else: - fname = dir.name + OS_SEP + fname - dir = dir.up() - - self._memo['get_all_rdirs'] = list(result) - - return result - - def addRepository(self, dir): - if dir != self and dir not in self.repositories: - self.repositories.append(dir) - dir._tpath = '.' - self.__clearRepositoryCache() - - def up(self): - return self.dir - - def _rel_path_key(self, other): - return str(other) - - @SCons.Memoize.CountDictCall(_rel_path_key) - def rel_path(self, other): - """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. - # - # 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'] - except KeyError: - memo_dict = {} - self._memo['rel_path'] = memo_dict - else: - try: - return memo_dict[other] - except KeyError: - pass - - if self is other: - result = '.' - - elif other not in self._path_elements: - try: - other_dir = other.get_dir() - except AttributeError: - result = str(other) - else: - if other_dir is None: - result = other.name - else: - dir_rel_path = self.rel_path(other_dir) - if dir_rel_path == '.': - 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) \ - + [n.name for n in other._path_elements[i:]] - - result = OS_SEP.join(path_elems) - - memo_dict[other] = result - - return result - - def get_env_scanner(self, env, kw={}): - import SCons.Defaults - return SCons.Defaults.DirEntryScanner - - def get_target_scanner(self): - import SCons.Defaults - return SCons.Defaults.DirEntryScanner - - def get_found_includes(self, env, scanner, path): - """Return this directory's implicit dependencies. - - We don't bother caching the results because the scan typically - shouldn't be requested more than once (as opposed to scanning - .h file contents, which can be requested as many times as the - files is #included by other files). - """ - if not scanner: - return [] - # Clear cached info for this Dir. If we already visited this - # directory on our walk down the tree (because we didn't know at - # that point it was being used as the source for another Node) - # then we may have calculated build signature before realizing - # we had to scan the disk. Now that we have to, though, we need - # to invalidate the old calculated signature so that any node - # dependent on our directory structure gets one that includes - # info about everything on disk. - self.clear() - return scanner(self, env, path) - - # - # Taskmaster interface subsystem - # - - def prepare(self): - pass - - def build(self, **kw): - """A null "builder" for directories.""" - global MkdirBuilder - if self.builder is not MkdirBuilder: - SCons.Node.Node.build(self, **kw) - - # - # - # - - def _create(self): - """Create this directory, silently and without worrying about - whether the builder is the default or not.""" - listDirs = [] - parent = self - while parent: - if parent.exists(): - break - listDirs.append(parent) - p = parent.up() - if p is None: - # Don't use while: - else: for this condition because - # if so, then parent is None and has no .path attribute. - raise SCons.Errors.StopError(parent._path) - parent = p - listDirs.reverse() - for dirnode in listDirs: - try: - # Don't call dirnode.build(), call the base Node method - # directly because we definitely *must* create this - # directory. The dirnode.build() method will suppress - # the build if it's the default builder. - SCons.Node.Node.build(dirnode) - dirnode.get_executor().nullify() - # The build() action may or may not have actually - # created the directory, depending on whether the -n - # option was used or not. Delete the _exists and - # _rexists attributes so they can be reevaluated. - dirnode.clear() - except OSError: - pass - - def multiple_side_effect_has_builder(self): - global MkdirBuilder - return self.builder is not MkdirBuilder and self.has_builder() - - def alter_targets(self): - """Return any corresponding targets in a variant directory. - """ - return self.fs.variant_dir_target_climb(self, self, []) - - def scanner_key(self): - """A directory does not get scanned.""" - return None - - def get_text_contents(self): - """We already emit things in text, so just return the binary - version.""" - return self.get_contents() - - def get_contents(self): - """Return content signatures and names of all our children - separated by new-lines. Ensure that the nodes are sorted.""" - return SCons.Node._get_contents_map[self._func_get_contents](self) - - 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 MD5signature(contents) - - def do_duplicate(self, src): - pass - - def is_up_to_date(self): - """If any child is not up-to-date, then this directory isn't, - either.""" - 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(): - if kid.get_state() > up_to_date: - return 0 - return 1 - - def rdir(self): - if not self.exists(): - norm_name = _my_normcase(self.name) - for dir in self.dir.get_all_rdirs(): - try: node = dir.entries[norm_name] - except KeyError: node = dir.dir_on_disk(self.name) - if node and node.exists() and \ - (isinstance(dir, Dir) or isinstance(dir, Entry)): - return node - return self - - def sconsign(self): - """Return the .sconsign file info for this directory. """ - return _sconsign_map[self._func_sconsign](self) - - def srcnode(self): - """Dir has a special need for srcnode()...if we - have a srcdir attribute set, then that *is* our srcnode.""" - if self.srcdir: - return self.srcdir - return Base.srcnode(self) - - def get_timestamp(self): - """Return the latest timestamp from among our children""" - stamp = 0 - for kid in self.children(): - if kid.get_timestamp() > stamp: - stamp = kid.get_timestamp() - return stamp - - def get_abspath(self): - """Get the absolute path of the file.""" - return self._abspath - - def get_labspath(self): - """Get the absolute path of the file.""" - return self._labspath - - def get_internal_path(self): - return self._path - - def get_tpath(self): - return self._tpath - - def get_path_elements(self): - return self._path_elements - - def entry_abspath(self, name): - return self._abspath + OS_SEP + name - - def entry_labspath(self, name): - return self._labspath + '/' + name - - def entry_path(self, name): - return self._path + OS_SEP + name - - def entry_tpath(self, name): - return self._tpath + OS_SEP + name - - def entry_exists_on_disk(self, name): - """ Searches through the file/dir entries of the current - directory, and returns True if a physical entry with the given - name could be found. - - @see rentry_exists_on_disk - """ - try: - d = self.on_disk_entries - except AttributeError: - d = {} - try: - entries = os.listdir(self._abspath) - except OSError: - pass - else: - for entry in map(_my_normcase, entries): - d[entry] = True - self.on_disk_entries = d - if sys.platform == 'win32' or sys.platform == 'cygwin': - name = _my_normcase(name) - result = d.get(name) - if result is None: - # Belt-and-suspenders for Windows: check directly for - # 8.3 file names that don't show up in os.listdir(). - result = os.path.exists(self._abspath + OS_SEP + name) - d[name] = result - return result - else: - return name in d - - def rentry_exists_on_disk(self, name): - """ Searches through the file/dir entries of the current - *and* all its remote directories (repos), and returns - True if a physical entry with the given name could be found. - The local directory (self) gets searched first, so - repositories take a lower precedence regarding the - searching order. - - @see entry_exists_on_disk - """ - - rentry_exists = self.entry_exists_on_disk(name) - if not rentry_exists: - # Search through the repository folders - norm_name = _my_normcase(name) - for rdir in self.get_all_rdirs(): - try: - node = rdir.entries[norm_name] - if node: - rentry_exists = True - break - except KeyError: - if rdir.entry_exists_on_disk(name): - rentry_exists = True - break - return rentry_exists - - @SCons.Memoize.CountMethodCall - def srcdir_list(self): - try: - return self._memo['srcdir_list'] - except KeyError: - pass - - result = [] - - dirname = '.' - dir = self - while dir: - if dir.srcdir: - result.append(dir.srcdir.Dir(dirname)) - dirname = dir.name + OS_SEP + dirname - dir = dir.up() - - self._memo['srcdir_list'] = result - - return result - - def srcdir_duplicate(self, name): - for dir in self.srcdir_list(): - if self.is_under(dir): - # We shouldn't source from something in the build path; - # variant_dir is probably under src_dir, in which case - # we are reflecting. - break - if dir.entry_exists_on_disk(name): - srcnode = dir.Entry(name).disambiguate() - if self.duplicate: - node = self.Entry(name).disambiguate() - node.do_duplicate(srcnode) - return node - else: - return srcnode - return None - - def _srcdir_find_file_key(self, filename): - return filename - - @SCons.Memoize.CountDictCall(_srcdir_find_file_key) - def srcdir_find_file(self, filename): - try: - memo_dict = self._memo['srcdir_find_file'] - except KeyError: - memo_dict = {} - self._memo['srcdir_find_file'] = memo_dict - else: - try: - return memo_dict[filename] - except KeyError: - pass - - def func(node): - if (isinstance(node, File) or isinstance(node, Entry)) and \ - (node.is_derived() or node.exists()): - return node - return None - - norm_name = _my_normcase(filename) - - for rdir in self.get_all_rdirs(): - try: node = rdir.entries[norm_name] - except KeyError: node = rdir.file_on_disk(filename) - else: node = func(node) - if node: - result = (node, self) - memo_dict[filename] = result - return result - - for srcdir in self.srcdir_list(): - for rdir in srcdir.get_all_rdirs(): - try: node = rdir.entries[norm_name] - except KeyError: node = rdir.file_on_disk(filename) - else: node = func(node) - if node: - result = (File(filename, self, self.fs), srcdir) - memo_dict[filename] = result - return result - - result = (None, None) - memo_dict[filename] = result - return result - - def dir_on_disk(self, name): - if self.entry_exists_on_disk(name): - try: return self.Dir(name) - except TypeError: pass - 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): - try: return self.File(name) - except TypeError: pass - node = self.srcdir_duplicate(name) - if isinstance(node, Dir): - return None - return node - - def walk(self, func, arg): - """ - Walk this directory tree by calling the specified function - for each directory in the tree. - - This behaves like the os.path.walk() function, but for in-memory - Node.FS.Dir objects. The function takes the same arguments as - the functions passed to os.path.walk(): - - func(arg, dirname, fnames) - - Except that "dirname" will actually be the directory *Node*, - not the string. The '.' and '..' entries are excluded from - fnames. The fnames list may be modified in-place to filter the - subdirectories visited or otherwise impose a specific order. - The "arg" argument is always passed to func() and may be used - in any way (or ignored, passing None is common). - """ - entries = self.entries - names = list(entries.keys()) - names.remove('.') - names.remove('..') - func(arg, self, names) - for dirname in [n for n in names if isinstance(entries[n], Dir)]: - entries[dirname].walk(func, arg) - - def glob(self, pathname, ondisk=True, source=False, strings=False, exclude=None): - """ - Returns a list of Nodes (or strings) matching a specified - pathname pattern. - - Pathname patterns follow UNIX shell semantics: * matches - any-length strings of any characters, ? matches any character, - and [] can enclose lists or ranges of characters. Matches do - not span directory separators. - - The matches take into account Repositories, returning local - Nodes if a corresponding entry exists in a Repository (either - an in-memory Node or something on disk). - - By defafult, the glob() function matches entries that exist - on-disk, in addition to in-memory Nodes. Setting the "ondisk" - argument to False (or some other non-true value) causes the glob() - function to only match in-memory Nodes. The default behavior is - to return both the on-disk and in-memory Nodes. - - The "source" argument, when true, specifies that corresponding - source Nodes must be returned if you're globbing in a build - 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. - - The "exclude" argument, if not None, must be a pattern or a list - of patterns following the same UNIX shell semantics. - Elements matching a least one pattern of this list will be excluded - from the result. - - The underlying algorithm is adapted from the glob.glob() function - in the Python library (but heavily modified), and uses fnmatch() - under the covers. - """ - dirname, basename = os.path.split(pathname) - if not dirname: - result = self._glob1(basename, ondisk, source, strings) - else: - if has_glob_magic(dirname): - list = self.glob(dirname, ondisk, source, False, exclude) - else: - list = [self.Dir(dirname, create=True)] - result = [] - for dir in list: - r = dir._glob1(basename, ondisk, source, strings) - if strings: - r = [os.path.join(str(dir), x) for x in r] - result.extend(r) - if exclude: - excludes = [] - excludeList = SCons.Util.flatten(exclude) - for x in excludeList: - r = self.glob(x, ondisk, source, strings) - excludes.extend(r) - result = [x for x in result if not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes))] - return sorted(result, key=lambda a: str(a)) - - def _glob1(self, pattern, ondisk=True, source=False, strings=False): - """ - Globs for and returns a list of entry names matching a single - pattern in this directory. - - This searches any repositories and source directories for - corresponding entries and returns a Node (or string) relative - to the current directory if an entry is found anywhere. - - TODO: handle pattern with no wildcard - """ - search_dir_list = self.get_all_rdirs() - 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 - # the dir.entries dictionary are normalized (that is, all upper - # case) on case-insensitive systems like Windows. - node_names = [ v.name for k, v in dir.entries.items() - if k not in ('.', '..') ] - names.extend(node_names) - if not strings: - # Make sure the working directory (self) actually has - # entries for all Nodes in repositories or variant dirs. - for name in node_names: selfEntry(name) - if ondisk: - try: - disk_names = os.listdir(dir._abspath) - except os.error: - 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 = [x for x in disk_names if x[0] != '.'] - 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] != '.': - names = [x for x in names if x[0] != '.'] - names = fnmatch.filter(names, pattern) - - if strings: - return names - - return [self.entries[_my_normcase(n)] for n in names] - -class RootDir(Dir): - """A class for the root directory of a file system. - - This is the same as a Dir class, except that the path separator - ('/' or '\\') is actually part of the name, so we don't need to - add a separator when creating the path names of entries within - this directory. - """ - - __slots__ = ('_lookupDict', 'abspath', 'path') - - def __init__(self, drive, fs): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.RootDir') - SCons.Node.Node.__init__(self) - - # Handle all the types of drives: - if drive == '': - # No drive, regular UNIX root or Windows default drive. - name = OS_SEP - dirname = OS_SEP - elif drive == '//': - # UNC path - name = UNC_PREFIX - dirname = UNC_PREFIX - else: - # Windows drive letter - name = drive - dirname = drive + OS_SEP - - # Filename with extension as it was specified when the object was - # created; to obtain filesystem path, use Python str() function - self.name = SCons.Util.silent_intern(name) - self.fs = fs #: Reference to parent Node.FS object - - self._path_elements = [self] - self.dir = self - self._func_rexists = 2 - self._func_target_from_source = 1 - self.store_info = 1 - - # Now set our paths to what we really want them to be. The - # name should already contain any necessary separators, such - # as the initial drive letter (the name) plus the directory - # separator, except for the "lookup abspath," which does not - # have the drive letter. - self._abspath = dirname - self._labspath = '' - self._path = dirname - self._tpath = dirname - self.dirname = dirname - - # EntryProxy interferes with this class and turns drive paths on - # Windows such as "C:" into "C:\C:". Avoid this problem by setting - # commonly-accessed attributes directly. - self.abspath = self._abspath - self.path = self._path - - self._morph() - - self.duplicate = 0 - self._lookupDict = {'': self, '/': self} - - self.root = self - # The // entry is necessary because os.path.normpath() - # preserves double slashes at the beginning of a path on Posix - # platforms. - if not has_unc: - self._lookupDict['//'] = self - - def _morph(self): - """Turn a file system Node (either a freshly initialized directory - object or a separate Entry object) into a proper directory object. - - Set up this directory's entries and hook it into the file - system tree. Specify that directories (this Node) don't use - signatures for calculating whether they're current. - """ - - self.repositories = [] - self.srcdir = None - - self.entries = {'.': self, '..': self.dir} - self.cwd = self - self.searched = 0 - self._sconsign = None - self.variant_dirs = [] - self.changed_since_last_build = 3 - self._func_sconsign = 1 - self._func_exists = 2 - self._func_get_contents = 2 - - # Don't just reset the executor, replace its action list, - # because it might have some pre-or post-actions that need to - # be preserved. - # - # But don't reset the executor if there is a non-null executor - # attached already. The existing executor might have other - # targets, in which case replacing the action list with a - # Mkdir action is a big mistake. - if not hasattr(self, 'executor'): - self.builder = get_MkdirBuilder() - self.get_executor().set_action_list(self.builder.action) - else: - # Prepend MkdirBuilder action to existing action list - l = self.get_executor().action_list - a = get_MkdirBuilder().action - l.insert(0, a) - self.get_executor().set_action_list(l) - - - def must_be_same(self, klass): - if klass is Dir: - return - Base.must_be_same(self, klass) - - def _lookup_abs(self, p, klass, create=1): - """ - Fast (?) lookup of a *normalized* absolute path. - - This method is intended for use by internal lookups with - already-normalized path data. For general-purpose lookups, - use the FS.Entry(), FS.Dir() or FS.File() methods. - - The caller is responsible for making sure we're passed a - normalized absolute path; we merely let Python's dictionary look - up and return the One True Node.FS object for the path. - - If a Node for the specified "p" doesn't already exist, and - "create" is specified, the Node may be created after recursive - invocation to find or create the parent directory or directories. - """ - k = _my_normcase(p) - try: - result = self._lookupDict[k] - except KeyError: - if not create: - msg = "No such file or directory: '%s' in '%s' (and create is False)" % (p, str(self)) - raise SCons.Errors.UserError(msg) - # There is no Node for this path name, and we're allowed - # to create it. - dir_name, file_name = p.rsplit('/',1) - dir_node = self._lookup_abs(dir_name, Dir) - result = klass(file_name, dir_node, self.fs) - - # 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. - result.must_be_same(klass) - return result - - def __str__(self): - return self._abspath - - def entry_abspath(self, name): - return self._abspath + name - - def entry_labspath(self, name): - return '/' + name - - def entry_path(self, name): - return self._path + name - - def entry_tpath(self, name): - return self._tpath + name - - def is_under(self, dir): - if self is dir: - return 1 - else: - return 0 - - def up(self): - return None - - def get_dir(self): - return None - - def src_builder(self): - return _null - - -class FileNodeInfo(SCons.Node.NodeInfoBase): - __slots__ = ('csig', 'timestamp', 'size') - current_version_id = 2 - - field_list = ['csig', 'timestamp', 'size'] - - # This should get reset by the FS initialization. - fs = None - - def str_to_node(self, s): - top = self.fs.Top - root = top.root - if do_splitdrive: - drive, s = _my_splitdrive(s) - if drive: - root = self.fs.get_root(drive) - if not os.path.isabs(s): - s = top.get_labspath() + '/' + s - return root._lookup_abs(s, Entry) - - def __getstate__(self): - """ - Return all fields that shall be pickled. Walk the slots in the class - hierarchy and add those to the state dictionary. If a '__dict__' slot is - available, copy all entries to the dictionary. Also include the version - id, which is fixed for all instances of a class. - """ - state = getattr(self, '__dict__', {}).copy() - for obj in type(self).mro(): - for name in getattr(obj, '__slots__', ()): - if hasattr(self, name): - state[name] = getattr(self, name) - - state['_version_id'] = self.current_version_id - try: - del state['__weakref__'] - except KeyError: - pass - - return state - - def __setstate__(self, state): - """ - Restore the attributes from a pickled state. - """ - # TODO check or discard version - del state['_version_id'] - for key, value in state.items(): - if key not in ('__weakref__',): - setattr(self, key, value) - - def __eq__(self, other): - return self.csig == other.csig and self.timestamp == other.timestamp and self.size == other.size - - def __ne__(self, other): - return not self.__eq__(other) - - -class FileBuildInfo(SCons.Node.BuildInfoBase): - """ - This is info loaded from sconsign. - - Attributes unique to FileBuildInfo: - dependency_map : Caches file->csig mapping - for all dependencies. Currently this is only used when using - MD5-timestamp decider. - It's used to ensure that we copy the correct csig from the - previous build to be written to .sconsign when current build - is done. Previously the matching of csig to file was strictly - by order they appeared in bdepends, bsources, or bimplicit, - and so a change in order or count of any of these could - yield writing wrong csig, and then false positive rebuilds - """ - __slots__ = ['dependency_map', ] - current_version_id = 2 - - def __setattr__(self, key, value): - - # If any attributes are changed in FileBuildInfo, we need to - # invalidate the cached map of file name to content signature - # heald in dependency_map. Currently only used with - # MD5-timestamp decider - if key != 'dependency_map' and hasattr(self, 'dependency_map'): - del self.dependency_map - - return super(FileBuildInfo, self).__setattr__(key, value) - - def convert_to_sconsign(self): - """ - Converts this FileBuildInfo object for writing to a .sconsign file - - This replaces each Node in our various dependency lists with its - usual string representation: relative to the top-level SConstruct - directory, or an absolute path if it's outside. - """ - if os_sep_is_slash: - node_to_str = str - else: - def node_to_str(n): - try: - s = n.get_internal_path() - except AttributeError: - s = str(n) - else: - s = s.replace(OS_SEP, '/') - return s - for attr in ['bsources', 'bdepends', 'bimplicit']: - try: - val = getattr(self, attr) - except AttributeError: - pass - else: - setattr(self, attr, list(map(node_to_str, val))) - - def convert_from_sconsign(self, dir, name): - """ - Converts a newly-read FileBuildInfo object for in-SCons use - - For normal up-to-date checking, we don't have any conversion to - perform--but we're leaving this method here to make that clear. - """ - pass - - def prepare_dependencies(self): - """ - Prepares a FileBuildInfo object for explaining what changed - - The bsources, bdepends and bimplicit lists have all been - stored on disk as paths relative to the top-level SConstruct - directory. Convert the strings to actual Nodes (for use by the - --debug=explain code and --implicit-cache). - """ - attrs = [ - ('bsources', 'bsourcesigs'), - ('bdepends', 'bdependsigs'), - ('bimplicit', 'bimplicitsigs'), - ] - for (nattr, sattr) in attrs: - try: - strings = getattr(self, nattr) - nodeinfos = getattr(self, sattr) - except AttributeError: - continue - if strings is None or nodeinfos is None: - continue - 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) - - 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): - result.append(str(bkid) + ': ' + - ' '.join(bkidsig.format(names=names))) - if not hasattr(self,'bact'): - self.bact = "none" - result.append('%s [%s]' % (self.bactsig, self.bact)) - return '\n'.join(result) - - -class File(Base): - """A class for files in a file system. - """ - - __slots__ = ['scanner_paths', - 'cachedir_csig', - 'cachesig', - 'repositories', - 'srcdir', - 'entries', - 'searched', - '_sconsign', - 'variant_dirs', - 'root', - 'dirname', - 'on_disk_entries', - 'released_target_info', - 'contentsig'] - - NodeInfo = FileNodeInfo - BuildInfo = FileBuildInfo - - # Although the command-line argument is in kilobytes, this is in bytes. - md5_chunksize = 65536 - - def diskcheck_match(self): - diskcheck_match(self, self.isdir, - "Directory %s found where file expected.") - - def __init__(self, name, directory, fs): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.File') - Base.__init__(self, name, directory, fs) - self._morph() - - def Entry(self, name): - """Create an entry node named 'name' relative to - 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 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.""" - return [self.Dir(p) for p in pathlist] - - def File(self, name): - """Create a file node named 'name' relative to - the directory of this file.""" - return self.dir.File(name) - - def _morph(self): - """Turn a file system node into a File object.""" - self.scanner_paths = {} - if not hasattr(self, '_local'): - self._local = 0 - if not hasattr(self, 'released_target_info'): - self.released_target_info = False - - self.store_info = 1 - self._func_exists = 4 - self._func_get_contents = 3 - - # Initialize this Node's decider function to decide_source() because - # every file is a source file until it has a Builder attached... - self.changed_since_last_build = 4 - - # If there was already a Builder set on this entry, then - # we need to make sure we call the target-decider function, - # not the source-decider. Reaching in and doing this by hand - # is a little bogus. We'd prefer to handle this by adding - # an Entry.builder_set() method that disambiguates like the - # other methods, but that starts running into problems with the - # fragile way we initialize Dir Nodes with their Mkdir builders, - # yet still allow them to be overridden by the user. Since it's - # not clear right now how to fix that, stick with what works - # until it becomes clear... - if self.has_builder(): - self.changed_since_last_build = 5 - - def scanner_key(self): - return self.get_suffix() - - def get_contents(self) -> bytes: - """Return the contents of the file as bytes.""" - return SCons.Node._get_contents_map[self._func_get_contents](self) - - def get_text_contents(self) -> str: - """Return the contents of the file in text form. - - This attempts to figure out what the encoding of the text is - based upon the BOM bytes, and then decodes the contents so that - it's a valid python string. - """ - contents = self.get_contents() - # The behavior of various decode() methods and functions - # w.r.t. the initial BOM bytes is different for different - # encodings and/or Python versions. ('utf-8' does not strip - # them, but has a 'utf-8-sig' which does; 'utf-16' seems to - # strip them; etc.) Just sidestep all the complication by - # explicitly stripping the BOM before we decode(). - if contents[:len(codecs.BOM_UTF8)] == codecs.BOM_UTF8: - return contents[len(codecs.BOM_UTF8):].decode('utf-8') - if contents[:len(codecs.BOM_UTF16_LE)] == codecs.BOM_UTF16_LE: - return contents[len(codecs.BOM_UTF16_LE):].decode('utf-16-le') - if contents[:len(codecs.BOM_UTF16_BE)] == codecs.BOM_UTF16_BE: - return contents[len(codecs.BOM_UTF16_BE):].decode('utf-16-be') - try: - return contents.decode('utf-8') - except UnicodeDecodeError as e: - try: - return contents.decode('latin-1') - except UnicodeDecodeError as e: - return contents.decode('utf-8', errors='backslashreplace') - - - def get_content_hash(self) -> str: - """Compute and return the hash of the file contents.""" - if not self.rexists(): - return MD5signature(SCons.Util.NOFILE) - fname = self.rfile().get_abspath() - try: - cs = MD5filesignature(fname, chunksize=File.md5_chunksize) - except EnvironmentError as e: - if not e.filename: - e.filename = fname - raise - return cs - - @SCons.Memoize.CountMethodCall - def get_size(self) -> int: - try: - return self._memo['get_size'] - except KeyError: - pass - - if self.rexists(): - size = self.rfile().getsize() - else: - # sentinel value for doesn't exist, even in repository - size = -1 - - self._memo['get_size'] = size - return size - - @SCons.Memoize.CountMethodCall - def get_timestamp(self) -> int: - try: - return self._memo['get_timestamp'] - except KeyError: - pass - - if self.rexists(): - timestamp = self.rfile().getmtime() - else: - timestamp = 0 - - self._memo['get_timestamp'] = timestamp - return timestamp - - convert_copy_attrs = [ - 'bsources', - 'bimplicit', - 'bdepends', - 'bact', - 'bactsig', - 'ninfo', - ] - - convert_sig_attrs = [ - 'bsourcesigs', - 'bimplicitsigs', - 'bdependsigs', - ] - - def convert_old_entry(self, old_entry): - # Convert a .sconsign entry from before the Big Signature - # Refactoring, doing what we can to convert its information - # to the new .sconsign entry format. - # - # The old format looked essentially like this: - # - # BuildInfo - # .ninfo (NodeInfo) - # .bsig - # .csig - # .timestamp - # .size - # .bsources - # .bsourcesigs ("signature" list) - # .bdepends - # .bdependsigs ("signature" list) - # .bimplicit - # .bimplicitsigs ("signature" list) - # .bact - # .bactsig - # - # The new format looks like this: - # - # .ninfo (NodeInfo) - # .bsig - # .csig - # .timestamp - # .size - # .binfo (BuildInfo) - # .bsources - # .bsourcesigs (NodeInfo list) - # .bsig - # .csig - # .timestamp - # .size - # .bdepends - # .bdependsigs (NodeInfo list) - # .bsig - # .csig - # .timestamp - # .size - # .bimplicit - # .bimplicitsigs (NodeInfo list) - # .bsig - # .csig - # .timestamp - # .size - # .bact - # .bactsig - # - # The basic idea of the new structure is that a NodeInfo always - # holds all available information about the state of a given Node - # at a certain point in time. The various .b*sigs lists can just - # be a list of pointers to the .ninfo attributes of the different - # dependent nodes, without any copying of information until it's - # time to pickle it for writing out to a .sconsign file. - # - # The complicating issue is that the *old* format only stored one - # "signature" per dependency, based on however the *last* build - # was configured. We don't know from just looking at it whether - # it was a build signature, a content signature, or a timestamp - # "signature". Since we no longer use build signatures, the - # best we can do is look at the length and if it's thirty two, - # assume that it was (or might have been) a content signature. - # If it was actually a build signature, then it will cause a - # rebuild anyway when it doesn't match the new content signature, - # but that's probably the best we can do. - import SCons.SConsign - new_entry = SCons.SConsign.SConsignEntry() - new_entry.binfo = self.new_binfo() - binfo = new_entry.binfo - for attr in self.convert_copy_attrs: - try: - value = getattr(old_entry, attr) - except AttributeError: - 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: - 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 - - @SCons.Memoize.CountMethodCall - def get_stored_info(self): - try: - return self._memo['get_stored_info'] - except KeyError: - pass - - try: - sconsign_entry = self.dir.sconsign().get_entry(self.name) - except (KeyError, EnvironmentError): - import SCons.SConsign - sconsign_entry = SCons.SConsign.SConsignEntry() - sconsign_entry.binfo = self.new_binfo() - sconsign_entry.ninfo = self.new_ninfo() - else: - if isinstance(sconsign_entry, FileBuildInfo): - # This is a .sconsign file from before the Big Signature - # Refactoring; convert it as best we can. - sconsign_entry = self.convert_old_entry(sconsign_entry) - try: - delattr(sconsign_entry.ninfo, 'bsig') - except AttributeError: - pass - - self._memo['get_stored_info'] = sconsign_entry - - return sconsign_entry - - def get_stored_implicit(self): - binfo = self.get_stored_info().binfo - binfo.prepare_dependencies() - try: return binfo.bimplicit - except AttributeError: return None - - def rel_path(self, other): - return self.dir.rel_path(other) - - def _get_found_includes_key(self, env, scanner, path): - return (id(env), id(scanner), path) - - @SCons.Memoize.CountDictCall(_get_found_includes_key) - def get_found_includes(self, env, scanner, path): - """Return the included implicit dependencies in this file. - Cache results so we only scan the file once per path - regardless of how many times this information is requested. - """ - memo_key = (id(env), id(scanner), path) - try: - memo_dict = self._memo['get_found_includes'] - except KeyError: - memo_dict = {} - self._memo['get_found_includes'] = memo_dict - else: - try: - return memo_dict[memo_key] - except KeyError: - pass - - if scanner: - result = [n.disambiguate() for n in scanner(self, env, path)] - else: - result = [] - - memo_dict[memo_key] = result - - return result - - def _createDir(self): - # ensure that the directories for this node are - # created. - self.dir._create() - - def push_to_cache(self): - """Try to push the node into a cache - """ - # This should get called before the Nodes' .built() method is - # called, which would clear the build signature if the file has - # a source scanner. - # - # We have to clear the local memoized values *before* we push - # the node to cache so that the memoization of the self.exists() - # return value doesn't interfere. - if self.nocache: - return - self.clear_memoized_values() - if self.exists(): - self.get_build_env().get_CacheDir().push(self) - - def retrieve_from_cache(self): - """Try to retrieve the node's content from a cache - - This method is called from multiple threads in a parallel build, - so only do thread safe stuff here. Do thread unsafe stuff in - built(). - - Returns true if the node was successfully retrieved. - """ - if self.nocache: - return None - if not self.is_derived(): - return None - return self.get_build_env().get_CacheDir().retrieve(self) - - def visited(self): - if self.exists() and self.executor is not None: - self.get_build_env().get_CacheDir().push_if_forced(self) - - ninfo = self.get_ninfo() - - csig = self.get_max_drift_csig() - if csig: - ninfo.csig = csig - - 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().merge(old.binfo) - - SCons.Node.store_info_map[self.store_info](self) - - def release_target_info(self): - """Called just after this node has been marked - up-to-date or was built completely. - - This is where we try to release as many target node infos - as possible for clean builds and update runs, in order - to minimize the overall memory consumption. - - We'd like to remove a lot more attributes like self.sources - and self.sources_set, but they might get used - in a next build step. For example, during configuration - the source files for a built E{*}.o file are used to figure out - which linker to use for the resulting Program (gcc vs. g++)! - That's why we check for the 'keep_targetinfo' attribute, - config Nodes and the Interactive mode just don't allow - an early release of most variables. - - In the same manner, we can't simply remove the self.attributes - here. The smart linking relies on the shared flag, and some - parts of the java Tool use it to transport information - about nodes... - - @see: built() and Node.release_target_info() - """ - if self.released_target_info or SCons.Node.interactive: - return - - if not hasattr(self.attributes, 'keep_targetinfo'): - # Cache some required values, before releasing - # stuff like env, executor and builder... - self.changed(allowcache=True) - self.get_contents_sig() - self.get_build_env() - # Now purge unneeded stuff to free memory... - self.executor = None - self._memo.pop('rfile', None) - self.prerequisites = None - # Cleanup lists, but only if they're empty - if not len(self.ignore_set): - self.ignore_set = None - if not len(self.implicit_set): - self.implicit_set = None - if not len(self.depends_set): - self.depends_set = None - if not len(self.ignore): - self.ignore = None - if not len(self.depends): - self.depends = None - # Mark this node as done, we only have to release - # the memory once... - self.released_target_info = True - - def find_src_builder(self): - if self.rexists(): - return None - scb = self.dir.src_builder() - if scb is _null: - scb = None - if scb is not None: - try: - b = self.builder - except AttributeError: - b = None - if b is None: - self.builder_set(scb) - return scb - - def has_src_builder(self): - """Return whether this Node has a source builder or not. - - If this Node doesn't have an explicit source code builder, this - is where we figure out, on the fly, if there's a transparent - source code builder for it. - - Note that if we found a source builder, we also set the - self.builder attribute, so that all of the methods that actually - *build* this file don't have to do anything different. - """ - try: - scb = self.sbuilder - except AttributeError: - scb = self.sbuilder = self.find_src_builder() - return scb is not None - - def alter_targets(self): - """Return any corresponding targets in a variant directory. - """ - if self.is_derived(): - return [], None - return self.fs.variant_dir_target_climb(self, self.dir, [self.name]) - - def _rmv_existing(self): - self.clear_memoized_values() - if SCons.Node.print_duplicate: - print("dup: removing existing target {}".format(self)) - e = Unlink(self, [], None) - if isinstance(e, SCons.Errors.BuildError): - raise e - - # - # Taskmaster interface subsystem - # - - def make_ready(self): - self.has_src_builder() - self.get_binfo() - - def prepare(self): - """Prepare for this file to be created.""" - SCons.Node.Node.prepare(self) - - if self.get_state() != SCons.Node.up_to_date: - # Exists will report False for dangling symlinks so if it - # exists or is a link (which would mean it's a dangling - # link) then we should remove it as appropriate. - if self.exists() or self.islink(): - if self.is_derived() and not self.precious: - self._rmv_existing() - else: - try: - self._createDir() - except SCons.Errors.StopError as drive: - raise SCons.Errors.StopError("No drive `{}' for target `{}'.".format(drive, self)) - - # - # - # - - def remove(self): - """Remove this file.""" - if self.exists() or self.islink(): - self.fs.unlink(self.get_internal_path()) - return 1 - return None - - def do_duplicate(self, src): - self._createDir() - if SCons.Node.print_duplicate: - print("dup: relinking variant '{}' from '{}'".format(self, src)) - Unlink(self, None, None) - e = Link(self, src, None) - if isinstance(e, SCons.Errors.BuildError): - raise SCons.Errors.StopError("Cannot duplicate `{}' in `{}': {}.".format(src.get_internal_path(), self.dir._path, e.errstr)) - self.linked = 1 - # The Link() action may or may not have actually - # created the file, depending on whether the -n - # option was used or not. Delete the _exists and - # _rexists attributes so they can be reevaluated. - self.clear() - - @SCons.Memoize.CountMethodCall - def exists(self): - try: - return self._memo['exists'] - except KeyError: - pass - result = SCons.Node._exists_map[self._func_exists](self) - self._memo['exists'] = result - return result - - # - # SIGNATURE SUBSYSTEM - # - - def get_max_drift_csig(self) -> str: - """ - 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) -> str: - """Generate a node's content signature.""" - ninfo = self.get_ninfo() - try: - return ninfo.csig - except AttributeError: - pass - - csig = self.get_max_drift_csig() - if csig is None: - try: - size = self.get_size() - if size == -1: - contents = SCons.Util.NOFILE - elif size < 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 - - return csig - - # - # DECISION SUBSYSTEM - # - - def builder_set(self, builder): - SCons.Node.Node.builder_set(self, builder) - self.changed_since_last_build = 5 - - def built(self): - """Called just after this File node is successfully built. - - Just like for 'release_target_info' we try to release - some more target node attributes in order to minimize the - overall memory consumption. - - @see: release_target_info - """ - - SCons.Node.Node.built(self) - - if (not SCons.Node.interactive and - not hasattr(self.attributes, 'keep_targetinfo')): - # Ensure that the build infos get computed and cached... - SCons.Node.store_info_map[self.store_info](self) - # ... then release some more variables. - self._specific_sources = False - self._labspath = None - self._save_str() - self.cwd = None - - self.scanner_paths = None - - def changed(self, node=None, allowcache=False): - """ - Returns if the node is up-to-date with respect to the BuildInfo - stored last time it was built. - - For File nodes this is basically a wrapper around Node.changed(), - but we allow the return value to get cached after the reference - to the Executor got released in release_target_info(). - - @see: Node.changed() - """ - if node is None: - try: - return self._memo['changed'] - except KeyError: - pass - - has_changed = SCons.Node.Node.changed(self, node) - if allowcache: - self._memo['changed'] = has_changed - return has_changed - - def changed_content(self, target, prev_ni, repo_node=None): - cur_csig = self.get_csig() - try: - return cur_csig != prev_ni.csig - except AttributeError: - return 1 - - def changed_state(self, target, prev_ni, repo_node=None): - return self.state != SCons.Node.up_to_date - - - # Caching node -> string mapping for the below method - __dmap_cache = {} - __dmap_sig_cache = {} - - - def _build_dependency_map(self, binfo): - """ - Build mapping from file -> signature - - Args: - self - self - binfo - buildinfo from node being considered - - Returns: - dictionary of file->signature mappings - """ - - # For an "empty" binfo properties like bsources - # do not exist: check this to avoid exception. - if (len(binfo.bsourcesigs) + len(binfo.bdependsigs) + - len(binfo.bimplicitsigs)) == 0: - return {} - - binfo.dependency_map = { child:signature for child, signature in zip(chain(binfo.bsources, binfo.bdepends, binfo.bimplicit), - chain(binfo.bsourcesigs, binfo.bdependsigs, binfo.bimplicitsigs))} - - return binfo.dependency_map - - # @profile - def _add_strings_to_dependency_map(self, dmap): - """ - In the case comparing node objects isn't sufficient, we'll add the strings for the nodes to the dependency map - :return: - """ - - first_string = str(next(iter(dmap))) - - # print("DMAP:%s"%id(dmap)) - if first_string not in dmap: - string_dict = {str(child): signature for child, signature in dmap.items()} - dmap.update(string_dict) - return dmap - - def _get_previous_signatures(self, dmap): - """ - Return a list of corresponding csigs from previous - build in order of the node/files in children. - - Args: - self - self - dmap - Dictionary of file -> csig - - Returns: - List of csigs for provided list of children - """ - prev = [] - # MD5_TIMESTAMP_DEBUG = False - - if len(dmap) == 0: - if MD5_TIMESTAMP_DEBUG: print("Nothing dmap shortcutting") - return None - elif MD5_TIMESTAMP_DEBUG: print("len(dmap):%d"%len(dmap)) - - - # First try retrieving via Node - if MD5_TIMESTAMP_DEBUG: print("Checking if self is in map:%s id:%s type:%s"%(str(self), id(self), type(self))) - df = dmap.get(self, False) - if df: - return df - - # Now check if self's repository file is in map. - rf = self.rfile() - if MD5_TIMESTAMP_DEBUG: print("Checking if self.rfile is in map:%s id:%s type:%s"%(str(rf), id(rf), type(rf))) - rfm = dmap.get(rf, False) - if rfm: - return rfm - - # get default string for node and then also string swapping os.altsep for os.sep (/ for \) - c_strs = [str(self)] - - if os.altsep: - c_strs.append(c_strs[0].replace(os.sep, os.altsep)) - - # In some cases the dependency_maps' keys are already strings check. - # Check if either string is now in dmap. - for s in c_strs: - if MD5_TIMESTAMP_DEBUG: print("Checking if str(self) is in map :%s" % s) - df = dmap.get(s, False) - if df: - return df - - # Strings don't exist in map, add them and try again - # If there are no strings in this dmap, then add them. - # This may not be necessary, we could walk the nodes in the dmap and check each string - # rather than adding ALL the strings to dmap. In theory that would be n/2 vs 2n str() calls on node - # if not dmap.has_strings: - dmap = self._add_strings_to_dependency_map(dmap) - - # In some cases the dependency_maps' keys are already strings check. - # Check if either string is now in dmap. - for s in c_strs: - if MD5_TIMESTAMP_DEBUG: print("Checking if str(self) is in map (now with strings) :%s" % s) - df = dmap.get(s, False) - if df: - return df - - # Lastly use nodes get_path() to generate string and see if that's in dmap - if not df: - try: - # this should yield a path which matches what's in the sconsign - c_str = self.get_path() - if os.altsep: - c_str = c_str.replace(os.sep, os.altsep) - - if MD5_TIMESTAMP_DEBUG: print("Checking if self.get_path is in map (now with strings) :%s" % s) - - df = dmap.get(c_str, None) - - except AttributeError as e: - raise FileBuildInfoFileToCsigMappingError("No mapping from file name to content signature for :%s"%c_str) - - return df - - def changed_timestamp_then_content(self, target, prev_ni, node=None): - """ - Used when decider for file is Timestamp-MD5 - - NOTE: If the timestamp hasn't changed this will skip md5'ing the - file and just copy the prev_ni provided. If the prev_ni - is wrong. It will propagate it. - See: https://github.com/SCons/scons/issues/2980 - - Args: - self - dependency - target - target - prev_ni - The NodeInfo object loaded from previous builds .sconsign - node - Node instance. Check this node for file existence/timestamp - if specified. - - Returns: - Boolean - Indicates if node(File) has changed. - """ - - if node is None: - node = self - # Now get sconsign name -> csig map and then get proper prev_ni if possible - bi = node.get_stored_info().binfo - rebuilt = False - try: - dependency_map = bi.dependency_map - except AttributeError as e: - dependency_map = self._build_dependency_map(bi) - rebuilt = True - - if len(dependency_map) == 0: - # If there's no dependency map, there's no need to find the - # prev_ni as there aren't any - # shortcut the rest of the logic - if MD5_TIMESTAMP_DEBUG: print("Skipping checks len(dmap)=0") - - # We still need to get the current file's csig - # This should be slightly faster than calling self.changed_content(target, new_prev_ni) - self.get_csig() - return True - - new_prev_ni = self._get_previous_signatures(dependency_map) - new = self.changed_timestamp_match(target, new_prev_ni) - - if MD5_TIMESTAMP_DEBUG: - old = self.changed_timestamp_match(target, prev_ni) - - if old != new: - print("Mismatch self.changed_timestamp_match(%s, prev_ni) old:%s new:%s"%(str(target), old, new)) - new_prev_ni = self._get_previous_signatures(dependency_map) - - if not new: - try: - # NOTE: We're modifying the current node's csig in a query. - self.get_ninfo().csig = new_prev_ni.csig - except AttributeError: - pass - return False - return self.changed_content(target, new_prev_ni) - - def changed_timestamp_newer(self, target, prev_ni, repo_node=None): - try: - return self.get_timestamp() > target.get_timestamp() - except AttributeError: - return 1 - - def changed_timestamp_match(self, target, prev_ni, repo_node=None): - """ - Return True if the timestamps don't match or if there is no previous timestamp - :param target: - :param prev_ni: Information about the node from the previous build - :return: - """ - try: - return self.get_timestamp() != prev_ni.timestamp - except AttributeError: - return 1 - - def is_up_to_date(self): - """Check for whether the Node is current - In all cases self is the target we're checking to see if it's up to date - """ - - T = 0 - if T: Trace('is_up_to_date(%s):' % self) - if not self.exists(): - if T: Trace(' not self.exists():') - # The file (always a target) doesn't exist locally... - r = self.rfile() - if r != self: - # ...but there is one (always a target) in a Repository... - if not self.changed(r): - if T: Trace(' changed(%s):' % r) - # ...and it's even up-to-date... - if self._local: - # ...and they'd like a local copy. - e = LocalCopy(self, r, None) - if isinstance(e, SCons.Errors.BuildError): - # Likely this should be re-raising exception e - # (which would be BuildError) - raise e - SCons.Node.store_info_map[self.store_info](self) - if T: Trace(' 1\n') - return 1 - self.changed() - if T: Trace(' None\n') - return None - else: - r = self.changed() - if T: Trace(' self.exists(): %s\n' % r) - return not r - - @SCons.Memoize.CountMethodCall - def rfile(self): - try: - return self._memo['rfile'] - except KeyError: - pass - result = self - if not self.exists(): - norm_name = _my_normcase(self.name) - for repo_dir in self.dir.get_all_rdirs(): - try: - node = repo_dir.entries[norm_name] - except KeyError: - node = repo_dir.file_on_disk(self.name) - - if node and node.exists() and \ - (isinstance(node, File) or isinstance(node, Entry) - or not node.is_derived()): - result = node - # Copy over our local attributes to the repository - # Node so we identify shared object files in the - # repository and don't assume they're static. - # - # This isn't perfect; the attribute would ideally - # be attached to the object in the repository in - # case it was built statically in the repository - # and we changed it to shared locally, but that's - # rarely the case and would only occur if you - # intentionally used the same suffix for both - # shared and static objects anyway. So this - # should work well in practice. - result.attributes = self.attributes - break - self._memo['rfile'] = result - return result - - def find_repo_file(self): - """ - For this node, find if there exists a corresponding file in one or more repositories - :return: list of corresponding files in repositories - """ - retvals = [] - - norm_name = _my_normcase(self.name) - for repo_dir in self.dir.get_all_rdirs(): - try: - node = repo_dir.entries[norm_name] - except KeyError: - node = repo_dir.file_on_disk(self.name) - - if node and node.exists() and \ - (isinstance(node, File) or isinstance(node, Entry) - or not node.is_derived()): - retvals.append(node) - - return retvals - - - def rstr(self): - return str(self.rfile()) - - def get_cachedir_csig(self): - """ - Fetch a Node's content signature for purposes of computing - another Node's cachesig. - - This is a wrapper around the normal get_csig() method that handles - the somewhat obscure case of using CacheDir with the -n option. - Any files that don't exist would normally be "built" by fetching - them from the cache, but the normal get_csig() method will try - to open up the local file, which doesn't exist because the -n - option meant we didn't actually pull the file from cachedir. - But since the file *does* actually exist in the cachedir, we - can use its contents for the csig. - """ - try: - return self.cachedir_csig - except AttributeError: - pass - - cachedir, cachefile = self.get_build_env().get_CacheDir().cachepath(self) - if not self.exists() and cachefile and os.path.exists(cachefile): - self.cachedir_csig = MD5filesignature(cachefile, File.md5_chunksize) - else: - self.cachedir_csig = self.get_csig() - return self.cachedir_csig - - def get_contents_sig(self): - """ - A helper method for get_cachedir_bsig. - - It computes and returns the signature for this - node's contents. - """ - - try: - return self.contentsig - except AttributeError: - pass - - executor = self.get_executor() - - result = self.contentsig = MD5signature(executor.get_contents()) - return result - - def get_cachedir_bsig(self): - """ - Return the signature for a cached file, including - its children. - - It adds the path of the cached file 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. - - Signature should normally be string of hex digits. - """ - try: - return self.cachesig - except AttributeError: - pass - - # Collect signatures for all children - children = self.children() - sigs = [n.get_cachedir_csig() for n in children] - - # Append this node's signature... - sigs.append(self.get_contents_sig()) - - # ...and it's path - sigs.append(self.get_internal_path()) - - # Merge this all into a single signature - result = self.cachesig = MD5collect(sigs) - return result - -default_fs = None - -def get_default_fs(): - global default_fs - if not default_fs: - default_fs = FS() - return default_fs - -class FileFinder: - """ - """ - - def __init__(self): - self._memo = {} - - def filedir_lookup(self, p, fd=None): - """ - A helper method for find_file() that looks up a directory for - a file we're trying to find. This only creates the Dir Node if - it exists on-disk, since if the directory doesn't exist we know - we won't find any files in it... :-) - - 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 so this work under Python 1.5.2. - """ - if fd is None: - fd = self.default_filedir - dir, name = os.path.split(fd) - drive, d = _my_splitdrive(dir) - if not name and d[:1] in ('/', OS_SEP): - #return p.fs.get_root(drive).dir_on_disk(name) - return p.fs.get_root(drive) - if dir: - p = self.filedir_lookup(p, dir) - if not p: - return None - norm_name = _my_normcase(name) - try: - node = p.entries[norm_name] - except KeyError: - return p.dir_on_disk(name) - if isinstance(node, Dir): - return node - if isinstance(node, Entry): - node.must_be_same(Dir) - return node - return None - - def _find_file_key(self, filename, paths, verbose=None): - return (filename, paths) - - @SCons.Memoize.CountDictCall(_find_file_key) - def find_file(self, filename, paths, verbose=None): - """ - Find a node corresponding to either a derived file or a file that exists already. - - Only the first file found is returned, and none is returned if no file is found. - - filename: A filename to find - paths: A list of directory path *nodes* to search in. Can be represented as a list, a tuple, or a callable that is called with no arguments and returns the list or tuple. - - returns The node created from the found file. - - """ - memo_key = self._find_file_key(filename, paths) - try: - memo_dict = self._memo['find_file'] - except KeyError: - memo_dict = {} - self._memo['find_file'] = memo_dict - else: - try: - return memo_dict[memo_key] - except KeyError: - pass - - if verbose and not callable(verbose): - if not SCons.Util.is_String(verbose): - verbose = "find_file" - _verbose = ' %s: ' % verbose - verbose = lambda s: sys.stdout.write(_verbose + s) - - filedir, filename = os.path.split(filename) - if filedir: - self.default_filedir = filedir - paths = [_f for _f in map(self.filedir_lookup, paths) if _f] - - result = None - for dir in paths: - if verbose: - verbose("looking for '%s' in '%s' ...\n" % (filename, dir)) - node, d = dir.srcdir_find_file(filename) - if node: - if verbose: - verbose("... FOUND '%s' in '%s'\n" % (filename, d)) - result = node - break - - memo_dict[memo_key] = result - - 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() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Node/Python.py b/scons/scons-local-4.1.0/SCons/Node/Python.py deleted file mode 100644 index 738682ccb..000000000 --- a/scons/scons-local-4.1.0/SCons/Node/Python.py +++ /dev/null @@ -1,202 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Python nodes.""" - -import SCons.Node - -_memo_lookup_map = {} - - -class ValueNodeInfo(SCons.Node.NodeInfoBase): - __slots__ = ('csig',) - current_version_id = 2 - - field_list = ['csig'] - - def str_to_node(self, s): - return ValueWithMemo(s) - - def __getstate__(self): - """ - Return all fields that shall be pickled. Walk the slots in the class - hierarchy and add those to the state dictionary. If a '__dict__' slot - is available, copy all entries to the dictionary. Also include the - version id, which is fixed for all instances of a class. - """ - state = getattr(self, '__dict__', {}).copy() - for obj in type(self).mro(): - for name in getattr(obj, '__slots__', ()): - if hasattr(self, name): - state[name] = getattr(self, name) - - state['_version_id'] = self.current_version_id - try: - del state['__weakref__'] - except KeyError: - pass - - return state - - def __setstate__(self, state): - """ - Restore the attributes from a pickled state. - """ - # TODO check or discard version - del state['_version_id'] - for key, value in state.items(): - if key not in ('__weakref__',): - setattr(self, key, value) - - -class ValueBuildInfo(SCons.Node.BuildInfoBase): - __slots__ = () - current_version_id = 2 - - -class Value(SCons.Node.Node): - """A class for Python variables, typically passed on the command line - or generated by a script, but not from a file or some other source. - """ - - NodeInfo = ValueNodeInfo - BuildInfo = ValueBuildInfo - - def __init__(self, value, built_value=None, name=None): - SCons.Node.Node.__init__(self) - self.value = value - self.changed_since_last_build = 6 - self.store_info = 0 - if built_value is not None: - self.built_value = built_value - - # Set a name so it can be a child of a node and not break - # its parent's implementation of Node.get_contents. - if name: - self.name = name - else: - self.name = str(value) - - def str_for_display(self): - return repr(self.value) - - def __str__(self): - return str(self.value) - - def make_ready(self): - self.get_csig() - - def build(self, **kw): - if not hasattr(self, 'built_value'): - SCons.Node.Node.build(self, **kw) - - is_up_to_date = SCons.Node.Node.children_are_up_to_date - - def is_under(self, dir): - # Make Value nodes get built regardless of - # what directory scons was run from. Value nodes - # are outside the filesystem: - return 1 - - def write(self, built_value): - """Set the value of the node.""" - self.built_value = built_value - - def read(self): - """Return the value. If necessary, the value is built.""" - self.build() - if not hasattr(self, 'built_value'): - self.built_value = self.value - return self.built_value - - def get_text_contents(self) -> str: - """By the assumption that the node.built_value is a - deterministic product of the sources, the contents of a Value - are the concatenation of all the contents of its sources. As - the value need not be built when get_contents() is called, we - cannot use the actual node.built_value.""" - ###TODO: something reasonable about universal newlines - contents = str(self.value) - for kid in self.children(None): - # Get csig() value of child as this is more efficent - contents = contents + kid.get_csig() - return contents - - def get_contents(self) -> bytes: - """Get contents for signature calculations.""" - return self.get_text_contents().encode() - - def changed_since_last_build(self, target, prev_ni): - cur_csig = self.get_csig() - try: - return cur_csig != prev_ni.csig - except AttributeError: - return True - - def get_csig(self, calc=None): - """Because we're a Python value node and don't have a real - timestamp, we get to ignore the calculator and just use the - value contents. - - Returns string. Ideally string of hex digits. (Not bytes) - """ - try: - return self.ninfo.csig - except AttributeError: - pass - - contents = self.get_text_contents() - - self.get_ninfo().csig = contents - return contents - - -def ValueWithMemo(value, built_value=None, name=None): - """ - Memoized Value() node factory. - """ - global _memo_lookup_map - - # No current support for memoizing a value that needs to be built. - if built_value: - return Value(value, built_value, name=name) - - try: - memo_lookup_key = hash((value, name)) - except TypeError: - # Non-primitive types will hit this codepath. - return Value(value, name=name) - - try: - return _memo_lookup_map[memo_lookup_key] - except KeyError: - v = Value(value, built_value, name) - _memo_lookup_map[memo_lookup_key] = v - return v - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Node/__init__.py b/scons/scons-local-4.1.0/SCons/Node/__init__.py deleted file mode 100644 index 491c6b8c5..000000000 --- a/scons/scons-local-4.1.0/SCons/Node/__init__.py +++ /dev/null @@ -1,1780 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""The Node package for the SCons software construction utility. - -This is, in many ways, the heart of SCons. - -A Node is where we encapsulate all of the dependency information about -any thing that SCons can build, or about any thing which SCons can use -to build some other thing. The canonical "thing," of course, is a file, -but a Node can also represent something remote (like a web page) or -something completely abstract (like an Alias). - -Each specific type of "thing" is specifically represented by a subclass -of the Node base class: Node.FS.File for files, Node.Alias for aliases, -etc. Dependency information is kept here in the base class, and -information specific to files/aliases/etc. is in the subclass. The -goal, if we've done this correctly, is that any type of "thing" should -be able to depend on any other type of "thing." - -""" - -import collections -import copy -from itertools import chain, zip_longest - -import SCons.Debug -import SCons.Executor -import SCons.Memoize -import SCons.Util -from SCons.compat import NoSlotsPyPy -from SCons.Debug import logInstanceCreation, Trace -from SCons.Util import MD5signature - -print_duplicate = 0 - -def classname(obj): - return str(obj.__class__).split('.')[-1] - -# Set to false if we're doing a dry run. There's more than one of these -# little treats -do_store_info = True - -# Node states -# -# These are in "priority" order, so that the maximum value for any -# child/dependency of a node represents the state of that node if -# it has no builder of its own. The canonical example is a file -# system directory, which is only up to date if all of its children -# were up to date. -no_state = 0 -pending = 1 -executing = 2 -up_to_date = 3 -executed = 4 -failed = 5 - -StateString = { - 0 : "no_state", - 1 : "pending", - 2 : "executing", - 3 : "up_to_date", - 4 : "executed", - 5 : "failed", -} - -# controls whether implicit dependencies are cached: -implicit_cache = 0 - -# controls whether implicit dep changes are ignored: -implicit_deps_unchanged = 0 - -# controls whether the cached implicit deps are ignored: -implicit_deps_changed = 0 - -# A variable that can be set to an interface-specific function be called -# to annotate a Node with information about its creation. -def do_nothing_node(node): pass - -Annotate = do_nothing_node - -# global set for recording all processed SContruct/SConscript nodes -SConscriptNodes = set() - -# Gets set to 'True' if we're running in interactive mode. Is -# currently used to release parts of a target's info during -# clean builds and update runs (see release_target_info). -interactive = False - -def is_derived_none(node): - raise NotImplementedError - -def is_derived_node(node): - """ - Returns true if this node is derived (i.e. built). - """ - return node.has_builder() or node.side_effect - -_is_derived_map = {0 : is_derived_none, - 1 : is_derived_node} - -def exists_none(node): - raise NotImplementedError - -def exists_always(node): - return 1 - -def exists_base(node): - return node.stat() is not None - -def exists_entry(node): - """Return if the Entry exists. Check the file system to see - what we should turn into first. Assume a file if there's no - directory.""" - node.disambiguate() - return _exists_map[node._func_exists](node) - - -def exists_file(node): - # Duplicate from source path if we are set up to do this. - if node.duplicate and not node.is_derived() and not node.linked: - src = node.srcnode() - if src is not node: - # At this point, src is meant to be copied in a variant directory. - src = src.rfile() - if src.get_abspath() != node.get_abspath(): - if src.exists(): - node.do_duplicate(src) - # Can't return 1 here because the duplication might - # 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 variant directory. - if print_duplicate: - print("dup: no src for %s, unlinking old variant copy" % node) - if exists_base(node) or node.islink(): - node.fs.unlink(node.get_internal_path()) - # Return None explicitly because the Base.exists() call - # above will have cached its value if the file existed. - return None - return exists_base(node) - -_exists_map = {0 : exists_none, - 1 : exists_always, - 2 : exists_base, - 3 : exists_entry, - 4 : exists_file} - - -def rexists_none(node): - raise NotImplementedError - -def rexists_node(node): - return node.exists() - -def rexists_base(node): - return node.rfile().exists() - -_rexists_map = {0 : rexists_none, - 1 : rexists_node, - 2 : rexists_base} - -def get_contents_none(node): - raise NotImplementedError - -def get_contents_entry(node): - """Fetch the contents of the entry. Returns the exact binary - contents of the file.""" - try: - node = node.disambiguate(must_exist=1) - except SCons.Errors.UserError: - # There was nothing on disk with which to disambiguate - # this entry. Leave it as an Entry, but return a null - # string so calls to get_contents() in emitters and the - # like (e.g. in qt.py) don't have to disambiguate by hand - # or catch the exception. - return '' - else: - return _get_contents_map[node._func_get_contents](node) - -def get_contents_dir(node): - """Return content signatures and names of all our children - separated by new-lines. Ensure that the nodes are sorted.""" - contents = [] - for n in sorted(node.children(), key=lambda t: t.name): - contents.append('%s %s\n' % (n.get_csig(), n.name)) - return ''.join(contents) - -def get_contents_file(node): - if not node.rexists(): - return b'' - fname = node.rfile().get_abspath() - try: - with open(fname, "rb") as fp: - contents = fp.read() - except EnvironmentError as e: - if not e.filename: - e.filename = fname - raise - return contents - -_get_contents_map = {0 : get_contents_none, - 1 : get_contents_entry, - 2 : get_contents_dir, - 3 : get_contents_file} - -def target_from_source_none(node, prefix, suffix, splitext): - raise NotImplementedError - -def target_from_source_base(node, prefix, suffix, splitext): - return node.dir.Entry(prefix + splitext(node.name)[0] + suffix) - -_target_from_source_map = {0 : target_from_source_none, - 1 : target_from_source_base} - -# -# The new decider subsystem for Nodes -# -# We would set and overwrite the changed_since_last_build function -# before, but for being able to use slots (less memory!) we now have -# a dictionary of the different decider functions. Then in the Node -# subclasses we simply store the index to the decider that should be -# used by it. -# - -# -# First, the single decider functions -# -def changed_since_last_build_node(node, target, prev_ni, repo_node=None): - """ - - Must be overridden in a specific subclass to return True if this - Node (a dependency) has changed since the last time it was used - to build the specified target. prev_ni is this Node's state (for - example, its file timestamp, length, maybe content signature) - as of the last time the target was built. - - Note that this method is called through the dependency, not the - target, because a dependency Node must be able to use its own - logic to decide if it changed. For example, File Nodes need to - obey if we're configured to use timestamps, but Python Value Nodes - never use timestamps and always use the content. If this method - were called through the target, then each Node's implementation - of this method would have to have more complicated logic to - handle all the different Node types on which it might depend. - """ - raise NotImplementedError - - -def changed_since_last_build_alias(node, target, prev_ni, repo_node=None): - cur_csig = node.get_csig() - try: - return cur_csig != prev_ni.csig - except AttributeError: - return 1 - - -def changed_since_last_build_entry(node, target, prev_ni, repo_node=None): - node.disambiguate() - return _decider_map[node.changed_since_last_build](node, target, prev_ni, repo_node) - - -def changed_since_last_build_state_changed(node, target, prev_ni, repo_node=None): - return node.state != SCons.Node.up_to_date - - -def decide_source(node, target, prev_ni, repo_node=None): - return target.get_build_env().decide_source(node, target, prev_ni, repo_node) - - -def decide_target(node, target, prev_ni, repo_node=None): - return target.get_build_env().decide_target(node, target, prev_ni, repo_node) - - -def changed_since_last_build_python(node, target, prev_ni, repo_node=None): - cur_csig = node.get_csig() - try: - return cur_csig != prev_ni.csig - except AttributeError: - return 1 - - -# -# Now, the mapping from indices to decider functions -# -_decider_map = {0 : changed_since_last_build_node, - 1 : changed_since_last_build_alias, - 2 : changed_since_last_build_entry, - 3 : changed_since_last_build_state_changed, - 4 : decide_source, - 5 : decide_target, - 6 : changed_since_last_build_python} - -do_store_info = True - -# -# The new store_info subsystem for Nodes -# -# We would set and overwrite the store_info function -# before, but for being able to use slots (less memory!) we now have -# a dictionary of the different functions. Then in the Node -# subclasses we simply store the index to the info method that should be -# used by it. -# - -# -# First, the single info functions -# - -def store_info_pass(node): - pass - -def store_info_file(node): - # Merge our build information into the already-stored entry. - # This accommodates "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. - if do_store_info: - node.dir.sconsign().store_info(node.name, node) - - -store_info_map = {0 : store_info_pass, - 1 : store_info_file} - -# Classes for signature info for Nodes. - -class NodeInfoBase: - """ - The generic base class for signature information for a Node. - - Node subclasses should subclass NodeInfoBase to provide their own - logic for dealing with their own Node-specific signature information. - """ - __slots__ = ('__weakref__',) - current_version_id = 2 - - def update(self, node): - try: - field_list = self.field_list - except AttributeError: - return - for f in field_list: - try: - delattr(self, f) - except AttributeError: - pass - try: - func = getattr(node, 'get_' + f) - except AttributeError: - pass - else: - setattr(self, f, func()) - - def convert(self, node, val): - pass - - def merge(self, other): - """ - Merge the fields of another object into this object. Already existing - information is overwritten by the other instance's data. - WARNING: If a '__dict__' slot is added, it should be updated instead of - replaced. - """ - state = other.__getstate__() - self.__setstate__(state) - - def format(self, field_list=None, names=0): - if field_list is None: - try: - field_list = self.field_list - except AttributeError: - field_list = list(getattr(self, '__dict__', {}).keys()) - for obj in type(self).mro(): - for slot in getattr(obj, '__slots__', ()): - if slot not in ('__weakref__', '__dict__'): - field_list.append(slot) - field_list.sort() - fields = [] - for field in field_list: - try: - f = getattr(self, field) - except AttributeError: - f = None - f = str(f) - if names: - f = field + ': ' + f - fields.append(f) - return fields - - def __getstate__(self): - """ - Return all fields that shall be pickled. Walk the slots in the class - hierarchy and add those to the state dictionary. If a '__dict__' slot is - available, copy all entries to the dictionary. Also include the version - id, which is fixed for all instances of a class. - """ - state = getattr(self, '__dict__', {}).copy() - for obj in type(self).mro(): - for name in getattr(obj,'__slots__',()): - if hasattr(self, name): - state[name] = getattr(self, name) - - state['_version_id'] = self.current_version_id - try: - del state['__weakref__'] - except KeyError: - pass - return state - - def __setstate__(self, state): - """ - Restore the attributes from a pickled state. The version is discarded. - """ - # TODO check or discard version - del state['_version_id'] - - for key, value in state.items(): - if key not in ('__weakref__',): - setattr(self, key, value) - - -class BuildInfoBase: - """ - The generic base class for build information for a Node. - - This is what gets stored in a .sconsign file for each target file. - It contains a NodeInfo instance for this node (signature information - that's specific to the type of Node) and direct attributes for the - generic build stuff we have to track: sources, explicit dependencies, - implicit dependencies, and action information. - """ - __slots__ = ("bsourcesigs", "bdependsigs", "bimplicitsigs", "bactsig", - "bsources", "bdepends", "bact", "bimplicit", "__weakref__") - current_version_id = 2 - - def __init__(self): - # Create an object attribute from the class attribute so it ends up - # in the pickled data in the .sconsign file. - self.bsourcesigs = [] - self.bdependsigs = [] - self.bimplicitsigs = [] - self.bactsig = None - - def merge(self, other): - """ - Merge the fields of another object into this object. Already existing - information is overwritten by the other instance's data. - WARNING: If a '__dict__' slot is added, it should be updated instead of - replaced. - """ - state = other.__getstate__() - self.__setstate__(state) - - def __getstate__(self): - """ - Return all fields that shall be pickled. Walk the slots in the class - hierarchy and add those to the state dictionary. If a '__dict__' slot is - available, copy all entries to the dictionary. Also include the version - id, which is fixed for all instances of a class. - """ - state = getattr(self, '__dict__', {}).copy() - for obj in type(self).mro(): - for name in getattr(obj,'__slots__',()): - if hasattr(self, name): - state[name] = getattr(self, name) - - state['_version_id'] = self.current_version_id - try: - del state['__weakref__'] - except KeyError: - pass - return state - - def __setstate__(self, state): - """ - Restore the attributes from a pickled state. - """ - # TODO check or discard version - del state['_version_id'] - for key, value in state.items(): - if key not in ('__weakref__',): - setattr(self, key, value) - - -class Node(object, metaclass=NoSlotsPyPy): - """The base Node class, for entities that we know how to - build, or use to build other Nodes. - """ - - __slots__ = ['sources', - 'sources_set', - 'target_peers', - '_specific_sources', - 'depends', - 'depends_set', - 'ignore', - 'ignore_set', - 'prerequisites', - 'implicit', - 'waiting_parents', - 'waiting_s_e', - 'ref_count', - 'wkids', - 'env', - 'state', - 'precious', - 'noclean', - 'nocache', - 'cached', - 'always_build', - 'includes', - 'attributes', - 'side_effect', - 'side_effects', - 'linked', - '_memo', - 'executor', - 'binfo', - 'ninfo', - 'builder', - 'is_explicit', - 'implicit_set', - 'changed_since_last_build', - 'store_info', - 'pseudo', - '_tags', - '_func_is_derived', - '_func_exists', - '_func_rexists', - '_func_get_contents', - '_func_target_from_source'] - - class Attrs: - __slots__ = ('shared', '__dict__') - - - def __init__(self): - if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node') - # Note that we no longer explicitly initialize a self.builder - # attribute to None here. That's because the self.builder - # attribute may be created on-the-fly later by a subclass (the - # canonical example being a builder to fetch a file from a - # source code system like CVS or Subversion). - - # Each list of children that we maintain is accompanied by a - # dictionary used to look up quickly whether a node is already - # present in the list. Empirical tests showed that it was - # fastest to maintain them as side-by-side Node attributes in - # this way, instead of wrapping up each list+dictionary pair in - # 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_set = set() - self._specific_sources = False - self.depends = [] # explicit dependencies (from Depends) - self.depends_set = set() - self.ignore = [] # dependencies to ignore - self.ignore_set = set() - self.prerequisites = None - self.implicit = None # implicit (scanned) dependencies (None means not scanned yet) - 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 - - self.env = None - self.state = no_state - self.precious = None - self.pseudo = False - self.noclean = 0 - self.nocache = 0 - self.cached = 0 # is this node pulled from cache? - self.always_build = None - 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 variant directory? - self.changed_since_last_build = 0 - self.store_info = 0 - self._tags = None - self._func_is_derived = 1 - self._func_exists = 1 - self._func_rexists = 1 - self._func_get_contents = 0 - self._func_target_from_source = 0 - self.ninfo = None - - self.clear_memoized_values() - - # Let the interface in which the build engine is embedded - # annotate this Node with its own info (like a description of - # what line in what file created the node, for example). - Annotate(self) - - def disambiguate(self, must_exist=None): - return self - - def get_suffix(self): - return '' - - @SCons.Memoize.CountMethodCall - def get_build_env(self): - """Fetch the appropriate Environment to build this node. - """ - try: - return self._memo['get_build_env'] - except KeyError: - pass - result = self.get_executor().get_build_env() - self._memo['get_build_env'] = result - return result - - def get_build_scanner_path(self, scanner): - """Fetch the appropriate scanner path for this node.""" - return self.get_executor().get_build_scanner_path(scanner) - - def set_executor(self, executor): - """Set the action executor for this node.""" - self.executor = executor - - def get_executor(self, create=1): - """Fetch the action executor for this node. Create one if - there isn't already one, and requested to do so.""" - try: - executor = self.executor - except AttributeError: - if not create: - raise - try: - act = self.builder.action - except AttributeError: - executor = SCons.Executor.Null(targets=[self]) - else: - executor = SCons.Executor.Executor(act, - self.env or self.builder.env, - [self.builder.overrides], - [self], - self.sources) - self.executor = executor - return executor - - def executor_cleanup(self): - """Let the executor clean up any cached information.""" - try: - executor = self.get_executor(create=None) - except AttributeError: - pass - else: - if executor is not None: - executor.cleanup() - - def reset_executor(self): - """Remove cached executor; forces recompute when needed.""" - try: - delattr(self, 'executor') - except AttributeError: - pass - - def push_to_cache(self): - """Try to push a node into a cache - """ - pass - - def retrieve_from_cache(self): - """Try to retrieve the node's content from a cache - - This method is called from multiple threads in a parallel build, - so only do thread safe stuff here. Do thread unsafe stuff in - built(). - - Returns true if the node was successfully retrieved. - """ - return 0 - - # - # Taskmaster interface subsystem - # - - def make_ready(self): - """Get a Node ready for evaluation. - - This is called before the Taskmaster decides if the Node is - up-to-date or not. Overriding this method allows for a Node - subclass to be disambiguated if necessary, or for an implicit - source builder to be attached. - """ - pass - - def prepare(self): - """Prepare for this Node to be built. - - This is called after the Taskmaster has decided that the Node - is out-of-date and must be rebuilt, but before actually calling - the method to build the Node. - - 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. - """ - if self.depends is not None: - 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 self.implicit is not None: - 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): - """Actually build the node. - - This is called by the Taskmaster after it's decided that the - Node is out-of-date and must be rebuilt, and after the prepare() - method has gotten everything, uh, prepared. - - This method is called from multiple threads in a parallel build, - so only do thread safe stuff here. Do thread unsafe stuff - in built(). - - """ - try: - self.get_executor()(self, **kw) - except SCons.Errors.BuildError as e: - e.node = self - raise - - def built(self): - """Called just after this node is successfully built.""" - - # Clear the implicit dependency caches of any Nodes - # waiting for this Node to be built. - for parent in self.waiting_parents: - parent.implicit = None - - # Handle issue where builder emits more than one target and - # the source file for the builder is generated. - # in that case only the first target was getting it's .implicit - # cleared when the source file is built (second scan). - # leaving only partial implicits from scan before source file is generated - # typically the compiler only. Then scanned files are appended - # This is persisted to sconsign and rebuild causes false rebuilds - # because the ordering of the implicit list then changes to what it - # should have been. - # This is at least the following bugs - # https://github.com/SCons/scons/issues/2811 - # https://jira.mongodb.org/browse/SERVER-33111 - try: - for peer in parent.target_peers: - peer.implicit = None - except AttributeError: - pass - - - self.clear() - - if self.pseudo: - if self.exists(): - raise SCons.Errors.UserError("Pseudo target " + str(self) + " must not exist") - else: - if not self.exists() and do_store_info: - SCons.Warnings.warn(SCons.Warnings.TargetNotBuiltWarning, - "Cannot find target " + str(self) + " after building") - self.ninfo.update(self) - - def visited(self): - """Called just after this node has been visited (with or - without a build).""" - try: - binfo = self.binfo - except AttributeError: - # Apparently this node doesn't need build info, so - # don't bother calculating or storing it. - pass - else: - self.ninfo.update(self) - SCons.Node.store_info_map[self.store_info](self) - - def release_target_info(self): - """Called just after this node has been marked - up-to-date or was built completely. - - This is where we try to release as many target node infos - as possible for clean builds and update runs, in order - to minimize the overall memory consumption. - - By purging attributes that aren't needed any longer after - a Node (=File) got built, we don't have to care that much how - many KBytes a Node actually requires...as long as we free - the memory shortly afterwards. - - @see: built() and File.release_target_info() - """ - pass - - def add_to_waiting_s_e(self, node): - self.waiting_s_e.add(node) - - def add_to_waiting_parents(self, node): - """ - Returns the number of nodes added to our waiting parents list: - 1 if we add a unique waiting parent, 0 if not. (Note that the - returned values are intended to be used to increment a reference - count, so don't think you can "clean up" this function by using - True and False instead...) - """ - wp = self.waiting_parents - 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 = 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). - """ - # 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() - for attr in ['cachedir_csig', 'cachesig', 'contentsig']: - try: - delattr(self, attr) - except AttributeError: - pass - self.cached = 0 - self.includes = None - - def clear_memoized_values(self): - self._memo = {} - - def builder_set(self, builder): - self.builder = builder - try: - del self.executor - except AttributeError: - pass - - def has_builder(self): - """Return whether this Node has a builder or not. - - In Boolean tests, this turns out to be a *lot* more efficient - than simply examining the builder attribute directly ("if - node.builder: ..."). When the builder attribute is examined - directly, it ends up calling __getattr__ for both the __len__ - and __bool__ attributes on instances of our Builder Proxy - class(es), generating a bazillion extra calls and slowing - things down immensely. - """ - try: - b = self.builder - except AttributeError: - # There was no explicit builder for this Node, so initialize - # the self.builder attribute to None now. - b = self.builder = None - return b is not None - - def set_explicit(self, is_explicit): - self.is_explicit = is_explicit - - def has_explicit_builder(self): - """Return whether this Node has an explicit builder - - This allows an internal Builder created by SCons to be marked - non-explicit, so that it can be overridden by an explicit - builder that the user supplies (the canonical example being - directories).""" - try: - return self.is_explicit - except AttributeError: - self.is_explicit = None - return self.is_explicit - - def get_builder(self, default_builder=None): - """Return the set builder, or a specified default value""" - try: - return self.builder - except AttributeError: - return default_builder - - multiple_side_effect_has_builder = has_builder - - def is_derived(self): - """ - Returns true if this node is derived (i.e. built). - - This should return true only for nodes whose path should be in - 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. - """ - return _is_derived_map[self._func_is_derived](self) - - def is_sconscript(self): - """ Returns true if this node is an sconscript """ - return self in SConscriptNodes - - def is_conftest(self): - """ Returns true if this node is an conftest node""" - try: - self.attributes.conftest_node - except AttributeError: - return False - return True - - def alter_targets(self): - """Return a list of alternate targets for this Node. - """ - return [], None - - def get_found_includes(self, env, scanner, path): - """Return the scanned include lines (implicit dependencies) - found in this node. - - The default is no implicit dependencies. We expect this method - to be overridden by any subclass that can be scanned for - implicit dependencies. - """ - return [] - - def get_implicit_deps(self, env, initial_scanner, path_func, kw = {}): - """Return a list of implicit dependencies for this node. - - This method exists to handle recursive invocation of the scanner - on the implicit dependencies returned by the scanner, if the - scanner's recursive flag says that we should. - """ - nodes = [self] - seen = set(nodes) - dependencies = [] - path_memo = {} - - root_node_scanner = self._get_scanner(env, initial_scanner, None, kw) - - while nodes: - node = nodes.pop(0) - - scanner = node._get_scanner(env, initial_scanner, root_node_scanner, kw) - if not scanner: - continue - - try: - path = path_memo[scanner] - except KeyError: - path = path_func(scanner) - path_memo[scanner] = path - - included_deps = [x for x in node.get_found_includes(env, scanner, path) if x not in seen] - if included_deps: - dependencies.extend(included_deps) - seen.update(included_deps) - nodes.extend(scanner.recurse_nodes(included_deps)) - - return dependencies - - def _get_scanner(self, env, initial_scanner, root_node_scanner, kw): - if initial_scanner: - # handle explicit scanner case - scanner = initial_scanner.select(self) - else: - # handle implicit scanner case - scanner = self.get_env_scanner(env, kw) - if scanner: - scanner = scanner.select(self) - - if not scanner: - # no scanner could be found for the given node's scanner key; - # thus, make an attempt at using a default. - scanner = root_node_scanner - - return scanner - - def get_env_scanner(self, env, kw={}): - return env.get_scanner(self.scanner_key()) - - def get_target_scanner(self): - return self.builder.target_scanner - - def get_source_scanner(self, node): - """Fetch the source scanner for the specified node - - NOTE: "self" is the target being built, "node" is - the source file for which we want to fetch the scanner. - - Implies self.has_builder() is true; again, expect to only be - called from locations where this is already verified. - - This function may be called very often; it attempts to cache - the scanner found to improve performance. - """ - scanner = None - try: - scanner = self.builder.source_scanner - except AttributeError: - pass - if not scanner: - # The builder didn't have an explicit scanner, so go look up - # a scanner from env['SCANNERS'] based on the node's scanner - # key (usually the file extension). - scanner = self.get_env_scanner(self.get_build_env()) - if scanner: - scanner = scanner.select(node) - return scanner - - def add_to_implicit(self, deps): - if not hasattr(self, 'implicit') or self.implicit is None: - self.implicit = [] - self.implicit_set = set() - self._children_reset() - self._add_child(self.implicit, self.implicit_set, deps) - - def scan(self): - """Scan this node's dependents for implicit dependencies.""" - # Don't bother scanning non-derived files, because we don't - # care what their dependencies are. - # Don't scan again, if we already have scanned. - if self.implicit is not None: - return - self.implicit = [] - self.implicit_set = set() - self._children_reset() - if not self.has_builder(): - return - - build_env = self.get_build_env() - executor = self.get_executor() - - # Here's where we implement --implicit-cache. - if implicit_cache and not implicit_deps_changed: - implicit = self.get_stored_implicit() - if implicit is not None: - # We now add the implicit dependencies returned from the - # stored .sconsign entry to have already been converted - # to Nodes for us. (We used to run them through a - # source_factory function here.) - - # Update all of the targets with them. This - # essentially short-circuits an N*M scan of the - # sources for each individual target, which is a hell - # of a lot more efficient. - for tgt in executor.get_all_targets(): - tgt.add_to_implicit(implicit) - - if implicit_deps_unchanged or self.is_up_to_date(): - return - # one of this node's sources has changed, - # so we must recalculate the implicit deps for all targets - for tgt in executor.get_all_targets(): - tgt.implicit = [] - tgt.implicit_set = set() - - # Have the executor scan the sources. - executor.scan_sources(self.builder.source_scanner) - - # If there's a target scanner, have the executor scan the target - # node itself and associated targets that might be built. - scanner = self.get_target_scanner() - if scanner: - executor.scan_targets(scanner) - - def scanner_key(self): - return None - - def select_scanner(self, scanner): - """Selects a scanner for this Node. - - This is a separate method so it can be overridden by Node - subclasses (specifically, Node.FS.Dir) that *must* use their - own Scanner and don't select one the Scanner.Selector that's - configured for the target. - """ - return scanner.select(self) - - def env_set(self, env, safe=0): - if safe and self.env: - return - self.env = env - - # - # SIGNATURE SUBSYSTEM - # - - NodeInfo = NodeInfoBase - BuildInfo = BuildInfoBase - - def new_ninfo(self): - ninfo = self.NodeInfo() - return ninfo - - def get_ninfo(self): - if self.ninfo is not None: - return self.ninfo - self.ninfo = self.new_ninfo() - return self.ninfo - - def new_binfo(self): - binfo = self.BuildInfo() - return binfo - - def get_binfo(self): - """ - Fetch a node's build information. - - node - the node whose sources will be collected - cache - alternate node to use for the signature cache - returns - the build signature - - This no longer handles the recursive descent of the - node's children's signatures. We expect that they're - already built and updated by someone else, if that's - what's wanted. - """ - try: - return self.binfo - except AttributeError: - pass - - binfo = self.new_binfo() - self.binfo = binfo - - executor = self.get_executor() - ignore_set = self.ignore_set - - if self.has_builder(): - binfo.bact = str(executor) - binfo.bactsig = MD5signature(executor.get_contents()) - - if self._specific_sources: - sources = [s for s in self.sources if s not in ignore_set] - - else: - sources = executor.get_unignored_sources(self, self.ignore) - - seen = set() - binfo.bsources = [s for s in sources if s not in seen and not seen.add(s)] - binfo.bsourcesigs = [s.get_ninfo() for s in binfo.bsources] - - binfo.bdepends = [d for d in self.depends if d not in ignore_set] - binfo.bdependsigs = [d.get_ninfo() for d in self.depends] - - # Because self.implicit is initialized to None (and not empty list []) - # we have to handle this case - if not self.implicit: - binfo.bimplicit = [] - binfo.bimplicitsigs = [] - else: - binfo.bimplicit = [i for i in self.implicit if i not in ignore_set] - binfo.bimplicitsigs = [i.get_ninfo() for i in binfo.bimplicit] - - return binfo - - def del_binfo(self): - """Delete the build info from this node.""" - try: - delattr(self, 'binfo') - except AttributeError: - pass - - def get_csig(self): - try: - return self.ninfo.csig - except AttributeError: - ninfo = self.get_ninfo() - ninfo.csig = MD5signature(self.get_contents()) - return self.ninfo.csig - - def get_cachedir_csig(self): - return self.get_csig() - - def get_stored_info(self): - return None - - def get_stored_implicit(self): - """Fetch the stored implicit dependencies""" - return None - - # - # - # - - def set_precious(self, precious = 1): - """Set the Node's precious value.""" - self.precious = precious - - def set_pseudo(self, pseudo = True): - """Set the Node's precious value.""" - self.pseudo = pseudo - - def set_noclean(self, noclean = 1): - """Set the Node's noclean value.""" - # Make sure noclean is an integer so the --debug=stree - # output in Util.py can use it as an index. - self.noclean = noclean and 1 or 0 - - def set_nocache(self, nocache = 1): - """Set the Node's nocache value.""" - # Make sure nocache is an integer so the --debug=stree - # output in Util.py can use it as an index. - self.nocache = nocache and 1 or 0 - - def set_always_build(self, always_build = 1): - """Set the Node's always_build value.""" - self.always_build = always_build - - def exists(self): - """Does this node exists?""" - return _exists_map[self._func_exists](self) - - def rexists(self): - """Does this node exist locally or in a repository?""" - # There are no repositories by default: - return _rexists_map[self._func_rexists](self) - - def get_contents(self): - """Fetch the contents of the entry.""" - return _get_contents_map[self._func_get_contents](self) - - def missing(self): - return not self.is_derived() and \ - not self.linked and \ - not self.rexists() - - def remove(self): - """Remove this Node: no-op by default.""" - return None - - def add_dependency(self, depend): - """Adds dependencies.""" - try: - self._add_child(self.depends, self.depends_set, depend) - except TypeError as e: - e = e.args[0] - if SCons.Util.is_List(e): - s = list(map(str, e)) - else: - s = str(e) - raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) - - def add_prerequisite(self, prerequisite): - """Adds prerequisites""" - if self.prerequisites is None: - self.prerequisites = SCons.Util.UniqueList() - self.prerequisites.extend(prerequisite) - self._children_reset() - - def add_ignore(self, depend): - """Adds dependencies to ignore.""" - try: - self._add_child(self.ignore, self.ignore_set, depend) - except TypeError as e: - e = e.args[0] - if SCons.Util.is_List(e): - s = list(map(str, e)) - else: - s = str(e) - raise SCons.Errors.UserError("attempted to ignore a non-Node dependency of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) - - def add_source(self, source): - """Adds sources.""" - if self._specific_sources: - return - try: - self._add_child(self.sources, self.sources_set, source) - except TypeError as e: - e = e.args[0] - if SCons.Util.is_List(e): - s = list(map(str, e)) - else: - 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, set, child): - """Adds 'child' to 'collection', first checking 'set' to see if it's - already present.""" - added = None - for c in child: - if c not in set: - set.add(c) - collection.append(c) - 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 is not None: - self.wkids.append(wkid) - - def _children_reset(self): - self.clear_memoized_values() - # We need to let the Executor clear out any calculated - # build info that it's cached so we can re-calculate it. - self.executor_cleanup() - - @SCons.Memoize.CountMethodCall - 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: - iter = chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f]) - - children = [] - for i in iter: - if i not in self.ignore_set: - children.append(i) - else: - children = self.all_children(scan=0) - - 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() - - # 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...) - return list(chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f])) - - def children(self, scan=1): - """Return a list of the node's direct children, minus those - that are ignored by this node.""" - if scan: - self.scan() - return self._children_get() - - def set_state(self, state): - self.state = state - - def get_state(self): - return self.state - - def get_env(self): - env = self.env - if not env: - import SCons.Defaults - env = SCons.Defaults.DefaultEnvironment() - return env - - def Decider(self, function): - foundkey = None - for k, v in _decider_map.items(): - if v == function: - foundkey = k - break - if not foundkey: - foundkey = len(_decider_map) - _decider_map[foundkey] = function - self.changed_since_last_build = foundkey - - def Tag(self, key, value): - """ Add a user-defined tag. """ - if not self._tags: - self._tags = {} - self._tags[key] = value - - def GetTag(self, key): - """ Return a user-defined tag. """ - if not self._tags: - return None - return self._tags.get(key, None) - - def changed(self, node=None, allowcache=False): - """ - Returns if the node is up-to-date with respect to the BuildInfo - stored last time it was built. The default behavior is to compare - it against our own previously stored BuildInfo, but the stored - BuildInfo from another Node (typically one in a Repository) - can be used instead. - - Note that we now *always* check every dependency. We used to - short-circuit the check by returning as soon as we detected - any difference, but we now rely on checking every dependency - to make sure that any necessary Node information (for example, - the content signature of an #included .h file) is updated. - - The allowcache option was added for supporting the early - release of the executor/builder structures, right after - a File target was built. When set to true, the return - value of this changed method gets cached for File nodes. - Like this, the executor isn't needed any longer for subsequent - calls to changed(). - - @see: FS.File.changed(), FS.File.release_target_info() - """ - t = 0 - if t: Trace('changed(%s [%s], %s)' % (self, classname(self), node)) - if node is None: - node = self - - result = False - - bi = node.get_stored_info().binfo - then = bi.bsourcesigs + bi.bdependsigs + bi.bimplicitsigs - children = self.children() - - diff = len(children) - len(then) - if diff: - # The old and new dependency lists are different lengths. - # This always indicates that the Node must be rebuilt. - # We also extend the old dependency list with enough None - # 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): - if _decider_map[child.changed_since_last_build](child, self, prev_ni, node): - if t: Trace(': %s changed' % child) - result = True - - if self.has_builder(): - contents = self.get_executor().get_contents() - newsig = MD5signature(contents) - if bi.bactsig != newsig: - if t: Trace(': bactsig %s != newsig %s' % (bi.bactsig, newsig)) - result = True - - if not result: - if t: Trace(': up to date') - - if t: Trace('\n') - - return result - - def is_up_to_date(self): - """Default check for whether the Node is current: unknown Node - subtypes are always out of date, so they will always get built.""" - return None - - def children_are_up_to_date(self): - """Alternate check for whether the Node is current: If all of - our children were up-to-date, then this Node was up-to-date, too. - - The SCons.Node.Alias and SCons.Node.Python.Value subclasses - rebind their current() method to this method.""" - # Allow the children to calculate their signatures. - self.binfo = self.get_binfo() - if self.always_build: - return None - state = 0 - for kid in self.children(None): - s = kid.get_state() - if s and (not state or s > state): - state = s - return (state == 0 or state == SCons.Node.up_to_date) - - def is_literal(self): - """Always pass the string representation of a Node to - the command interpreter literally.""" - return 1 - - def render_include_tree(self): - """ - Return a text representation, suitable for displaying to the - user, of the include tree for the sources of this node. - """ - if self.is_derived(): - env = self.get_build_env() - if env: - for s in self.sources: - scanner = self.get_source_scanner(s) - 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) - else: - return None - - def get_abspath(self): - """ - Return an absolute path to the Node. This will return simply - str(Node) by default, but for Node types that have a concept of - relative path, this might return something different. - """ - return str(self) - - def for_signature(self): - """ - Return a string representation of the Node that will always - be the same for this particular Node, no matter what. This - is by contrast to the __str__() method, which might, for - instance, return a relative path for a file Node. The purpose - of this method is to generate a value to be used in signature - calculation for the command line used to build a target, and - we use this method instead of str() to avoid unnecessary - rebuilds. This method does not need to return something that - would actually work in a command line; it can return any kind of - nonsense, so long as it does not change. - """ - return str(self) - - def get_string(self, for_signature): - """This is a convenience function designed primarily to be - used in command generators (i.e., CommandGeneratorActions or - Environment variables that are callable), which are called - with a for_signature argument that is nonzero if the command - generator is being called to generate a signature for the - command line, which determines if we should rebuild or not. - - Such command generators should use this method in preference - to str(Node) when converting a Node to a string, passing - in the for_signature parameter, such that we will call - Node.for_signature() or str(Node) properly, depending on whether - we are calculating a signature or actually constructing a - command line.""" - if for_signature: - return self.for_signature() - return str(self) - - def get_subst_proxy(self): - """ - This method is expected to return an object that will function - exactly like this Node, except that it implements any additional - special features that we would like to be in effect for - Environment variable substitution. The principle use is that - some Nodes would like to implement a __getattr__() method, - but putting that in the Node type itself has a tendency to kill - performance. We instead put it in a proxy and return it from - this method. It is legal for this method to return self - if no new functionality is needed for Environment substitution. - """ - return self - - def explain(self): - if not self.exists(): - return "building `%s' because it doesn't exist\n" % self - - if self.always_build: - return "rebuilding `%s' because AlwaysBuild() is specified\n" % self - - old = self.get_stored_info() - if old is None: - return None - - old = old.binfo - old.prepare_dependencies() - - try: - old_bkids = old.bsources + old.bdepends + old.bimplicit - old_bkidsigs = old.bsourcesigs + old.bdependsigs + old.bimplicitsigs - except AttributeError: - return "Cannot explain why `%s' is being rebuilt: No previous build information found\n" % self - - new = self.get_binfo() - - new_bkids = new.bsources + new.bdepends + new.bimplicit - new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs - - osig = dict(list(zip(old_bkids, old_bkidsigs))) - nsig = dict(list(zip(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 - # report them relative to the top-level SConstruct directory, - # so we only print them after running them through this lambda - # to turn them into the right relative Node and then return - # its string. - def stringify( s, E=self.dir.Entry): - if hasattr( s, 'dir' ) : - return str(E(s)) - return str(s) - - lines = [] - - removed = [x for x in old_bkids if x not in new_bkids] - if removed: - removed = [stringify(r) for r in removed] - fmt = "`%s' is no longer a dependency\n" - lines.extend([fmt % s for s in removed]) - - for k in new_bkids: - if k not in old_bkids: - lines.append("`%s' is a new dependency\n" % stringify(k)) - else: - changed = _decider_map[k.changed_since_last_build](k, self, osig[k]) - - if changed: - lines.append("`%s' changed\n" % stringify(k)) - - if len(lines) == 0 and old_bkids != new_bkids: - lines.append("the dependency order changed:\n") - lines.append("->Sources\n") - for (o,n) in zip_longest(old.bsources, new.bsources, fillvalue=None): - lines.append("Old:%s\tNew:%s\n"%(o,n)) - lines.append("->Depends\n") - for (o,n) in zip_longest(old.bdepends, new.bdepends, fillvalue=None): - lines.append("Old:%s\tNew:%s\n"%(o,n)) - lines.append("->Implicit\n") - for (o,n) in zip_longest(old.bimplicit, new.bimplicit, fillvalue=None): - lines.append("Old:%s\tNew:%s\n"%(o,n)) - - if len(lines) == 0: - def fmt_with_title(title, strlines): - lines = strlines.split('\n') - sep = '\n' + ' '*(15 + len(title)) - return ' '*15 + title + sep.join(lines) + '\n' - if old.bactsig != new.bactsig: - if old.bact == new.bact: - lines.append("the contents of the build action changed\n" + - fmt_with_title('action: ', new.bact)) - - # lines.append("the contents of the build action changed [%s] [%s]\n"%(old.bactsig,new.bactsig) + - # fmt_with_title('action: ', new.bact)) - else: - lines.append("the build action changed:\n" + - fmt_with_title('old: ', old.bact) + - fmt_with_title('new: ', new.bact)) - - if len(lines) == 0: - return "rebuilding `%s' for unknown reasons\n" % self - - preamble = "rebuilding `%s' because" % self - if len(lines) == 1: - return "%s %s" % (preamble, lines[0]) - else: - lines = ["%s:\n" % preamble] + lines - return ( ' '*11).join(lines) - -class NodeList(collections.UserList): - def __str__(self): - return str(list(map(str, self.data))) - -def get_children(node, parent): return node.children() -def ignore_cycle(node, stack): pass -def do_nothing(node, parent): pass - -class Walker: - """An iterator for walking a Node tree. - - This is depth-first, children are visited before the parent. - The Walker object can be initialized with any node, and - returns the next node on the descent with each get_next() call. - get the children of a node instead of calling 'children'. - 'cycle_func' is an optional function that will be called - when a cycle is detected. - - This class does not get caught in node cycles caused, for example, - by C header file include loops. - """ - def __init__(self, node, kids_func=get_children, - cycle_func=ignore_cycle, - eval_func=do_nothing): - self.kids_func = kids_func - self.cycle_func = cycle_func - self.eval_func = eval_func - node.wkids = copy.copy(kids_func(node, None)) - self.stack = [node] - self.history = {} # used to efficiently detect and avoid cycles - self.history[node] = None - - def get_next(self): - """Return the next node for this walk of the tree. - - This function is intentionally iterative, not recursive, - to sidestep any issues of stack size limitations. - """ - - while self.stack: - if self.stack[-1].wkids: - node = self.stack[-1].wkids.pop(0) - if not self.stack[-1].wkids: - self.stack[-1].wkids = None - if node in self.history: - self.cycle_func(node, self.stack) - else: - node.wkids = copy.copy(self.kids_func(node, self.stack[-1])) - self.stack.append(node) - self.history[node] = None - else: - node = self.stack.pop() - del self.history[node] - if node: - if self.stack: - parent = self.stack[-1] - else: - parent = None - self.eval_func(node, parent) - return node - return None - - def is_done(self): - return not self.stack - - -arg2nodes_lookups = [] - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/PathList.py b/scons/scons-local-4.1.0/SCons/PathList.py deleted file mode 100644 index a7e666dfa..000000000 --- a/scons/scons-local-4.1.0/SCons/PathList.py +++ /dev/null @@ -1,224 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Handle lists of directory paths. - -These are the path lists that get set as CPPPATH, LIBPATH, -etc.) with as much caching of data and efficiency as we can, while -still keeping the evaluation delayed so that we Do the Right Thing -(almost) regardless of how the variable is specified. -""" - -import os - -import SCons.Memoize -import SCons.Node -import SCons.Util - -# -# Variables to specify the different types of entries in a PathList object: -# - -TYPE_STRING_NO_SUBST = 0 # string with no '$' -TYPE_STRING_SUBST = 1 # string containing '$' -TYPE_OBJECT = 2 # other object - -def node_conv(obj): - """ - This is the "string conversion" routine that we have our substitutions - use to return Nodes, not strings. This relies on the fact that an - EntryProxy object has a get() method that returns the underlying - Node that it wraps, which is a bit of architectural dependence - that we might need to break or modify in the future in response to - additional requirements. - """ - try: - get = obj.get - except AttributeError: - if isinstance(obj, SCons.Node.Node) or SCons.Util.is_Sequence( obj ): - result = obj - else: - result = str(obj) - else: - result = get() - return result - -class _PathList: - """ - An actual PathList object. - """ - def __init__(self, pathlist): - """ - Initializes a PathList object, canonicalizing the input and - pre-processing it for quicker substitution later. - - The stored representation of the PathList is a list of tuples - containing (type, value), where the "type" is one of the TYPE_* - variables defined above. We distinguish between: - - strings that contain no '$' and therefore need no - delayed-evaluation string substitution (we expect that there - will be many of these and that we therefore get a pretty - big win from avoiding string substitution) - - strings that contain '$' and therefore need substitution - (the hard case is things like '${TARGET.dir}/include', - which require re-evaluation for every target + source) - - other objects (which may be something like an EntryProxy - that needs a method called to return a Node) - - Pre-identifying the type of each element in the PathList up-front - and storing the type in the list of tuples is intended to reduce - the amount of calculation when we actually do the substitution - over and over for each target. - """ - if SCons.Util.is_String(pathlist): - pathlist = pathlist.split(os.pathsep) - elif not SCons.Util.is_Sequence(pathlist): - pathlist = [pathlist] - - pl = [] - for p in pathlist: - try: - found = '$' in p - except (AttributeError, TypeError): - type = TYPE_OBJECT - else: - if not found: - type = TYPE_STRING_NO_SUBST - else: - type = TYPE_STRING_SUBST - pl.append((type, p)) - - self.pathlist = tuple(pl) - - def __len__(self): return len(self.pathlist) - - def __getitem__(self, i): return self.pathlist[i] - - def subst_path(self, env, target, source): - """ - Performs construction variable substitution on a pre-digested - PathList for a specific target and source. - """ - result = [] - for type, value in self.pathlist: - if type == TYPE_STRING_SUBST: - value = env.subst(value, target=target, source=source, - conv=node_conv) - if SCons.Util.is_Sequence(value): - result.extend(SCons.Util.flatten(value)) - elif value: - result.append(value) - elif type == TYPE_OBJECT: - value = node_conv(value) - if value: - result.append(value) - elif value: - result.append(value) - return tuple(result) - - -class PathListCache: - """ - A class to handle caching of PathList lookups. - - This class gets instantiated once and then deleted from the namespace, - so it's used as a Singleton (although we don't enforce that in the - usual Pythonic ways). We could have just made the cache a dictionary - in the module namespace, but putting it in this class allows us to - use the same Memoizer pattern that we use elsewhere to count cache - hits and misses, which is very valuable. - - Lookup keys in the cache are computed by the _PathList_key() method. - Cache lookup should be quick, so we don't spend cycles canonicalizing - all forms of the same lookup key. For example, 'x:y' and ['x', - 'y'] logically represent the same list, but we don't bother to - split string representations and treat those two equivalently. - (Note, however, that we do, treat lists and tuples the same.) - - The main type of duplication we're trying to catch will come from - looking up the same path list from two different clones of the - same construction environment. That is, given - - env2 = env1.Clone() - - both env1 and env2 will have the same CPPPATH value, and we can - cheaply avoid re-parsing both values of CPPPATH by using the - common value from this cache. - """ - def __init__(self): - self._memo = {} - - def _PathList_key(self, pathlist): - """ - Returns the key for memoization of PathLists. - - Note that we want this to be pretty quick, so we don't completely - canonicalize all forms of the same list. For example, - 'dir1:$ROOT/dir2' and ['$ROOT/dir1', 'dir'] may logically - represent the same list if you're executing from $ROOT, but - we're not going to bother splitting strings into path elements, - or massaging strings into Nodes, to identify that equivalence. - We just want to eliminate obvious redundancy from the normal - case of re-using exactly the same cloned value for a path. - """ - if SCons.Util.is_Sequence(pathlist): - pathlist = tuple(SCons.Util.flatten(pathlist)) - return pathlist - - @SCons.Memoize.CountDictCall(_PathList_key) - def PathList(self, pathlist): - """ - Returns the cached _PathList object for the specified pathlist, - creating and caching a new object as necessary. - """ - pathlist = self._PathList_key(pathlist) - try: - memo_dict = self._memo['PathList'] - except KeyError: - memo_dict = {} - self._memo['PathList'] = memo_dict - else: - try: - return memo_dict[pathlist] - except KeyError: - pass - - result = _PathList(pathlist) - - memo_dict[pathlist] = result - - return result - -PathList = PathListCache().PathList - - -del PathListCache - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/__init__.py b/scons/scons-local-4.1.0/SCons/Platform/__init__.py deleted file mode 100644 index 745db095d..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/__init__.py +++ /dev/null @@ -1,314 +0,0 @@ -# MIT License -# -# Copyright 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 platform selection. - -Looks for modules that define a callable object that can modify a -construction environment as appropriate for a given platform. - -Note that we take a more simplistic view of "platform" than Python does. -We're looking for a single string that determines a set of -tool-independent variables with which to initialize a construction -environment. Consequently, we'll examine both sys.platform and os.name -(and anything else that might come in to play) in order to return some -specification which is unique enough for our purposes. - -Note that because this subsystem just *selects* a callable that can -modify a construction environment, it's possible for people to define -their own "platform specification" in an arbitrary callable function. -No one needs to use or tie in to this subsystem in order to roll -their own platform definition. -""" - -import SCons.compat - -import importlib -import os -import sys -import tempfile - -import SCons.Errors -import SCons.Subst -import SCons.Tool - - -def platform_default(): - """Return the platform string for our execution environment. - - The returned value should map to one of the SCons/Platform/\*.py - files. Since scons is architecture independent, though, we don't - care about the machine architecture. - """ - osname = os.name - if osname == 'java': - osname = os._osType - if osname == 'posix': - if sys.platform == 'cygwin': - return 'cygwin' - elif sys.platform.find('irix') != -1: - return 'irix' - elif sys.platform.find('sunos') != -1: - return 'sunos' - elif sys.platform.find('hp-ux') != -1: - return 'hpux' - elif sys.platform.find('aix') != -1: - return 'aix' - elif sys.platform.find('darwin') != -1: - return 'darwin' - else: - return 'posix' - elif os.name == 'os2': - return 'os2' - else: - return sys.platform - - -def platform_module(name = platform_default()): - """Return the imported module for the platform. - - This looks for a module name that matches the specified argument. - If the name is unspecified, we fetch the appropriate default for - our execution environment. - """ - full_name = 'SCons.Platform.' + name - if full_name not in sys.modules: - if os.name == 'java': - eval(full_name) - else: - try: - # the specific platform module is a relative import - mod = importlib.import_module("." + name, __name__) - except ImportError: - try: - import zipimport - importer = zipimport.zipimporter( sys.modules['SCons.Platform'].__path__[0] ) - mod = importer.load_module(full_name) - except ImportError: - raise SCons.Errors.UserError("No platform named '%s'" % name) - setattr(SCons.Platform, name, mod) - return sys.modules[full_name] - - -def DefaultToolList(platform, env): - """Select a default tool list for the specified platform. - """ - return SCons.Tool.tool_list(platform, env) - - -class PlatformSpec: - def __init__(self, name, generate): - self.name = name - self.generate = generate - - def __call__(self, *args, **kw): - return self.generate(*args, **kw) - - def __str__(self): - return self.name - - -class TempFileMunge: - """Convert long command lines to use a temporary file. - - You can set an Environment variable (usually `TEMPFILE`) to this, - then call it with a string argument, and it will perform temporary - file substitution on it. This is used to circumvent limitations on - the length of command lines. Example:: - - env["TEMPFILE"] = TempFileMunge - env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES','$LINKCOMSTR')}" - - By default, the name of the temporary file used begins with a - prefix of '@'. This may be configured for other tool chains by - setting the TEMPFILEPREFIX variable. Example:: - - env["TEMPFILEPREFIX"] = '-@' # diab compiler - env["TEMPFILEPREFIX"] = '-via' # arm tool chain - env["TEMPFILEPREFIX"] = '' # (the empty string) PC Lint - - You can configure the extension of the temporary file through the - TEMPFILESUFFIX variable, which defaults to '.lnk' (see comments - in the code below). Example:: - - env["TEMPFILESUFFIX"] = '.lnt' # PC Lint - - Entries in the temporary file are separated by the value of the - TEMPFILEARGJOIN variable, which defaults to an OS-appropriate value. - - """ - def __init__(self, cmd, cmdstr = None): - self.cmd = cmd - self.cmdstr = cmdstr - - def __call__(self, target, source, env, for_signature): - if for_signature: - # If we're being called for signature calculation, it's - # because we're being called by the string expansion in - # Subst.py, which has the logic to strip any $( $) that - # may be in the command line we squirreled away. So we - # just return the raw command line and let the upper - # string substitution layers do their thing. - return self.cmd - - # Now we're actually being called because someone is actually - # going to try to execute the command, so we have to do our - # own expansion. - cmd = env.subst_list(self.cmd, SCons.Subst.SUBST_CMD, target, source)[0] - try: - maxline = int(env.subst('$MAXLINELENGTH')) - except ValueError: - maxline = 2048 - - length = 0 - for c in cmd: - length += len(c) - length += len(cmd) - 1 - if length <= maxline: - return self.cmd - - # Check if we already created the temporary file for this target - # It should have been previously done by Action.strfunction() call - if SCons.Util.is_List(target): - node = target[0] - else: - node = target - - cmdlist = None - - if SCons.Util.is_List(self.cmd): - cmdlist_key = tuple(self.cmd) - else: - cmdlist_key = self.cmd - - if node and hasattr(node.attributes, 'tempfile_cmdlist'): - cmdlist = node.attributes.tempfile_cmdlist.get(cmdlist_key, None) - if cmdlist is not None: - return cmdlist - - # Default to the .lnk suffix for the benefit of the Phar Lap - # linkloc linker, which likes to append an .lnk suffix if - # none is given. - if 'TEMPFILESUFFIX' in env: - suffix = env.subst('$TEMPFILESUFFIX') - else: - suffix = '.lnk' - - if 'TEMPFILEDIR' in env: - tempfile_dir = env.subst('$TEMPFILEDIR') - os.makedirs(tempfile_dir, exist_ok=True) - else: - tempfile_dir = None - - fd, tmp = tempfile.mkstemp(suffix, dir=tempfile_dir, text=True) - native_tmp = SCons.Util.get_native_path(tmp) - - if env.get('SHELL', None) == 'sh': - # The sh shell will try to escape the backslashes in the - # path, so unescape them. - native_tmp = native_tmp.replace('\\', r'\\\\') - # In Cygwin, we want to use rm to delete the temporary - # file, because del does not exist in the sh shell. - rm = env.Detect('rm') or 'del' - else: - # Don't use 'rm' if the shell is not sh, because rm won't - # work with the Windows shells (cmd.exe or command.com) or - # Windows path names. - rm = 'del' - - prefix = env.subst('$TEMPFILEPREFIX') - if not prefix: - prefix = '@' - - args = list(map(SCons.Subst.quote_spaces, cmd[1:])) - join_char = env.get('TEMPFILEARGJOIN',' ') - os.write(fd, bytearray(join_char.join(args) + "\n",'utf-8')) - os.close(fd) - - # XXX Using the SCons.Action.print_actions value directly - # like this is bogus, but expedient. This class should - # really be rewritten as an Action that defines the - # __call__() and strfunction() methods and lets the - # normal action-execution logic handle whether or not to - # print/execute the action. The problem, though, is all - # of that is decided before we execute this method as - # part of expanding the $TEMPFILE construction variable. - # Consequently, refactoring this will have to wait until - # we get more flexible with allowing Actions to exist - # independently and get strung together arbitrarily like - # Ant tasks. In the meantime, it's going to be more - # user-friendly to not let obsession with architectural - # purity get in the way of just being helpful, so we'll - # reach into SCons.Action directly. - if SCons.Action.print_actions: - cmdstr = env.subst(self.cmdstr, SCons.Subst.SUBST_RAW, target, - source) if self.cmdstr is not None else '' - # Print our message only if XXXCOMSTR returns an empty string - if len(cmdstr) == 0 : - cmdstr = ("Using tempfile "+native_tmp+" for command line:\n"+ - str(cmd[0]) + " " + " ".join(args)) - self._print_cmd_str(target, source, env, cmdstr) - - cmdlist = [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ] - - # Store the temporary file command list into the target Node.attributes - # to avoid creating two temporary files one for print and one for execute. - if node is not None: - try: - # Storing in tempfile_cmdlist by self.cmd provided when intializing - # $TEMPFILE{} fixes issue raised in PR #3140 and #3553 - node.attributes.tempfile_cmdlist[cmdlist_key] = cmdlist - except AttributeError: - node.attributes.tempfile_cmdlist = {cmdlist_key:cmdlist} - - return cmdlist - - def _print_cmd_str(self, target, source, env, cmdstr): - # check if the user has specified a cmd line print function - print_func = None - try: - get = env.get - except AttributeError: - pass - else: - print_func = get('PRINT_CMD_LINE_FUNC') - - # use the default action cmd line print if user did not supply one - if not print_func: - action = SCons.Action._ActionAction() - action.print_cmd_line(cmdstr, target, source, env) - else: - print_func(cmdstr, target, source, env) - - -def Platform(name = platform_default()): - """Select a canned Platform specification. - """ - module = platform_module(name) - spec = PlatformSpec(name, module.generate) - return spec - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/aix.py b/scons/scons-local-4.1.0/SCons/Platform/aix.py deleted file mode 100644 index db1ccdb3f..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/aix.py +++ /dev/null @@ -1,80 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for IBM AIX systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -import subprocess - -from . import posix - -import SCons.Util -import SCons.Action - -def get_xlc(env, xlc=None, packages=[]): - # Use the AIX package installer tool lslpp to figure out where a - # given xl* compiler is installed and what version it is. - xlcPath = None - xlcVersion = None - - if xlc is None: - xlc = env.get('CC', 'xlc') - if SCons.Util.is_List(xlc): - xlc = xlc[0] - for package in packages: - # find the installed filename, which may be a symlink as well - pipe = SCons.Action._subproc(env, ['lslpp', '-fc', package], - stdin = 'devnull', - stderr = 'devnull', - universal_newlines=True, - stdout = subprocess.PIPE) - # output of lslpp is something like this: - # #Path:Fileset:File - # /usr/lib/objrepos:vac.C 6.0.0.0:/usr/vac/exe/xlCcpp - # /usr/lib/objrepos:vac.C 6.0.0.0:/usr/vac/bin/xlc_r -> /usr/vac/bin/xlc - for line in pipe.stdout: - if xlcPath: - continue # read everything to let lslpp terminate - fileset, filename = line.split(':')[1:3] - filename = filename.split()[0] - if ('/' in xlc and filename == xlc) \ - or ('/' not in xlc and filename.endswith('/' + xlc)): - xlcVersion = fileset.split()[1] - xlcPath, sep, xlc = filename.rpartition('/') - return (xlcPath, xlc, xlcVersion) - -def generate(env): - posix.generate(env) - #Based on AIX 5.2: ARG_MAX=24576 - 3000 for environment expansion - env['MAXLINELENGTH'] = 21576 - env['SHLIBSUFFIX'] = '.a' - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/cygwin.py b/scons/scons-local-4.1.0/SCons/Platform/cygwin.py deleted file mode 100644 index ce010075a..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/cygwin.py +++ /dev/null @@ -1,60 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for Cygwin systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -import sys - -from . import posix -from SCons.Platform import TempFileMunge - -CYGWIN_DEFAULT_PATHS = [] -if sys.platform == 'win32': - CYGWIN_DEFAULT_PATHS = [ - r'C:\cygwin64\bin', - r'C:\cygwin\bin' - ] - -def generate(env): - posix.generate(env) - - env['PROGPREFIX'] = '' - env['PROGSUFFIX'] = '.exe' - env['SHLIBPREFIX'] = '' - env['SHLIBSUFFIX'] = '.dll' - env['LIBPREFIXES'] = [ '$LIBPREFIX', '$SHLIBPREFIX', '$IMPLIBPREFIX' ] - env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX', '$IMPLIBSUFFIX' ] - env['TEMPFILE'] = TempFileMunge - env['TEMPFILEPREFIX'] = '@' - env['MAXLINELENGTH'] = 2048 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/darwin.py b/scons/scons-local-4.1.0/SCons/Platform/darwin.py deleted file mode 100644 index 68cb7df89..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/darwin.py +++ /dev/null @@ -1,69 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for Mac OS X systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -from . import posix -import os - -def generate(env): - posix.generate(env) - env['SHLIBSUFFIX'] = '.dylib' - # put macports paths at front to override Apple's versions, fink path is after - # For now let people who want Macports or Fink tools specify it! - # env['ENV']['PATH'] = '/opt/local/bin:/opt/local/sbin:' + env['ENV']['PATH'] + ':/sw/bin' - - # Store extra system paths in env['ENV']['PATHOSX'] - - filelist = ['/etc/paths',] - # make sure this works on Macs with Tiger or earlier - try: - dirlist = os.listdir('/etc/paths.d') - except: - dirlist = [] - - for file in dirlist: - filelist.append('/etc/paths.d/'+file) - - for file in filelist: - if os.path.isfile(file): - with open(file, 'r') as f: - lines = f.readlines() - for line in lines: - if line: - env.AppendENVPath('PATHOSX', line.strip('\n')) - - # Not sure why this wasn't the case all along? - if env['ENV'].get('PATHOSX', False) and os.environ.get('SCONS_USE_MAC_PATHS', False): - env.AppendENVPath('PATH',env['ENV']['PATHOSX']) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/hpux.py b/scons/scons-local-4.1.0/SCons/Platform/hpux.py deleted file mode 100644 index 53c7b6736..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/hpux.py +++ /dev/null @@ -1,44 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for HP-UX systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -from . import posix - -def generate(env): - posix.generate(env) - #Based on HP-UX11i: ARG_MAX=2048000 - 3000 for environment expansion - env['MAXLINELENGTH'] = 2045000 - - env['SHLIBSUFFIX'] = '.sl' - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/irix.py b/scons/scons-local-4.1.0/SCons/Platform/irix.py deleted file mode 100644 index 70f37087a..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/irix.py +++ /dev/null @@ -1,40 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for SGI IRIX systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -from . import posix - -def generate(env): - posix.generate(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/mingw.py b/scons/scons-local-4.1.0/SCons/Platform/mingw.py deleted file mode 100644 index 1d38a9bdb..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/mingw.py +++ /dev/null @@ -1,33 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for the MinGW system.""" - -import sys - -MINGW_DEFAULT_PATHS = [] -if sys.platform == 'win32': - MINGW_DEFAULT_PATHS = [ - r'C:\msys64', - r'C:\msys' - ] diff --git a/scons/scons-local-4.1.0/SCons/Platform/os2.py b/scons/scons-local-4.1.0/SCons/Platform/os2.py deleted file mode 100644 index 6b412eed2..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/os2.py +++ /dev/null @@ -1,55 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for OS/2 systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -from . import win32 - -def generate(env): - if 'ENV' not in env: - env['ENV'] = {} - env['OBJPREFIX'] = '' - env['OBJSUFFIX'] = '.obj' - env['SHOBJPREFIX'] = '$OBJPREFIX' - env['SHOBJSUFFIX'] = '$OBJSUFFIX' - env['PROGPREFIX'] = '' - env['PROGSUFFIX'] = '.exe' - env['LIBPREFIX'] = '' - env['LIBSUFFIX'] = '.lib' - env['SHLIBPREFIX'] = '' - env['SHLIBSUFFIX'] = '.dll' - env['LIBPREFIXES'] = '$LIBPREFIX' - env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ] - env['HOST_OS'] = 'os2' - env['HOST_ARCH'] = win32.get_architecture().arch - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/posix.py b/scons/scons-local-4.1.0/SCons/Platform/posix.py deleted file mode 100644 index 4c9f8f9ba..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/posix.py +++ /dev/null @@ -1,124 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for POSIX (Linux, UNIX, etc.) systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -import errno -import subprocess -import select - -import SCons.Util -from SCons.Platform import TempFileMunge -from SCons.Platform.virtualenv import ImportVirtualenv -from SCons.Platform.virtualenv import ignore_virtualenv, enable_virtualenv - -exitvalmap = { - 2 : 127, - 13 : 126, -} - -def escape(arg): - """escape shell special characters""" - slash = '\\' - special = '"$' - - arg = arg.replace(slash, slash+slash) - for c in special: - arg = arg.replace(c, slash+c) - - # print("ESCAPE RESULT: %s" % arg) - return '"' + arg + '"' - - -def exec_subprocess(l, env): - proc = subprocess.Popen(l, env = env, close_fds = True) - return proc.wait() - -def subprocess_spawn(sh, escape, cmd, args, env): - return exec_subprocess([sh, '-c', ' '.join(args)], env) - -def exec_popen3(l, env, stdout, stderr): - proc = subprocess.Popen(l, env = env, close_fds = True, - stdout = stdout, - stderr = stderr) - return proc.wait() - -def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr): - # spawn using Popen3 combined with the env command - # the command name and the command's stdout is written to stdout - # the command's stderr is written to stderr - return exec_popen3([sh, '-c', ' '.join(args)], - env, stdout, stderr) - - -def generate(env): - # Bearing in mind we have python 2.4 as a baseline, we can just do this: - spawn = subprocess_spawn - pspawn = piped_env_spawn - # Note that this means that 'escape' is no longer used - - if 'ENV' not in env: - env['ENV'] = {} - env['ENV']['PATH'] = '/usr/local/bin:/opt/bin:/bin:/usr/bin:/snap/bin' - env['OBJPREFIX'] = '' - env['OBJSUFFIX'] = '.o' - env['SHOBJPREFIX'] = '$OBJPREFIX' - env['SHOBJSUFFIX'] = '$OBJSUFFIX' - env['PROGPREFIX'] = '' - env['PROGSUFFIX'] = '' - env['LIBPREFIX'] = 'lib' - env['LIBSUFFIX'] = '.a' - env['SHLIBPREFIX'] = '$LIBPREFIX' - env['SHLIBSUFFIX'] = '.so' - env['LIBPREFIXES'] = [ '$LIBPREFIX' ] - env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ] - env['PSPAWN'] = pspawn - env['SPAWN'] = spawn - env['SHELL'] = 'sh' - env['ESCAPE'] = escape - env['TEMPFILE'] = TempFileMunge - env['TEMPFILEPREFIX'] = '@' - #Based on LINUX: ARG_MAX=ARG_MAX=131072 - 3000 for environment expansion - #Note: specific platforms might rise or lower this value - env['MAXLINELENGTH'] = 128072 - - # This platform supports RPATH specifications. - env['__RPATH'] = '$_RPATH' - - # GDC is GCC family, but DMD and LDC have different options. - # Must be able to have GCC and DMD work in the same build, so: - env['__DRPATH'] = '$_DRPATH' - - if enable_virtualenv and not ignore_virtualenv: - ImportVirtualenv(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/sunos.py b/scons/scons-local-4.1.0/SCons/Platform/sunos.py deleted file mode 100644 index d33af1e43..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/sunos.py +++ /dev/null @@ -1,46 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for Sun systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -from . import posix - -def generate(env): - posix.generate(env) - # Based on sunSparc 8:32bit - # ARG_MAX=1048320 - 3000 for environment expansion - env['MAXLINELENGTH'] = 1045320 - env['PKGINFO'] = 'pkginfo' - env['PKGCHK'] = '/usr/sbin/pkgchk' - env['ENV']['PATH'] = env['ENV']['PATH'] + ':/opt/SUNWspro/bin:/usr/ccs/bin' - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/virtualenv.py b/scons/scons-local-4.1.0/SCons/Platform/virtualenv.py deleted file mode 100644 index 2204a595b..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/virtualenv.py +++ /dev/null @@ -1,115 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""'Platform" support for a Python virtualenv.""" - -import os -import sys -import SCons.Util - - -virtualenv_enabled_by_default = False - - -def _enable_virtualenv_default(): - return SCons.Util.get_os_env_bool('SCONS_ENABLE_VIRTUALENV', virtualenv_enabled_by_default) - - -def _ignore_virtualenv_default(): - return SCons.Util.get_os_env_bool('SCONS_IGNORE_VIRTUALENV', False) - - -enable_virtualenv = _enable_virtualenv_default() -ignore_virtualenv = _ignore_virtualenv_default() -virtualenv_variables = ['VIRTUAL_ENV', 'PIPENV_ACTIVE'] - - -def _running_in_virtualenv(): - """Returns True if scons is executed within a virtualenv""" - # see https://stackoverflow.com/a/42580137 - return (hasattr(sys, 'real_prefix') or - (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)) - - -def _is_path_in(path, base): - """Returns true if **path** is located under the **base** directory.""" - if not path or not base: # empty path may happen, base too - return False - rp = os.path.relpath(path, base) - return (not rp.startswith(os.path.pardir)) and (not rp == os.path.curdir) - - -def _inject_venv_variables(env): - if 'ENV' not in env: - env['ENV'] = {} - ENV = env['ENV'] - for name in virtualenv_variables: - try: - ENV[name] = os.environ[name] - except KeyError: - pass - -def _inject_venv_path(env, path_list=None): - """Modify environment such that SCons will take into account its virtualenv - when running external tools.""" - if path_list is None: - path_list = os.getenv('PATH') - env.PrependENVPath('PATH', select_paths_in_venv(path_list)) - - -def select_paths_in_venv(path_list): - """Returns a list of paths from **path_list** which are under virtualenv's - home directory.""" - if SCons.Util.is_String(path_list): - path_list = path_list.split(os.path.pathsep) - # Find in path_list the paths under the virtualenv's home - return [path for path in path_list if IsInVirtualenv(path)] - - -def ImportVirtualenv(env): - """Copies virtualenv-related environment variables from OS environment - to ``env['ENV']`` and prepends virtualenv's PATH to ``env['ENV']['PATH']``. - """ - _inject_venv_variables(env) - _inject_venv_path(env) - - -def Virtualenv(): - """Returns path to the virtualenv home if scons is executing within a - virtualenv or None, if not.""" - if _running_in_virtualenv(): - return sys.prefix - return None - - -def IsInVirtualenv(path): - """Returns True, if **path** is under virtualenv's home directory. If not, - or if we don't use virtualenv, returns False.""" - return _is_path_in(path, Virtualenv()) - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Platform/win32.py b/scons/scons-local-4.1.0/SCons/Platform/win32.py deleted file mode 100644 index aa76387cb..000000000 --- a/scons/scons-local-4.1.0/SCons/Platform/win32.py +++ /dev/null @@ -1,428 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Platform-specific initialization for Win32 systems. - -There normally shouldn't be any need to import this module directly. It -will usually be imported through the generic SCons.Platform.Platform() -selection method. -""" - -import os -import os.path -import sys -import tempfile - -from SCons.Platform.posix import exitvalmap -from SCons.Platform import TempFileMunge -from SCons.Platform.virtualenv import ImportVirtualenv -from SCons.Platform.virtualenv import ignore_virtualenv, enable_virtualenv -import SCons.Util - -CHOCO_DEFAULT_PATH = [ - r'C:\ProgramData\chocolatey\bin' -] - -if False: - # Now swap out shutil.filecopy and filecopy2 for win32 api native CopyFile - try: - from ctypes import windll - import shutil - - CopyFile = windll.kernel32.CopyFileA - SetFileTime = windll.kernel32.SetFileTime - - _shutil_copy = shutil.copy - _shutil_copy2 = shutil.copy2 - - shutil.copy2 = CopyFile - - def win_api_copyfile(src,dst): - CopyFile(src,dst) - os.utime(dst) - - shutil.copy = win_api_copyfile - - except AttributeError: - parallel_msg = \ - "Couldn't override shutil.copy or shutil.copy2 falling back to shutil defaults" - - - - - - - -try: - import threading - spawn_lock = threading.Lock() - - # This locked version of spawnve works around a Windows - # MSVCRT bug, because its spawnve is not thread-safe. - # Without this, python can randomly crash while using -jN. - # See the python bug at http://bugs.python.org/issue6476 - # and SCons issue at - # https://github.com/SCons/scons/issues/2449 - def spawnve(mode, file, args, env): - spawn_lock.acquire() - try: - if mode == os.P_WAIT: - ret = os.spawnve(os.P_NOWAIT, file, args, env) - else: - ret = os.spawnve(mode, file, args, env) - finally: - spawn_lock.release() - if mode == os.P_WAIT: - pid, status = os.waitpid(ret, 0) - ret = status >> 8 - return ret -except ImportError: - # Use the unsafe method of spawnve. - # Please, don't try to optimize this try-except block - # away by assuming that the threading module is always present. - # In the test test/option-j.py we intentionally call SCons with - # a fake threading.py that raises an import exception right away, - # simulating a non-existent package. - def spawnve(mode, file, args, env): - return os.spawnve(mode, file, args, env) - -# The upshot of all this is that, if you are using Python 1.5.2, -# you had better have cmd or command.com in your PATH when you run -# scons. - - -def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): - # There is no direct way to do that in python. What we do - # here should work for most cases: - # In case stdout (stderr) is not redirected to a file, - # we redirect it into a temporary file tmpFileStdout - # (tmpFileStderr) and copy the contents of this file - # to stdout (stderr) given in the argument - # Note that because this will paste shell redirection syntax - # into the cmdline, we have to call a shell to run the command, - # even though that's a bit of a performance hit. - if not sh: - sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n") - return 127 - - # one temporary file for stdout and stderr - tmpFileStdout, tmpFileStdoutName = tempfile.mkstemp(text=True) - os.close(tmpFileStdout) # don't need open until the subproc is done - tmpFileStderr, tmpFileStderrName = tempfile.mkstemp(text=True) - os.close(tmpFileStderr) - - # check if output is redirected - stdoutRedirected = False - stderrRedirected = False - for arg in args: - # are there more possibilities to redirect stdout ? - if arg.find(">", 0, 1) != -1 or arg.find("1>", 0, 2) != -1: - stdoutRedirected = True - # are there more possibilities to redirect stderr ? - if arg.find("2>", 0, 2) != -1: - stderrRedirected = True - - # redirect output of non-redirected streams to our tempfiles - if not stdoutRedirected: - args.append(">" + tmpFileStdoutName) - if not stderrRedirected: - args.append("2>" + tmpFileStderrName) - - # actually do the spawn - try: - args = [sh, '/C', escape(' '.join(args))] - ret = spawnve(os.P_WAIT, sh, args, env) - except OSError as e: - # catch any error - try: - ret = exitvalmap[e.errno] - except KeyError: - sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e.errno, cmd, e.strerror)) - if stderr is not None: - stderr.write("scons: %s: %s\n" % (cmd, e.strerror)) - - # copy child output from tempfiles to our streams - # and do clean up stuff - if stdout is not None and not stdoutRedirected: - try: - with open(tmpFileStdoutName, "r") as tmpFileStdout: - stdout.write(tmpFileStdout.read()) - os.remove(tmpFileStdoutName) - except (IOError, OSError): - pass - - if stderr is not None and not stderrRedirected: - try: - with open(tmpFileStderrName, "r") as tmpFileStderr: - stderr.write(tmpFileStderr.read()) - os.remove(tmpFileStderrName) - except (IOError, OSError): - pass - - return ret - - -def exec_spawn(l, env): - try: - result = spawnve(os.P_WAIT, l[0], l, env) - except (OSError, EnvironmentError) as e: - try: - result = exitvalmap[e.errno] - sys.stderr.write("scons: %s: %s\n" % (l[0], e.strerror)) - except KeyError: - result = 127 - if len(l) > 2: - if len(l[2]) < 1000: - command = ' '.join(l[0:3]) - else: - command = l[0] - else: - command = l[0] - sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e.errno, command, e.strerror)) - return result - - -def spawn(sh, escape, cmd, args, env): - if not sh: - sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n") - return 127 - return exec_spawn([sh, '/C', escape(' '.join(args))], env) - -# Windows does not allow special characters in file names anyway, so no -# need for a complex escape function, we will just quote the arg, except -# that "cmd /c" requires that if an argument ends with a backslash it -# needs to be escaped so as not to interfere with closing double quote -# that we add. -def escape(x): - if x[-1] == '\\': - x = x + '\\' - return '"' + x + '"' - -# Get the windows system directory name -_system_root = None - - -def get_system_root(): - global _system_root - if _system_root is not None: - return _system_root - - # A resonable default if we can't read the registry - val = os.environ.get('SystemRoot', "C:\\WINDOWS") - - if SCons.Util.can_read_reg: - try: - # Look for Windows NT system root - k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE, - 'Software\\Microsoft\\Windows NT\\CurrentVersion') - val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot') - except SCons.Util.RegError: - try: - # Okay, try the Windows 9x system root - k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE, - 'Software\\Microsoft\\Windows\\CurrentVersion') - val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot') - except KeyboardInterrupt: - raise - except: - pass - - _system_root = val - return val - - -def get_program_files_dir(): - """ - Get the location of the program files directory - Returns - ------- - - """ - # Now see if we can look in the registry... - val = '' - if SCons.Util.can_read_reg: - try: - # Look for Windows Program Files directory - k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE, - 'Software\\Microsoft\\Windows\\CurrentVersion') - val, tok = SCons.Util.RegQueryValueEx(k, 'ProgramFilesDir') - except SCons.Util.RegError: - val = '' - - if val == '': - # A reasonable default if we can't read the registry - # (Actually, it's pretty reasonable even if we can :-) - val = os.path.join(os.path.dirname(get_system_root()),"Program Files") - - return val - - -class ArchDefinition: - """ - Determine which windows CPU were running on. - A class for defining architecture-specific settings and logic. - """ - def __init__(self, arch, synonyms=[]): - self.arch = arch - self.synonyms = synonyms - -SupportedArchitectureList = [ - ArchDefinition( - 'x86', - ['i386', 'i486', 'i586', 'i686'], - ), - - ArchDefinition( - 'x86_64', - ['AMD64', 'amd64', 'em64t', 'EM64T', 'x86_64'], - ), - - ArchDefinition( - 'ia64', - ['IA64'], - ), -] - -SupportedArchitectureMap = {} -for a in SupportedArchitectureList: - SupportedArchitectureMap[a.arch] = a - for s in a.synonyms: - SupportedArchitectureMap[s] = a - - -def get_architecture(arch=None): - """Returns the definition for the specified architecture string. - - If no string is specified, the system default is returned (as defined - by the PROCESSOR_ARCHITEW6432 or PROCESSOR_ARCHITECTURE environment - variables). - """ - if arch is None: - arch = os.environ.get('PROCESSOR_ARCHITEW6432') - if not arch: - arch = os.environ.get('PROCESSOR_ARCHITECTURE') - return SupportedArchitectureMap.get(arch, ArchDefinition('', [''])) - - -def generate(env): - # Attempt to find cmd.exe (for WinNT/2k/XP) or - # command.com for Win9x - cmd_interp = '' - # First see if we can look in the registry... - if SCons.Util.can_read_reg: - try: - # Look for Windows NT system root - k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE, - 'Software\\Microsoft\\Windows NT\\CurrentVersion') - val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot') - cmd_interp = os.path.join(val, 'System32\\cmd.exe') - except SCons.Util.RegError: - try: - # Okay, try the Windows 9x system root - k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE, - 'Software\\Microsoft\\Windows\\CurrentVersion') - val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot') - cmd_interp = os.path.join(val, 'command.com') - except KeyboardInterrupt: - raise - except: - pass - - # For the special case of not having access to the registry, we - # use a temporary path and pathext to attempt to find the command - # interpreter. If we fail, we try to find the interpreter through - # the env's PATH. The problem with that is that it might not - # contain an ENV and a PATH. - if not cmd_interp: - systemroot = get_system_root() - tmp_path = systemroot + os.pathsep + \ - os.path.join(systemroot,'System32') - tmp_pathext = '.com;.exe;.bat;.cmd' - if 'PATHEXT' in os.environ: - tmp_pathext = os.environ['PATHEXT'] - cmd_interp = SCons.Util.WhereIs('cmd', tmp_path, tmp_pathext) - if not cmd_interp: - cmd_interp = SCons.Util.WhereIs('command', tmp_path, tmp_pathext) - - if not cmd_interp: - cmd_interp = env.Detect('cmd') - if not cmd_interp: - cmd_interp = env.Detect('command') - - if 'ENV' not in env: - env['ENV'] = {} - - # Import things from the external environment to the construction - # environment's ENV. This is a potential slippery slope, because we - # *don't* want to make builds dependent on the user's environment by - # default. We're doing this for SystemRoot, though, because it's - # needed for anything that uses sockets, and seldom changes, and - # for SystemDrive because it's related. - # - # Weigh the impact carefully before adding other variables to this list. - import_env = ['SystemDrive', 'SystemRoot', 'TEMP', 'TMP' ] - for var in import_env: - v = os.environ.get(var) - if v: - env['ENV'][var] = v - - if 'COMSPEC' not in env['ENV']: - v = os.environ.get("COMSPEC") - if v: - env['ENV']['COMSPEC'] = v - - env.AppendENVPath('PATH', get_system_root() + '\\System32') - - env['ENV']['PATHEXT'] = '.COM;.EXE;.BAT;.CMD' - env['OBJPREFIX'] = '' - env['OBJSUFFIX'] = '.obj' - env['SHOBJPREFIX'] = '$OBJPREFIX' - env['SHOBJSUFFIX'] = '$OBJSUFFIX' - env['PROGPREFIX'] = '' - env['PROGSUFFIX'] = '.exe' - env['LIBPREFIX'] = '' - env['LIBSUFFIX'] = '.lib' - env['SHLIBPREFIX'] = '' - env['SHLIBSUFFIX'] = '.dll' - env['LIBPREFIXES'] = [ '$LIBPREFIX' ] - env['LIBSUFFIXES'] = [ '$LIBSUFFIX' ] - env['PSPAWN'] = piped_spawn - env['SPAWN'] = spawn - env['SHELL'] = cmd_interp - env['TEMPFILE'] = TempFileMunge - env['TEMPFILEPREFIX'] = '@' - env['MAXLINELENGTH'] = 2048 - env['ESCAPE'] = escape - - env['HOST_OS'] = 'win32' - env['HOST_ARCH'] = get_architecture().arch - - if enable_virtualenv and not ignore_virtualenv: - ImportVirtualenv(env) - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/SConf.py b/scons/scons-local-4.1.0/SCons/SConf.py deleted file mode 100644 index 70a98c867..000000000 --- a/scons/scons-local-4.1.0/SCons/SConf.py +++ /dev/null @@ -1,1116 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Autoconf-like configuration support. - -In other words, SConf allows to run tests on the build machine to detect -capabilities of system and do some things based on result: generate config -files, header files for C/C++, update variables in environment. - -Tests on the build system can detect if compiler sees header files, if -libraries are installed, if some command line options are supported etc. -""" - -import SCons.compat - -import atexit -import io -import os -import re -import sys -import traceback - -import SCons.Action -import SCons.Builder -import SCons.Errors -import SCons.Job -import SCons.Node.FS -import SCons.Taskmaster -import SCons.Util -import SCons.Warnings -import SCons.Conftest - -from SCons.Debug import Trace -from collections import defaultdict - -# Turn off the Conftest error logging -SCons.Conftest.LogInputFiles = 0 -SCons.Conftest.LogErrorMessages = 0 - -# Set -build_type = None -build_types = ['clean', 'help'] - -def SetBuildType(buildtype): - global build_type - build_type = buildtype - -# to be set, if we are in dry-run mode -dryrun = 0 - -AUTO=0 # use SCons dependency scanning for up-to-date checks -FORCE=1 # force all tests to be rebuilt -CACHE=2 # force all tests to be taken from cache (raise an error, if necessary) -cache_mode = AUTO - -def SetCacheMode(mode): - """Set the Configure cache mode. mode must be one of "auto", "force", - or "cache".""" - global cache_mode - if mode == "auto": - cache_mode = AUTO - elif mode == "force": - cache_mode = FORCE - elif mode == "cache": - cache_mode = CACHE - else: - raise ValueError("SCons.SConf.SetCacheMode: Unknown mode " + mode) - -progress_display = SCons.Util.display # will be overwritten by SCons.Script -def SetProgressDisplay(display): - """Set the progress display to use (called from SCons.Script)""" - global progress_display - progress_display = display - -SConfFS = None - -_ac_build_counter = defaultdict(int) -_ac_config_logs = {} # all config.log files created in this build -_ac_config_hs = {} # all config.h files created in this build -sconf_global = None # current sconf object - -def _createConfigH(target, source, env): - t = open(str(target[0]), "w") - defname = re.sub('[^A-Za-z0-9_]', '_', str(target[0]).upper()) - t.write("""#ifndef %(DEFNAME)s_SEEN -#define %(DEFNAME)s_SEEN - -""" % {'DEFNAME' : defname}) - t.write(source[0].get_contents().decode()) - t.write(""" -#endif /* %(DEFNAME)s_SEEN */ -""" % {'DEFNAME' : defname}) - t.close() - -def _stringConfigH(target, source, env): - return "scons: Configure: creating " + str(target[0]) - - -def NeedConfigHBuilder(): - if len(_ac_config_hs) == 0: - return False - else: - return True - -def CreateConfigHBuilder(env): - """Called if necessary just before the building targets phase begins.""" - action = SCons.Action.Action(_createConfigH, - _stringConfigH) - sconfigHBld = SCons.Builder.Builder(action=action) - env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} ) - for k, v in _ac_config_hs.items(): - env.SConfigHBuilder(k, env.Value(v)) - - -class SConfWarning(SCons.Warnings.SConsWarning): - pass -SCons.Warnings.enableWarningClass(SConfWarning) - -# some error definitions -class SConfError(SCons.Errors.UserError): - def __init__(self,msg): - SCons.Errors.UserError.__init__(self,msg) - -class ConfigureDryRunError(SConfError): - """Raised when a file or directory needs to be updated during a Configure - process, but the user requested a dry-run""" - def __init__(self,target): - if not isinstance(target, SCons.Node.FS.File): - msg = 'Cannot create configure directory "%s" within a dry-run.' % str(target) - else: - msg = 'Cannot update configure test "%s" within a dry-run.' % str(target) - SConfError.__init__(self,msg) - -class ConfigureCacheError(SConfError): - """Raised when a use explicitely requested the cache feature, but the test - is run the first time.""" - def __init__(self,target): - SConfError.__init__(self, '"%s" is not yet built and cache is forced.' % str(target)) - - -# define actions for building text files -def _createSource(target, source, env): - fd = open(str(target[0]), "w") - fd.write(source[0].get_contents().decode()) - fd.close() - - -def _stringSource( target, source, env ): - return (str(target[0]) + ' <-\n |' + - source[0].get_contents().decode().replace( '\n', "\n |" ) ) - -class SConfBuildInfo(SCons.Node.FS.FileBuildInfo): - """ - Special build info for targets of configure tests. Additional members - are result (did the builder succeed last time?) and string, which - contains messages of the original build phase. - """ - __slots__ = ('result', 'string') - - def __init__(self): - self.result = None # -> 0/None -> no error, != 0 error - self.string = None # the stdout / stderr output when building the target - - def set_build_result(self, result, string): - self.result = result - self.string = string - - -class Streamer: - """ - 'Sniffer' for a file-like writable object. Similar to the unix tool tee. - """ - def __init__(self, orig): - self.orig = orig - self.s = io.StringIO() - - def write(self, str): - if self.orig: - self.orig.write(str) - try: - self.s.write(str) - except TypeError as e: - # "unicode argument expected" bug in IOStream (python 2.x) - self.s.write(str.decode()) - - def writelines(self, lines): - for l in lines: - self.write(l + '\n') - - def getvalue(self): - """ - Return everything written to orig since the Streamer was created. - """ - return self.s.getvalue() - - def flush(self): - if self.orig: - self.orig.flush() - self.s.flush() - - -class SConfBuildTask(SCons.Taskmaster.AlwaysTask): - """ - This is almost the same as SCons.Script.BuildTask. Handles SConfErrors - correctly and knows about the current cache_mode. - """ - def display(self, message): - if sconf_global.logstream: - sconf_global.logstream.write("scons: Configure: " + message + "\n") - - def display_cached_string(self, bi): - """ - Logs the original builder messages, given the SConfBuildInfo instance - bi. - """ - if not isinstance(bi, SConfBuildInfo): - SCons.Warnings.warn(SConfWarning, - "The stored build information has an unexpected class: %s" % bi.__class__) - else: - self.display("The original builder output was:\n" + - (" |" + str(bi.string)).replace("\n", "\n |")) - - def failed(self): - # check, if the reason was a ConfigureDryRunError or a - # ConfigureCacheError and if yes, reraise the exception - exc_type = self.exc_info()[0] - if issubclass(exc_type, SConfError): - # TODO pylint E0704: bare raise not inside except - raise - elif issubclass(exc_type, SCons.Errors.BuildError): - # we ignore Build Errors (occurs, when a test doesn't 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]) - sys.excepthook(*self.exc_info()) - return SCons.Taskmaster.Task.failed(self) - - def collect_node_states(self): - # returns (is_up_to_date, cached_error, cachable) - # where is_up_to_date is 1, if the node(s) are up_to_date - # cached_error is 1, if the node(s) are up_to_date, but the - # build will fail - # cachable is 0, if some nodes are not in our cache - T = 0 - changed = False - cached_error = False - cachable = True - for t in self.targets: - if T: Trace('%s' % t) - bi = t.get_stored_info().binfo - if isinstance(bi, SConfBuildInfo): - if T: Trace(': SConfBuildInfo') - if cache_mode == CACHE: - t.set_state(SCons.Node.up_to_date) - if T: Trace(': set_state(up_to-date)') - else: - if T: Trace(': get_state() %s' % t.get_state()) - if T: Trace(': changed() %s' % t.changed()) - if t.get_state() != SCons.Node.up_to_date and t.changed(): - changed = True - if T: Trace(': changed %s' % changed) - cached_error = cached_error or bi.result - else: - if T: Trace(': else') - # the node hasn't been built in a SConf context or doesn't - # exist - cachable = False - changed = ( t.get_state() != SCons.Node.up_to_date ) - if T: Trace(': changed %s' % changed) - if T: Trace('\n') - return (not changed, cached_error, cachable) - - def execute(self): - if not self.targets[0].has_builder(): - return - - sconf = sconf_global - - is_up_to_date, cached_error, cachable = self.collect_node_states() - - if cache_mode == CACHE and not cachable: - raise ConfigureCacheError(self.targets[0]) - elif cache_mode == FORCE: - is_up_to_date = 0 - - if cached_error and is_up_to_date: - self.display("Building \"%s\" failed in a previous run and all " - "its sources are up to date." % str(self.targets[0])) - binfo = self.targets[0].get_stored_info().binfo - self.display_cached_string(binfo) - raise SCons.Errors.BuildError # will be 'caught' in self.failed - elif is_up_to_date: - self.display("\"%s\" is up to date." % str(self.targets[0])) - binfo = self.targets[0].get_stored_info().binfo - self.display_cached_string(binfo) - elif dryrun: - raise ConfigureDryRunError(self.targets[0]) - else: - # note stdout and stderr are the same here - s = sys.stdout = sys.stderr = Streamer(sys.stdout) - try: - env = self.targets[0].get_build_env() - env['PSTDOUT'] = env['PSTDERR'] = s - try: - sconf.cached = 0 - self.targets[0].build() - finally: - sys.stdout = sys.stderr = env['PSTDOUT'] = \ - env['PSTDERR'] = sconf.logstream - except KeyboardInterrupt: - raise - except SystemExit: - exc_value = sys.exc_info()[1] - raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code) - except Exception as e: - for t in self.targets: - binfo = SConfBuildInfo() - binfo.merge(t.get_binfo()) - binfo.set_build_result(1, s.getvalue()) - sconsign_entry = SCons.SConsign.SConsignEntry() - sconsign_entry.binfo = binfo - #sconsign_entry.ninfo = self.get_ninfo() - # We'd like to do this as follows: - # t.store_info(binfo) - # However, we need to store it as an SConfBuildInfo - # object, and store_info() will turn it into a - # regular FileNodeInfo if the target is itself a - # regular File. - sconsign = t.dir.sconsign() - sconsign.set_entry(t.name, sconsign_entry) - sconsign.merge() - raise e - else: - for t in self.targets: - binfo = SConfBuildInfo() - binfo.merge(t.get_binfo()) - binfo.set_build_result(0, s.getvalue()) - sconsign_entry = SCons.SConsign.SConsignEntry() - sconsign_entry.binfo = binfo - #sconsign_entry.ninfo = self.get_ninfo() - # We'd like to do this as follows: - # t.store_info(binfo) - # However, we need to store it as an SConfBuildInfo - # object, and store_info() will turn it into a - # regular FileNodeInfo if the target is itself a - # regular File. - sconsign = t.dir.sconsign() - sconsign.set_entry(t.name, sconsign_entry) - sconsign.merge() - -class SConfBase: - """This is simply a class to represent a configure context. After - creating a SConf object, you can call any tests. After finished with your - tests, be sure to call the Finish() method, which returns the modified - environment. - Some words about caching: In most cases, it is not necessary to cache - Test results explicitly. Instead, we use the scons dependency checking - mechanism. For example, if one wants to compile a test program - (SConf.TryLink), the compiler is only called, if the program dependencies - have changed. However, if the program could not be compiled in a former - SConf run, we need to explicitly cache this error. - """ - - def __init__(self, env, custom_tests = {}, conf_dir='$CONFIGUREDIR', - log_file='$CONFIGURELOG', config_h = None, _depth = 0): - """Constructor. Pass additional tests in the custom_tests-dictionary, - 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 VariantDir, not in the SourceDir) - """ - global SConfFS - - # Now create isolated override so setting source_decider doesn't affect parent Environment - if cache_mode == FORCE: - self.original_env = env - self.env = env.Clone() - - # Set up the Decider() to force rebuilds by saying - # that every source has changed. Note that we still - # call the environment's underlying source decider so - # that the correct .sconsign info will get calculated - # and keep the build state consistent. - def force_build(dependency, target, prev_ni, - repo_node=None, - env_decider=env.decide_source): - try: - env_decider(dependency, target, prev_ni, repo_node) - except Exception as e: - raise e - return True - - if self.env.decide_source.__code__ is not force_build.__code__: - self.env.Decider(force_build) - - else: - self.env = env - - # print("Override env:%s"%env) - - if not SConfFS: - SConfFS = SCons.Node.FS.default_fs or \ - SCons.Node.FS.FS(env.fs.pathTop) - if sconf_global is not None: - raise SCons.Errors.UserError("""Configure() called while another Configure() exists. - Please call .Finish() before creating and second Configure() context""") - - if log_file is not None: - log_file = SConfFS.File(env.subst(log_file)) - self.logfile = log_file - self.logstream = None - self.lastTarget = None - self.depth = _depth - self.cached = 0 # will be set, if all test results are cached - - # 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, - 'CheckProg' : CheckProg, - } - self.AddTests(default_tests) - self.AddTests(custom_tests) - self.confdir = SConfFS.Dir(env.subst(conf_dir)) - if config_h is not None: - config_h = SConfFS.File(config_h) - self.config_h = config_h - self._startup() - - def Finish(self): - """Call this method after finished with your tests: - env = sconf.Finish() - """ - 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 will be added 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 + '\n'.join(lines) - - def BuildNodes(self, nodes): - """ - Tries to build the given nodes immediately. Returns 1 on success, - 0 on error. - """ - if self.logstream is not None: - # override stdout / stderr to write in log file - oldStdout = sys.stdout - sys.stdout = self.logstream - oldStderr = sys.stderr - sys.stderr = self.logstream - - # the engine assumes the current path is the SConstruct directory ... - old_fs_dir = SConfFS.getcwd() - old_os_dir = os.getcwd() - SConfFS.chdir(SConfFS.Top, change_os_dir=1) - - # Because we take responsibility here for writing out our - # own .sconsign info (see SConfBuildTask.execute(), above), - # we override the store_info() method with a null place-holder - # so we really control how it gets written. - for n in nodes: - self._set_conftest_node(n) - n.store_info = 0 - if not hasattr(n, 'attributes'): - n.attributes = SCons.Node.Node.Attrs() - n.attributes.keep_targetinfo = 1 - - if True: - # Some checkers have intermediate files (for example anything that compiles a c file into a program to run - # Those files need to be set to not release their target info, otherwise taskmaster will throw a - # Nonetype not callable - for c in n.children(scan=False): - # Keep debug code here. - # print("Checking [%s] for builders and then setting keep_targetinfo"%c) - self._set_conftest_node(c) - if c.has_builder(): - n.store_info = 0 - if not hasattr(c, 'attributes'): - c.attributes = SCons.Node.Node.Attrs() - c.attributes.keep_targetinfo = 1 - # pass - - ret = 1 - - try: - # ToDo: use user options for calc - save_max_drift = SConfFS.get_max_drift() - SConfFS.set_max_drift(0) - tm = SCons.Taskmaster.Taskmaster(nodes, SConfBuildTask) - # we don't want to build tests in parallel - jobs = SCons.Job.Jobs(1, tm ) - jobs.run() - for n in nodes: - state = n.get_state() - if (state != SCons.Node.executed and - state != SCons.Node.up_to_date): - # the node could not be built. we return 0 in this case - ret = 0 - finally: - SConfFS.set_max_drift(save_max_drift) - os.chdir(old_os_dir) - SConfFS.chdir(old_fs_dir, change_os_dir=0) - if self.logstream is not None: - # restore stdout / stderr - sys.stdout = oldStdout - sys.stderr = oldStderr - return ret - - def pspawn_wrapper(self, sh, escape, cmd, args, env): - """Wrapper function for handling piped spawns. - - This looks to the calling interface (in Action.py) like a "normal" - spawn, but associates the call with the PSPAWN variable from - the construction environment and with the streams to which we - want the output logged. This gets slid into the construction - environment as the SPAWN variable so Action.py doesn't have to - know or care whether it's spawning a piped command or not. - """ - return self.pspawn(sh, escape, cmd, args, env, self.logstream, self.logstream) - - def TryBuild(self, builder, text=None, extension=""): - """Low level TryBuild implementation. Normally you don't need to - call that - you can use TryCompile / TryLink / TryRun instead - """ - global _ac_build_counter - - # Make sure we have a PSPAWN value, and save the current - # SPAWN value. - try: - self.pspawn = self.env['PSPAWN'] - except KeyError: - raise SCons.Errors.UserError('Missing PSPAWN construction variable.') - try: - save_spawn = self.env['SPAWN'] - except KeyError: - raise SCons.Errors.UserError('Missing SPAWN construction variable.') - - nodesToBeBuilt = [] - sourcetext = self.env.Value(text) - self._set_conftest_node(sourcetext) - f = "conftest" - - if text is not None: - textSig = SCons.Util.MD5signature(sourcetext) - textSigCounter = str(_ac_build_counter[textSig]) - _ac_build_counter[textSig] += 1 - - f = "_".join([f, textSig, textSigCounter]) - textFile = self.confdir.File(f + extension) - self._set_conftest_node(sourcetext) - textFileNode = self.env.SConfSourceBuilder(target=textFile, - source=sourcetext) - nodesToBeBuilt.extend(textFileNode) - - source = textFile - target = textFile.File(f + "SConfActionsContentDummyTarget") - self._set_conftest_node(target) - else: - source = None - target = None - - action = builder.builder.action.get_contents(target=target, source=[source], env=self.env) - actionsig = SCons.Util.MD5signature(action) - f = "_".join([f, actionsig]) - - pref = self.env.subst( builder.builder.prefix ) - suff = self.env.subst( builder.builder.suffix ) - target = self.confdir.File(pref + f + suff) - - try: - # Slide our wrapper into the construction environment as - # the SPAWN function. - self.env['SPAWN'] = self.pspawn_wrapper - - nodes = builder(target = target, source = source) - if not SCons.Util.is_List(nodes): - nodes = [nodes] - nodesToBeBuilt.extend(nodes) - result = self.BuildNodes(nodesToBeBuilt) - - finally: - self.env['SPAWN'] = save_spawn - - if result: - self.lastTarget = nodes[0] - else: - self.lastTarget = None - - return result - - def TryAction(self, action, text = None, extension = ""): - """Tries to execute the given action with optional source file - contents and optional source file extension , - Returns the status (0 : failed, 1 : ok) and the contents of the - output file. - """ - builder = SCons.Builder.Builder(action=action) - self.env.Append( BUILDERS = {'SConfActionBuilder' : builder} ) - ok = self.TryBuild(self.env.SConfActionBuilder, text, extension) - del self.env['BUILDERS']['SConfActionBuilder'] - if ok: - outputStr = self.lastTarget.get_text_contents() - return (1, outputStr) - return (0, "") - - def TryCompile( self, text, extension): - """Compiles the program given in text to an env.Object, using extension - as file extension (e.g. '.c'). Returns 1, if compilation was - successful, 0 otherwise. The target is saved in self.lastTarget (for - further processing). - """ - return self.TryBuild(self.env.Object, text, extension) - - def TryLink( self, text, extension ): - """Compiles the program given in text to an executable env.Program, - using extension as file extension (e.g. '.c'). Returns 1, if - compilation was successful, 0 otherwise. The target is saved in - self.lastTarget (for further processing). - """ - return self.TryBuild(self.env.Program, text, extension ) - - def TryRun(self, text, extension ): - """Compiles and runs the program given in text, using extension - as file extension (e.g. '.c'). Returns (1, outputStr) on success, - (0, '') otherwise. The target (a file containing the program's stdout) - is saved in self.lastTarget (for further processing). - """ - ok = self.TryLink(text, extension) - if ok: - prog = self.lastTarget - pname = prog.get_internal_path() - output = self.confdir.File(os.path.basename(pname)+'.out') - node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ]) - ok = self.BuildNodes(node) - if ok: - outputStr = SCons.Util.to_str(output.get_contents()) - return( 1, outputStr) - return (0, "") - - class TestWrapper: - """A wrapper around Tests (to ensure sanity)""" - def __init__(self, test, sconf): - self.test = test - self.sconf = sconf - def __call__(self, *args, **kw): - if not self.sconf.active: - raise SCons.Errors.UserError - context = CheckContext(self.sconf) - ret = self.test(context, *args, **kw) - if self.sconf.config_h is not None: - self.sconf.config_h_text = self.sconf.config_h_text + context.config_h - context.Result("error: no result") - return ret - - def AddTest(self, test_name, test_instance): - """Adds test_class to this SConf instance. It can be called with - self.test_name(...)""" - setattr(self, test_name, SConfBase.TestWrapper(test_instance, self)) - - def AddTests(self, tests): - """Adds all the tests given in the tests dictionary to this SConf - instance - """ - for name in tests.keys(): - self.AddTest(name, tests[name]) - - def _createDir( self, node ): - dirName = str(node) - if dryrun: - if not os.path.isdir( dirName ): - raise ConfigureDryRunError(dirName) - else: - if not os.path.isdir( dirName ): - os.makedirs( dirName ) - - def _set_conftest_node(self, node): - node.attributes.conftest_node = 1 - - def _startup(self): - """Private method. Set up logstream, and set the environment - variables necessary for a piped build - """ - global _ac_config_logs - global sconf_global - global SConfFS - - self.lastEnvFs = self.env.fs - self.env.fs = SConfFS - self._createDir(self.confdir) - self.confdir.up().add_ignore( [self.confdir] ) - - if self.logfile is not None and not dryrun: - # truncate logfile, if SConf.Configure is called for the first time - # in a build - if self.logfile in _ac_config_logs: - log_mode = "a" - else: - _ac_config_logs[self.logfile] = None - log_mode = "w" - fp = open(str(self.logfile), log_mode) - - def conflog_cleanup(logf): - logf.close() - - atexit.register(conflog_cleanup, fp) - self.logstream = SCons.Util.Unbuffered(fp) - # logfile may stay in a build directory, so we tell - # the build system not to override it with an eventually - # existing file with the same name in the source directory - self.logfile.dir.add_ignore([self.logfile]) - - tb = traceback.extract_stack()[-3-self.depth] - old_fs_dir = SConfFS.getcwd() - SConfFS.chdir(SConfFS.Top, change_os_dir=0) - self.logstream.write('file %s,line %d:\n\tConfigure(confdir = %s)\n' % - (tb[0], tb[1], str(self.confdir)) ) - SConfFS.chdir(old_fs_dir) - else: - self.logstream = None - # we use a special builder to create source files from TEXT - action = SCons.Action.Action(_createSource, - _stringSource) - sconfSrcBld = SCons.Builder.Builder(action=action) - self.env.Append( BUILDERS={'SConfSourceBuilder':sconfSrcBld} ) - self.config_h_text = _ac_config_hs.get(self.config_h, "") - self.active = 1 - # only one SConf instance should be active at a time ... - sconf_global = self - - def _shutdown(self): - """Private method. Reset to non-piped spawn""" - global sconf_global, _ac_config_hs - - if not self.active: - raise SCons.Errors.UserError("Finish may be called only once!") - if self.logstream is not None and not dryrun: - self.logstream.write("\n") - self.logstream.close() - self.logstream = None - - # Now reset the decider if we changed it due to --config=force - # We saved original Environment passed in and cloned it to isolate - # it from being changed. - if cache_mode == FORCE: - self.env.Decider(self.original_env.decide_source) - - # remove the SConfSourceBuilder from the environment - blds = self.env['BUILDERS'] - del blds['SConfSourceBuilder'] - self.env.Replace( BUILDERS=blds ) - - self.active = 0 - sconf_global = None - if self.config_h is not None: - _ac_config_hs[self.config_h] = self.config_h_text - self.env.fs = self.lastEnvFs - -class CheckContext: - """Provides a context for configure tests. Defines how a test writes to the - screen and log file. - - A typical test is just a callable with an instance of CheckContext as - first argument: - - def CheckCustom(context, ...): - context.Message('Checking my weird test ... ') - ret = myWeirdTestFunction(...) - context.Result(ret) - - Often, myWeirdTestFunction will be one of - context.TryCompile/context.TryLink/context.TryRun. The results of - those are cached, for they are only rebuild, if the dependencies have - changed. - """ - - def __init__(self, sconf): - """Constructor. Pass the corresponding SConf instance.""" - self.sconf = sconf - self.did_show_result = 0 - - # for Conftest.py: - self.vardict = {} - self.havedict = {} - self.headerfilename = None - self.config_h = "" # config_h text will be stored here - # we don't regenerate the config.h file after each test. That means, - # that tests won't be able to include the config.h file, and so - # they can't do an #ifdef HAVE_XXX_H. This shouldn't be a major - # issue, though. If it turns out, that we need to include config.h - # in tests, we must ensure, that the dependencies are worked out - # correctly. Note that we can't use Conftest.py's support for config.h, - # cause we will need to specify a builder for the config.h file ... - - def Message(self, text): - """Inform about what we are doing right now, e.g. - 'Checking for SOMETHING ... ' - """ - self.Display(text) - self.sconf.cached = 1 - self.did_show_result = 0 - - def Result(self, res): - """Inform about the result of the test. If res is not a string, displays - 'yes' or 'no' depending on whether res is evaluated as true or false. - The result is only displayed when self.did_show_result is not set. - """ - if isinstance(res, str): - text = res - elif res: - text = "yes" - else: - text = "no" - - if self.did_show_result == 0: - # Didn't show result yet, do it now. - self.Display(text + "\n") - self.did_show_result = 1 - - def TryBuild(self, *args, **kw): - return self.sconf.TryBuild(*args, **kw) - - def TryAction(self, *args, **kw): - return self.sconf.TryAction(*args, **kw) - - def TryCompile(self, *args, **kw): - return self.sconf.TryCompile(*args, **kw) - - def TryLink(self, *args, **kw): - return self.sconf.TryLink(*args, **kw) - - def TryRun(self, *args, **kw): - return self.sconf.TryRun(*args, **kw) - - def __getattr__( self, attr ): - if attr == 'env': - return self.sconf.env - elif attr == 'lastTarget': - return self.sconf.lastTarget - else: - raise AttributeError("CheckContext instance has no attribute '%s'" % attr) - - #### Stuff used by Conftest.py (look there for explanations). - - def BuildProg(self, text, ext): - self.sconf.cached = 1 - # TODO: should use self.vardict for $CC, $CPPFLAGS, etc. - return not self.TryBuild(self.env.Program, text, ext) - - def CompileProg(self, text, ext): - self.sconf.cached = 1 - # 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) - return oldLIBS - - def PrependLIBS(self, lib_name_list): - oldLIBS = self.env.get( 'LIBS', [] ) - self.env.Prepend(LIBS = lib_name_list) - return oldLIBS - - def SetLIBS(self, val): - oldLIBS = self.env.get( 'LIBS', [] ) - self.env.Replace(LIBS = val) - return oldLIBS - - def Display(self, msg): - if self.sconf.cached: - # We assume that Display is called twice for each test here - # once for the Checking for ... message and once for the result. - # The self.sconf.cached flag can only be set between those calls - msg = "(cached) " + msg - self.sconf.cached = 0 - progress_display(msg, append_newline=0) - self.Log("scons: Configure: " + msg + "\n") - - def Log(self, msg): - if self.sconf.logstream is not None: - self.sconf.logstream.write(msg) - - #### End of stuff used by Conftest.py. - - -def SConf(*args, **kw): - if kw.get(build_type, True): - kw['_depth'] = kw.get('_depth', 0) + 1 - for bt in build_types: - try: - del kw[bt] - except KeyError: - pass - return SConfBase(*args, **kw) - else: - return SCons.Util.Null() - - -def CheckFunc(context, function_name, header = None, language = None): - res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language) - context.did_show_result = 1 - return not res - -def CheckType(context, type_name, includes = "", language = None): - res = SCons.Conftest.CheckType(context, type_name, - header = includes, language = language) - context.did_show_result = 1 - return not res - -def CheckTypeSize(context, type_name, includes = "", language = None, expect = None): - res = SCons.Conftest.CheckTypeSize(context, type_name, - header = includes, language = language, - expect = expect) - 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) - if not SCons.Util.is_List(headers): - headers = [headers] - l = [] - if leaveLast: - lastHeader = headers[-1] - headers = headers[:-1] - else: - lastHeader = None - for s in headers: - l.append("#include %s%s%s\n" - % (include_quotes[0], s, include_quotes[1])) - return ''.join(l), lastHeader - -def CheckHeader(context, header, include_quotes = '<>', language = None): - """ - A test for a C or C++ header file. - """ - prog_prefix, hdr_to_check = \ - createIncludesFromHeaders(header, 1, include_quotes) - res = SCons.Conftest.CheckHeader(context, hdr_to_check, prog_prefix, - language = language, - include_quotes = include_quotes) - context.did_show_result = 1 - return not res - -def CheckCC(context): - res = SCons.Conftest.CheckCC(context) - context.did_show_result = 1 - return not res - -def CheckCXX(context): - res = SCons.Conftest.CheckCXX(context) - context.did_show_result = 1 - return not res - -def CheckSHCC(context): - res = SCons.Conftest.CheckSHCC(context) - context.did_show_result = 1 - return not res - -def CheckSHCXX(context): - res = SCons.Conftest.CheckSHCXX(context) - context.did_show_result = 1 - return not res - -# Bram: Make this function obsolete? CheckHeader() is more generic. - -def CheckCHeader(context, header, include_quotes = '""'): - """ - A test for a C header file. - """ - return CheckHeader(context, header, include_quotes, language = "C") - - -# Bram: Make this function obsolete? CheckHeader() is more generic. - -def CheckCXXHeader(context, header, include_quotes = '""'): - """ - A test for a C++ header file. - """ - return CheckHeader(context, header, include_quotes, language = "C++") - - -def CheckLib(context, library = None, symbol = "main", - header = None, language = None, autoadd = 1): - """ - A test for a library. See also CheckLibWithHeader. - Note that library may also be None to test whether the given symbol - compiles without flags. - """ - - if not library: - library = [None] - - if not SCons.Util.is_List(library): - library = [library] - - # ToDo: accept path for the library - res = SCons.Conftest.CheckLib(context, library, symbol, header = header, - language = language, autoadd = autoadd) - context.did_show_result = 1 - return not res - -# XXX -# Bram: Can only include one header and can't use #ifdef HAVE_HEADER_H. - -def CheckLibWithHeader(context, libs, header, language, - call = None, autoadd = 1): - # ToDo: accept path for library. Support system header files. - """ - Another (more sophisticated) test for a library. - Checks, if library and header is available for language (may be 'C' - or 'CXX'). Call maybe be a valid expression _with_ a trailing ';'. - As in CheckLib, we support library=None, to test if the call compiles - without extra link flags. - """ - prog_prefix, dummy = \ - createIncludesFromHeaders(header, 0) - if not libs: - libs = [None] - - if not SCons.Util.is_List(libs): - libs = [libs] - - res = SCons.Conftest.CheckLib(context, libs, None, prog_prefix, - call = call, language = language, autoadd = autoadd) - context.did_show_result = 1 - return not res - -def CheckProg(context, prog_name): - """Simple check if a program exists in the path. Returns the path - for the application, or None if not found. - """ - res = SCons.Conftest.CheckProg(context, prog_name) - context.did_show_result = 1 - return res - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/SConsign.py b/scons/scons-local-4.1.0/SCons/SConsign.py deleted file mode 100644 index 95b809629..000000000 --- a/scons/scons-local-4.1.0/SCons/SConsign.py +++ /dev/null @@ -1,427 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Operations on signature database files (.sconsign). """ - -import SCons.compat - -import os -import pickle - -import SCons.dblite -import SCons.Warnings - -from SCons.compat import PICKLE_PROTOCOL - - -def corrupt_dblite_warning(filename): - SCons.Warnings.warn( - SCons.Warnings.CorruptSConsignWarning, - "Ignoring corrupt .sconsign file: %s" % filename, - ) - -SCons.dblite.IGNORE_CORRUPT_DBFILES = True -SCons.dblite.corruption_warning = corrupt_dblite_warning - -# XXX Get rid of the global array so this becomes re-entrant. -sig_files = [] - -# Info for the database SConsign implementation (now the default): -# "DataBase" is a dictionary that maps top-level SConstruct directories -# to open database handles. -# "DB_Module" is the Python database module to create the handles. -# "DB_Name" is the base name of the database file (minus any -# extension the underlying DB module will add). -DataBase = {} -DB_Module = SCons.dblite -DB_Name = ".sconsign" -DB_sync_list = [] - - -def Get_DataBase(dir): - global DataBase, DB_Module, DB_Name - top = dir.fs.Top - if not os.path.isabs(DB_Name) and top.repositories: - mode = "c" - for d in [top] + top.repositories: - if dir.is_under(d): - try: - return DataBase[d], mode - except KeyError: - path = d.entry_abspath(DB_Name) - try: db = DataBase[d] = DB_Module.open(path, mode) - except (IOError, OSError): - pass - else: - if mode != "r": - DB_sync_list.append(db) - return db, mode - mode = "r" - try: - return DataBase[top], "c" - except KeyError: - db = DataBase[top] = DB_Module.open(DB_Name, "c") - DB_sync_list.append(db) - return db, "c" - except TypeError: - print("DataBase =", DataBase) - raise - - -def Reset(): - """Reset global state. Used by unit tests that end up using - SConsign multiple times to get a clean slate for each test.""" - global sig_files, DB_sync_list - sig_files = [] - DB_sync_list = [] - -normcase = os.path.normcase - - -def write(): - global sig_files - for sig_file in sig_files: - sig_file.write(sync=0) - for db in DB_sync_list: - try: - syncmethod = db.sync - except AttributeError: - pass # Not all dbm modules have sync() methods. - else: - syncmethod() - try: - closemethod = db.close - except AttributeError: - pass # Not all dbm modules have close() methods. - else: - closemethod() - - -class SConsignEntry: - """ - Wrapper class for the generic entry in a .sconsign file. - The Node subclass populates it with attributes as it pleases. - - XXX As coded below, we do expect a '.binfo' attribute to be added, - but we'll probably generalize this in the next refactorings. - """ - __slots__ = ("binfo", "ninfo", "__weakref__") - current_version_id = 2 - - def __init__(self): - # Create an object attribute from the class attribute so it ends up - # in the pickled data in the .sconsign file. - #_version_id = self.current_version_id - pass - - def convert_to_sconsign(self): - self.binfo.convert_to_sconsign() - - def convert_from_sconsign(self, dir, name): - self.binfo.convert_from_sconsign(dir, name) - - def __getstate__(self): - state = getattr(self, '__dict__', {}).copy() - for obj in type(self).mro(): - for name in getattr(obj, '__slots__', ()): - if hasattr(self, name): - state[name] = getattr(self, name) - - state['_version_id'] = self.current_version_id - try: - del state['__weakref__'] - except KeyError: - pass - return state - - def __setstate__(self, state): - for key, value in state.items(): - if key not in ('_version_id', '__weakref__'): - setattr(self, key, value) - - -class Base: - """ - This is the controlling class for the signatures for the collection of - entries associated with a specific directory. The actual directory - association will be maintained by a subclass that is specific to - the underlying storage method. This class provides a common set of - methods for fetching and storing the individual bits of information - that make up signature entry. - """ - def __init__(self): - self.entries = {} - self.dirty = False - self.to_be_merged = {} - - def get_entry(self, filename): - """ - Fetch the specified entry attribute. - """ - return self.entries[filename] - - def set_entry(self, filename, obj): - """ - Set the entry. - """ - self.entries[filename] = obj - self.dirty = True - - def do_not_set_entry(self, filename, obj): - pass - - def store_info(self, filename, node): - entry = node.get_stored_info() - entry.binfo.merge(node.get_binfo()) - self.to_be_merged[filename] = node - self.dirty = True - - def do_not_store_info(self, filename, node): - pass - - def merge(self): - for key, node in self.to_be_merged.items(): - entry = node.get_stored_info() - try: - ninfo = entry.ninfo - except AttributeError: - # This happens with SConf Nodes, because the configuration - # subsystem takes direct control over how the build decision - # is made and its information stored. - pass - else: - ninfo.merge(node.get_ninfo()) - self.entries[key] = entry - self.to_be_merged = {} - - -class DB(Base): - """ - A Base subclass that reads and writes signature information - from a global .sconsign.db* file--the actual file suffix is - determined by the database module. - """ - def __init__(self, dir): - Base.__init__(self) - - self.dir = dir - - db, mode = Get_DataBase(dir) - - # Read using the path relative to the top of the Repository - # (self.dir.tpath) from which we're fetching the signature - # information. - path = normcase(dir.get_tpath()) - try: - rawentries = db[path] - except KeyError: - pass - else: - try: - self.entries = pickle.loads(rawentries) - if not isinstance(self.entries, dict): - self.entries = {} - raise TypeError - except KeyboardInterrupt: - raise - except Exception as e: - SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning, - "Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.get_tpath(), e)) - for key, entry in self.entries.items(): - entry.convert_from_sconsign(dir, key) - - if mode == "r": - # This directory is actually under a repository, which means - # likely they're reaching in directly for a dependency on - # a file there. Don't actually set any entry info, so we - # won't try to write to that .sconsign.dblite file. - self.set_entry = self.do_not_set_entry - self.store_info = self.do_not_store_info - - global sig_files - sig_files.append(self) - - def write(self, sync=1): - if not self.dirty: - return - - self.merge() - - db, mode = Get_DataBase(self.dir) - - # Write using the path relative to the top of the SConstruct - # directory (self.dir.path), not relative to the top of - # the Repository; we only write to our own .sconsign file, - # not to .sconsign files in Repositories. - path = normcase(self.dir.get_internal_path()) - for key, entry in self.entries.items(): - entry.convert_to_sconsign() - db[path] = pickle.dumps(self.entries, PICKLE_PROTOCOL) - - if sync: - try: - syncmethod = db.sync - except AttributeError: - # Not all anydbm modules have sync() methods. - pass - else: - syncmethod() - - -class Dir(Base): - def __init__(self, fp=None, dir=None): - """ - fp - file pointer to read entries from - """ - Base.__init__(self) - - if not fp: - return - - self.entries = pickle.load(fp) - if not isinstance(self.entries, dict): - self.entries = {} - raise TypeError - - if dir: - for key, entry in self.entries.items(): - entry.convert_from_sconsign(dir, key) - - -class DirFile(Dir): - """ - Encapsulates reading and writing a per-directory .sconsign file. - """ - def __init__(self, dir): - """ - dir - the directory for the file - """ - - self.dir = dir - self.sconsign = os.path.join(dir.get_internal_path(), '.sconsign') - - try: - fp = open(self.sconsign, 'rb') - except IOError: - fp = None - - try: - Dir.__init__(self, fp, dir) - except KeyboardInterrupt: - raise - except Exception: - SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning, - "Ignoring corrupt .sconsign file: %s"%self.sconsign) - - try: - fp.close() - except AttributeError: - pass - - global sig_files - sig_files.append(self) - - def write(self, sync=1): - """ - Write the .sconsign file to disk. - - Try to write to a temporary file first, and rename it if we - succeed. If we can't write to the temporary file, it's - probably because the directory isn't writable (and if so, - how did we build anything in this directory, anyway?), so - try to write directly to the .sconsign file as a backup. - If we can't rename, try to copy the temporary contents back - to the .sconsign file. Either way, always try to remove - the temporary file at the end. - """ - if not self.dirty: - return - - self.merge() - - temp = os.path.join(self.dir.get_internal_path(), '.scons%d' % os.getpid()) - try: - file = open(temp, 'wb') - fname = temp - except IOError: - try: - file = open(self.sconsign, 'wb') - fname = self.sconsign - except IOError: - return - for key, entry in self.entries.items(): - entry.convert_to_sconsign() - pickle.dump(self.entries, file, PICKLE_PROTOCOL) - file.close() - if fname != self.sconsign: - try: - mode = os.stat(self.sconsign)[0] - os.chmod(self.sconsign, 0o666) - os.unlink(self.sconsign) - except (IOError, OSError): - # Try to carry on in the face of either OSError - # (things like permission issues) or IOError (disk - # or network issues). If there's a really dangerous - # issue, it should get re-raised by the calls below. - pass - try: - os.rename(fname, self.sconsign) - except OSError: - # An OSError failure to rename may indicate something - # like the directory has no write permission, but - # the .sconsign file itself might still be writable, - # so try writing on top of it directly. An IOError - # here, or in any of the following calls, would get - # raised, indicating something like a potentially - # serious disk or network issue. - with open(self.sconsign, 'wb') as f, open(fname, 'rb') as f2: - f.write(f2.read()) - os.chmod(self.sconsign, mode) - try: - os.unlink(temp) - except (IOError, OSError): - pass - -ForDirectory = DB - - -def File(name, dbm_module=None): - """ - Arrange for all signatures to be stored in a global .sconsign.db* - file. - """ - global ForDirectory, DB_Name, DB_Module - if name is None: - ForDirectory = DirFile - DB_Module = None - else: - ForDirectory = DB - DB_Name = name - if dbm_module is not None: - DB_Module = dbm_module - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/C.py b/scons/scons-local-4.1.0/SCons/Scanner/C.py deleted file mode 100644 index 91beb04f4..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/C.py +++ /dev/null @@ -1,218 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for C/C++ code.""" - -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): - 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: - with open(str(file.rfile())) as fp: - return fp.read() - except EnvironmentError as e: - self.missing.append((file, self.current_file)) - return '' - -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", - r'^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")', - ) - return cs - - -# -# ConditionalScanner -# - - -class SConsCPPConditionalScanner(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): - SCons.cpp.PreProcessor.__init__(self, *args, **kw) - self.missing = [] - self._known_paths = [] - - def initialize_result(self, fname): - self.result = SCons.Util.UniqueList([fname]) - - def find_include_file(self, t): - keyword, quote, fname = t - paths = tuple(self._known_paths) + self.searchpath[quote] - if quote == '"': - paths = (self.current_file.dir,) + paths - result = SCons.Node.FS.find_file(fname, paths) - if result: - result_path = result.get_abspath() - for p in self.searchpath[quote]: - if result_path.startswith(p.get_abspath()): - self._known_paths.append(p) - break - else: - self.missing.append((fname, self.current_file)) - return result - - def read_file(self, file): - try: - with open(str(file.rfile())) as fp: - return fp.read() - except EnvironmentError: - self.missing.append((file, self.current_file)) - return "" - - -class SConsCPPConditionalScannerWrapper: - """ - 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=(), depth=-1): - cpp = SConsCPPConditionalScanner( - current=node.get_dir(), - cpppath=path, - dict=dictify_CPPDEFINES(env), - depth=depth, - ) - 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 CConditionalScanner(): - """ - Return an advanced conditional Scanner instance for scanning source files - - Interprets C/C++ Preprocessor conditional syntax - (#ifdef, #if, defined, #else, #elif, etc.). - """ - return SConsCPPConditionalScannerWrapper("CConditionalScanner", "CPPPATH") - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/D.py b/scons/scons-local-4.1.0/SCons/Scanner/D.py deleted file mode 100644 index 645934b1a..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/D.py +++ /dev/null @@ -1,67 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Scanner for the Digital Mars "D" programming language. - -Coded by Andy Friesen, 17 Nov 2003 -""" - -import SCons.Scanner - -def DScanner(): - """Return a prototype Scanner instance for scanning D source files""" - 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 = r'(?:import\s+)([\w\s=,.]+)(?:\s*:[\s\w,=]+)?(?:;)' - ) - - def find_include(self, include, source_dir, path): - # translate dots (package separators) to slashes - inc = include.replace('.', '/') - - 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 iii in self.cre.findall(node.get_text_contents()): - for jjj in iii.split(','): - kkk = jjj.split('=')[-1] - includes.append(kkk.strip()) - return includes - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/Dir.py b/scons/scons-local-4.1.0/SCons/Scanner/Dir.py deleted file mode 100644 index 617bf2bf9..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/Dir.py +++ /dev/null @@ -1,108 +0,0 @@ -# MIT License -# -# Copyright 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. - -import SCons.Node.FS -import SCons.Scanner - -def only_dirs(nodes): - is_Dir = lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir) - return [node for node in nodes if is_Dir(node)] - -def DirScanner(**kw): - """Return a prototype Scanner instance for scanning - directories for on-disk files""" - kw['node_factory'] = SCons.Node.FS.Entry - kw['recursive'] = only_dirs - return SCons.Scanner.Base(scan_on_disk, "DirScanner", **kw) - -def DirEntryScanner(**kw): - """Return a prototype Scanner instance for "scanning" - directory Nodes for their in-memory entries""" - kw['node_factory'] = SCons.Node.FS.Entry - kw['recursive'] = None - return SCons.Scanner.Base(scan_in_memory, "DirEntryScanner", **kw) - -skip_entry = {} - -skip_entry_list = [ - '.', - '..', - '.sconsign', - # Used by the native dblite.py module. - '.sconsign.dblite', - # Used by dbm and dumbdbm. - '.sconsign.dir', - # Used by dbm. - '.sconsign.pag', - # Used by dumbdbm. - '.sconsign.dat', - '.sconsign.bak', - # Used by some dbm emulations using Berkeley DB. - '.sconsign.db', -] - -for skip in skip_entry_list: - skip_entry[skip] = 1 - skip_entry[SCons.Node.FS._my_normcase(skip)] = 1 - -do_not_scan = lambda k: k not in skip_entry - -def scan_on_disk(node, env, path=()): - """ - Scans a directory for on-disk files and directories therein. - - Looking up the entries will add these to the in-memory Node tree - representation of the file system, so all we have to do is just - that and then call the in-memory scanning function. - """ - try: - flist = node.fs.listdir(node.get_abspath()) - except (IOError, OSError): - return [] - e = node.Entry - for f in filter(do_not_scan, flist): - # Add ./ to the beginning of the file name so if it begins with a - # '#' we don't look it up relative to the top-level directory. - e('./' + f) - return scan_in_memory(node, env, path) - -def scan_in_memory(node, env, path=()): - """ - "Scans" a Node.FS.Dir for its in-memory entries. - """ - try: - entries = node.entries - except AttributeError: - # It's not a Node.FS.Dir (or doesn't look enough like one for - # our purposes), which can happen if a target list containing - # mixed Node types (Dirs and Files, for example) has a Dir as - # the first entry. - return [] - entry_list = sorted(filter(do_not_scan, list(entries.keys()))) - return [entries[n] for n in entry_list] - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/Fortran.py b/scons/scons-local-4.1.0/SCons/Scanner/Fortran.py deleted file mode 100644 index 18e5082c0..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/Fortran.py +++ /dev/null @@ -1,319 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for Fortran code.""" - -import re - -import SCons.Node -import SCons.Node.FS -import SCons.Scanner -import SCons.Util -import SCons.Warnings - -class F90Scanner(SCons.Scanner.Classic): - """ - A Classic Scanner subclass for Fortran source files which takes - into account both USE and INCLUDE statements. This scanner will - work for both F77 and F90 (and beyond) compilers. - - Currently, this scanner assumes that the include files do not contain - USE statements. To enable the ability to deal with USE statements - in include files, add logic right after the module names are found - to loop over each include file, search for and locate each USE - statement, and append each module name to the list of dependencies. - Caching the search results in a common dictionary somewhere so that - the same include file is not searched multiple times would be a - smart thing to do. - """ - - def __init__(self, name, suffixes, path_variable, - use_regex, incl_regex, def_regex, *args, **kw): - - self.cre_use = re.compile(use_regex, re.M) - self.cre_incl = re.compile(incl_regex, re.M) - self.cre_def = re.compile(def_regex, re.M) - - def _scan(node, env, path, self=self): - node = node.rfile() - - if not node.exists(): - return [] - - return self.scan(node, env, path) - - kw['function'] = _scan - kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable) - kw['recursive'] = 1 - kw['skeys'] = suffixes - kw['name'] = name - - SCons.Scanner.Current.__init__(self, *args, **kw) - - def scan(self, node, env, path=()): - - # cache the includes list in node so we only scan it once: - if node.includes is not None: - mods_and_includes = node.includes - else: - # retrieve all included filenames - includes = self.cre_incl.findall(node.get_text_contents()) - # retrieve all USE'd module names - modules = self.cre_use.findall(node.get_text_contents()) - # retrieve all defined module names - defmodules = self.cre_def.findall(node.get_text_contents()) - - # Remove all USE'd module names that are defined in the same file - # (case-insensitively) - d = {} - for m in defmodules: - d[m.lower()] = 1 - modules = [m for m in modules if m.lower() not in d] - - # Convert module name to a .mod filename - suffix = env.subst('$FORTRANMODSUFFIX') - modules = [x.lower() + suffix for x in modules] - # Remove unique items from the list - mods_and_includes = SCons.Util.unique(includes+modules) - node.includes = mods_and_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 USE or INCLUDE line, 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() - if callable(path): - path = path() - for dep in mods_and_includes: - n, i = self.find_include(dep, source_dir, path) - - if n is None: - SCons.Warnings.warn(SCons.Warnings.DependencyWarning, - "No dependency generated for file: %s (referenced by: %s) -- file not found" % (i, node)) - else: - sortkey = self.sort_key(dep) - nodes.append((sortkey, n)) - - return [pair[1] for pair in sorted(nodes)] - -def FortranScan(path_variable="FORTRANPATH"): - """Return a prototype Scanner instance for scanning source files - for Fortran USE & INCLUDE statements""" - -# The USE statement regex matches the following: -# -# USE module_name -# USE :: module_name -# USE, INTRINSIC :: module_name -# USE, NON_INTRINSIC :: module_name -# -# Limitations -# -# -- While the regex can handle multiple USE statements on one line, -# it cannot properly handle them if they are commented out. -# In either of the following cases: -# -# ! USE mod_a ; USE mod_b [entire line is commented out] -# USE mod_a ! ; USE mod_b [in-line comment of second USE statement] -# -# the second module name (mod_b) will be picked up as a dependency -# even though it should be ignored. The only way I can see -# to rectify this would be to modify the scanner to eliminate -# the call to re.findall, read in the contents of the file, -# treating the comment character as an end-of-line character -# in addition to the normal linefeed, loop over each line, -# weeding out the comments, and looking for the USE statements. -# One advantage to this is that the regex passed to the scanner -# would no longer need to match a semicolon. -# -# -- I question whether or not we need to detect dependencies to -# INTRINSIC modules because these are built-in to the compiler. -# If we consider them a dependency, will SCons look for them, not -# find them, and kill the build? Or will we there be standard -# compiler-specific directories we will need to point to so the -# compiler and SCons can locate the proper object and mod files? - -# Here is a breakdown of the regex: -# -# (?i) : regex is case insensitive -# ^ : start of line -# (?: : group a collection of regex symbols without saving the match as a "group" -# ^|; : matches either the start of the line or a semicolon - semicolon -# ) : end the unsaved grouping -# \s* : any amount of white space -# USE : match the string USE, case insensitive -# (?: : group a collection of regex symbols without saving the match as a "group" -# \s+| : match one or more whitespace OR .... (the next entire grouped set of regex symbols) -# (?: : group a collection of regex symbols without saving the match as a "group" -# (?: : establish another unsaved grouping of regex symbols -# \s* : any amount of white space -# , : match a comma -# \s* : any amount of white space -# (?:NON_)? : optionally match the prefix NON_, case insensitive -# INTRINSIC : match the string INTRINSIC, case insensitive -# )? : optionally match the ", INTRINSIC/NON_INTRINSIC" grouped expression -# \s* : any amount of white space -# :: : match a double colon that must appear after the INTRINSIC/NON_INTRINSIC attribute -# ) : end the unsaved grouping -# ) : end the unsaved grouping -# \s* : match any amount of white space -# (\w+) : match the module name that is being USE'd -# -# - use_regex = r"(?i)(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)" - - -# The INCLUDE statement regex matches the following: -# -# INCLUDE 'some_Text' -# INCLUDE "some_Text" -# INCLUDE "some_Text" ; INCLUDE "some_Text" -# INCLUDE kind_"some_Text" -# INCLUDE kind_'some_Text" -# -# where some_Text can include any alphanumeric and/or special character -# as defined by the Fortran 2003 standard. -# -# Limitations: -# -# -- The Fortran standard dictates that a " or ' in the INCLUDE'd -# string must be represented as a "" or '', if the quotes that wrap -# the entire string are either a ' or ", respectively. While the -# regular expression below can detect the ' or " characters just fine, -# the scanning logic, presently is unable to detect them and reduce -# them to a single instance. This probably isn't an issue since, -# in practice, ' or " are not generally used in filenames. -# -# -- This regex will not properly deal with multiple INCLUDE statements -# when the entire line has been commented out, ala -# -# ! INCLUDE 'some_file' ; INCLUDE 'some_file' -# -# In such cases, it will properly ignore the first INCLUDE file, -# but will actually still pick up the second. Interestingly enough, -# the regex will properly deal with these cases: -# -# INCLUDE 'some_file' -# INCLUDE 'some_file' !; INCLUDE 'some_file' -# -# To get around the above limitation, the FORTRAN programmer could -# simply comment each INCLUDE statement separately, like this -# -# ! INCLUDE 'some_file' !; INCLUDE 'some_file' -# -# The way I see it, the only way to get around this limitation would -# be to modify the scanning logic to replace the calls to re.findall -# with a custom loop that processes each line separately, throwing -# away fully commented out lines before attempting to match against -# the INCLUDE syntax. -# -# Here is a breakdown of the regex: -# -# (?i) : regex is case insensitive -# (?: : begin a non-saving group that matches the following: -# ^ : either the start of the line -# | : or -# ['">]\s*; : a semicolon that follows a single quote, -# double quote or greater than symbol (with any -# amount of whitespace in between). This will -# allow the regex to match multiple INCLUDE -# statements per line (although it also requires -# the positive lookahead assertion that is -# used below). It will even properly deal with -# (i.e. ignore) cases in which the additional -# INCLUDES are part of an in-line comment, ala -# " INCLUDE 'someFile' ! ; INCLUDE 'someFile2' " -# ) : end of non-saving group -# \s* : any amount of white space -# INCLUDE : match the string INCLUDE, case insensitive -# \s+ : match one or more white space characters -# (?\w+_)? : match the optional "kind-param _" prefix allowed by the standard -# [<"'] : match the include delimiter - an apostrophe, double quote, or less than symbol -# (.+?) : match one or more characters that make up -# the included path and file name and save it -# in a group. The Fortran standard allows for -# any non-control character to be used. The dot -# operator will pick up any character, including -# control codes, but I can't conceive of anyone -# putting control codes in their file names. -# The question mark indicates it is non-greedy so -# that regex will match only up to the next quote, -# double quote, or greater than symbol -# (?=["'>]) : positive lookahead assertion to match the include -# delimiter - an apostrophe, double quote, or -# greater than symbol. This level of complexity -# is required so that the include delimiter is -# not consumed by the match, thus allowing the -# sub-regex discussed above to uniquely match a -# set of semicolon-separated INCLUDE statements -# (as allowed by the F2003 standard) - - include_regex = r"""(?i)(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])""" - -# The MODULE statement regex finds module definitions by matching -# the following: -# -# MODULE module_name -# -# but *not* the following: -# -# MODULE PROCEDURE procedure_name -# MODULE SUBROUTINE subroutine_name -# MODULE FUNCTION function_name -# MODULE PURE SUBROUTINE|FUNCTION subroutine_name|function_name -# MODULE ELEMENTAL SUBROUTINE|FUNCTION subroutine_name|function_name -# -# Here is a breakdown of the regex: -# -# (?i) : regex is case insensitive -# ^\s* : any amount of white space -# MODULE : match the string MODULE, case -# insensitive -# \s+ : match one or more white space -# characters -# (?!PROCEDURE|SUBROUTINE|FUNCTION|PURE|ELEMENTAL) -# : but *don't* match if the next word -# matches PROCEDURE, SUBROUTINE, -# FUNCTION, PURE or ELEMENTAL (negative -# lookahead assertion), case insensitive -# (\w+) : match one or more alphanumeric -# characters that make up the defined -# module name and save it in a group - - def_regex = r"""(?i)^\s*MODULE\s+(?!PROCEDURE|SUBROUTINE|FUNCTION|PURE|ELEMENTAL)(\w+)""" - - scanner = F90Scanner("FortranScan", - "$FORTRANSUFFIXES", - path_variable, - use_regex, - include_regex, - def_regex) - return scanner - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/IDL.py b/scons/scons-local-4.1.0/SCons/Scanner/IDL.py deleted file mode 100644 index 418608f6f..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/IDL.py +++ /dev/null @@ -1,43 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for IDL (Interface Definition Language) files.""" - -import SCons.Node.FS -import SCons.Scanner - -def IDLScan(): - """Return a prototype Scanner instance for scanning IDL source files""" - cs = SCons.Scanner.ClassicCPP( - "IDLScan", - "$IDLSUFFIXES", - "CPPPATH", - r'^[ \t]*(?:#[ \t]*include|[ \t]*import)[ \t]+(<|")([^>"]+)(>|")', - ) - return cs - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/LaTeX.py b/scons/scons-local-4.1.0/SCons/Scanner/LaTeX.py deleted file mode 100644 index 73f003580..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/LaTeX.py +++ /dev/null @@ -1,423 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for LaTeX code.""" - -import os.path -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'] -LatexGraphics = [ '.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]): - env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]]) - else: - # Split at os.pathsep to convert into absolute path - env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(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]): - env['ENV'][var] = os.pathsep.join(env['ENV'][var]) - # 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 E{*}PATH variable name to a function that - will return all of the E{*}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['TEXINPUTS'] for "lstinputlisting" keyword - env['BIBINPUTS'] for "bibliography" keyword - env['BSTINPUTS'] for "bibliographystyle" keyword - env['INDEXSTYLE'] for "makeindex" keyword, no scanning support needed just allows user to set it if needed. - - 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', - 'addbibresource': 'BIBINPUTS', - 'addglobalbib': 'BIBINPUTS', - 'addsectionbib': 'BIBINPUTS', - 'makeindex': 'INDEXSTYLE', - 'usepackage': 'TEXINPUTS', - 'lstinputlisting': 'TEXINPUTS'} - env_variables = SCons.Util.unique(list(keyword_paths.values())) - two_arg_commands = ['import', 'subimport', - 'includefrom', 'subincludefrom', - 'inputfrom', 'subinputfrom'] - - def __init__(self, name, suffixes, graphics_extensions, *args, **kw): - regex = r''' - \\( - include - | includegraphics(?:\s*\[[^\]]+\])? - | lstinputlisting(?:\[[^\]]+\])? - | input - | import - | subimport - | includefrom - | subincludefrom - | inputfrom - | subinputfrom - | bibliography - | addbibresource - | addglobalbib - | addsectionbib - | usepackage - ) - \s*{([^}]*)} # first arg - (?: \s*{([^}]*)} )? # maybe another arg - ''' - self.cre = re.compile(regex, re.M | re.X) - self.comment_re = re.compile(r'^((?:(?:\\%)|[^%\n])*)(.*)$', 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_recurse(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'] = 0 - kw['skeys'] = suffixes - kw['scan_check'] = LaTeXScanCheck(suffixes) - kw['name'] = name - - SCons.Scanner.Base.__init__(self, *args, **kw) - - def _latex_names(self, include_type, filename): - if include_type == 'input': - base, ext = os.path.splitext( filename ) - if ext == "": - return [filename + '.tex'] - if include_type in ('include', 'import', 'subimport', - 'includefrom', 'subincludefrom', - 'inputfrom', 'subinputfrom'): - base, ext = os.path.splitext( filename ) - if ext == "": - return [filename + '.tex'] - if include_type == 'bibliography': - base, ext = os.path.splitext( filename ) - if ext == "": - return [filename + '.bib'] - if include_type == 'usepackage': - base, ext = os.path.splitext( filename ) - if ext == "": - return [filename + '.sty'] - if include_type == 'includegraphics': - base, ext = os.path.splitext( filename ) - if ext == "": - #return [filename+e for e in self.graphics_extensions + TexGraphics] - # use the line above to find dependencies for the PDF builder - # when only an .eps figure is present. Since it will be found - # if the user tells scons how to make the pdf figure, leave - # it out for now. - return [filename+e for e in 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): - inc_type, inc_subdir, inc_filename = include - try: - sub_paths = path[inc_type] - except (IndexError, KeyError): - sub_paths = ((), ()) - try_names = self._latex_names(inc_type, inc_filename) - - # There are three search paths to try: - # 1. current directory "source_dir" - # 2. env[var] - # 3. env['ENV'][var] - search_paths = [(source_dir,)] + list(sub_paths) - - for n in try_names: - for search_path in search_paths: - paths = tuple([d.Dir(inc_subdir) for d in search_path]) - i = SCons.Node.FS.find_file(n, paths) - if i: - return i, include - return None, include - - def canonical_text(self, text): - """Standardize an input TeX-file contents. - - Currently: - * removes comments, unwrapping comment-wrapped lines. - """ - out = [] - line_continues_a_comment = False - for line in text.splitlines(): - line,comment = self.comment_re.findall(line)[0] - if line_continues_a_comment: - out[-1] = out[-1] + line.lstrip() - else: - out.append(line) - line_continues_a_comment = len(comment) > 0 - return '\n'.join(out).rstrip()+'\n' - - def scan(self, node, subdir='.'): - # 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)) - # add option for whitespace (\s) before the '[' - noopt_cre = re.compile(r'\s*\[.*$') - if node.includes is not None: - includes = node.includes - else: - text = self.canonical_text(node.get_text_contents()) - includes = self.cre.findall(text) - # 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_subdir = subdir - if inc_type in self.two_arg_commands: - inc_subdir = os.path.join(subdir, include[1]) - inc_list = include[2].split(',') - else: - inc_list = include[1].split(',') - for inc in inc_list: - split_includes.append((inc_type, inc_subdir, inc)) - - includes = split_includes - node.includes = includes - - return includes - - def scan_recurse(self, node, path=()): - """ do a recursive scan of the top level target file - This lets us search for included files based on the - directory of the main file just as latex does""" - - path_dict = dict(list(path)) - - queue = [] - queue.extend( self.scan(node) ) - seen = {} - - # 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: - while queue: - - include = queue.pop() - inc_type, inc_subdir, inc_filename = include - - try: - if seen[inc_filename] == 1: - continue - except KeyError: - seen[inc_filename] = 1 - - # - # 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 inc_type != '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)) - # recurse down - queue.extend( self.scan(n, inc_subdir) ) - - return [pair[1] for pair in sorted(nodes)] - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/Prog.py b/scons/scons-local-4.1.0/SCons/Scanner/Prog.py deleted file mode 100644 index 41be1a414..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/Prog.py +++ /dev/null @@ -1,114 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for program files.""" - -import SCons.Node -import SCons.Node.FS -import SCons.Scanner -import SCons.Util - -# global, set by --debug=findlibs -print_find_libs = None - -def ProgramScanner(**kw): - """Return a prototype Scanner instance for scanning executable - files for static-lib dependencies""" - kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH') - ps = SCons.Scanner.Base(scan, "ProgramScanner", **kw) - return ps - -def _subst_libs(env, libs): - """Substitute environment variables and split into list.""" - if SCons.Util.is_String(libs): - libs = env.subst(libs) - if SCons.Util.is_String(libs): - libs = libs.split() - elif SCons.Util.is_Sequence(libs): - _libs = [] - for l in libs: - _libs += _subst_libs(env, l) - libs = _libs - else: - # libs is an object (Node, for example) - libs = [libs] - return libs - -def scan(node, env, libpath = ()): - """Scans program files for static-library dependencies. - - It will search the LIBPATH environment variable - for libraries specified in the LIBS variable, returning any - files it finds as dependencies. - """ - try: - libs = env['LIBS'] - except KeyError: - # There are no LIBS in this environment, so just return a null list: - return [] - - libs = _subst_libs(env, libs) - - try: - prefix = env['LIBPREFIXES'] - if not SCons.Util.is_List(prefix): - prefix = [ prefix ] - except KeyError: - prefix = [ '' ] - - try: - suffix = env['LIBSUFFIXES'] - if not SCons.Util.is_List(suffix): - suffix = [ suffix ] - except KeyError: - suffix = [ '' ] - - pairs = [] - for suf in map(env.subst, suffix): - for pref in map(env.subst, prefix): - pairs.append((pref, suf)) - - result = [] - - if callable(libpath): - libpath = libpath() - - find_file = SCons.Node.FS.find_file - adjustixes = SCons.Util.adjustixes - for lib in libs: - if SCons.Util.is_String(lib): - for pref, suf in pairs: - l = adjustixes(lib, pref, suf) - l = find_file(l, libpath, verbose=print_find_libs) - if l: - result.append(l) - else: - result.append(lib) - - return result - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/Python.py b/scons/scons-local-4.1.0/SCons/Scanner/Python.py deleted file mode 100644 index dc6812c54..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/Python.py +++ /dev/null @@ -1,166 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for Python code. - -One important note about the design is that this does not take any dependencies -upon packages or binaries in the Python installation unless they are listed in -PYTHONPATH. To do otherwise would have required code to determine where the -Python installation is, which is outside of the scope of a scanner like this. -If consumers want to pick up dependencies upon these packages, they must put -those directories in PYTHONPATH. - -""" - -import itertools -import os -import re -import SCons.Scanner - -# Capture python "from a import b" and "import a" statements. -from_cre = re.compile(r'^\s*from\s+([^\s]+)\s+import\s+(.*)', re.M) -import_cre = re.compile(r'^\s*import\s+([^\s]+)', re.M) - - -def path_function(env, dir=None, target=None, source=None, argument=None): - """Retrieves a tuple with all search paths.""" - paths = env['ENV'].get('PYTHONPATH', '').split(os.pathsep) - if source: - paths.append(source[0].dir.abspath) - return tuple(paths) - - -def find_include_names(node): - """Scans the node for all imports. - - Returns a list of tuples. Each tuple has two elements: - 1. The main import (e.g. module, module.file, module.module2) - 2. Additional optional imports that could be functions or files - in the case of a "from X import Y" statement. In the case of a - normal "import" statement, this is None. - """ - text = node.get_text_contents() - all_matches = [] - matches = from_cre.findall(text) - if matches: - for match in matches: - imports = [i.strip() for i in match[1].split(',')] - - # Add some custom logic to strip out "as" because the regex - # includes it. - last_import_split = imports[-1].split() - if len(last_import_split) > 1: - imports[-1] = last_import_split[0] - - all_matches.append((match[0], imports)) - - matches = import_cre.findall(text) - if matches: - for match in matches: - all_matches.append((match, None)) - - return all_matches - - -def scan(node, env, path=()): - # cache the includes list in node so we only scan it once: - if node.includes is not None: - includes = node.includes - else: - includes = find_include_names(node) - # Intern the names of the include files. Saves some memory - # if the same header is included many times. - node.includes = list(map(SCons.Util.silent_intern, includes)) - - # XXX TODO: Sort? - nodes = [] - if callable(path): - path = path() - for module, imports in includes: - is_relative = module.startswith('.') - if is_relative: - # This is a relative include, so we must ignore PYTHONPATH. - module_lstripped = module.lstrip('.') - # One dot is current directory, two is parent, three is - # grandparent, etc. - num_parents = len(module) - len(module_lstripped) - 1 - current_dir = node.get_dir() - for i in itertools.repeat(None, num_parents): - current_dir = current_dir.up() - - search_paths = [current_dir.abspath] - search_string = module_lstripped - else: - search_paths = path - search_string = module - - module_components = search_string.split('.') - for search_path in search_paths: - candidate_path = os.path.join(search_path, *module_components) - # The import stored in "module" could refer to a directory or file. - import_dirs = [] - if os.path.isdir(candidate_path): - import_dirs = module_components - - # Because this resolved to a directory, there is a chance that - # additional imports (e.g. from module import A, B) could refer - # to files to import. - if imports: - for imp in imports: - file = os.path.join(candidate_path, imp + '.py') - if os.path.isfile(file): - nodes.append(file) - elif os.path.isfile(candidate_path + '.py'): - nodes.append(candidate_path + '.py') - import_dirs = module_components[:-1] - - # We can ignore imports because this resolved to a file. Any - # additional imports (e.g. from module.file import A, B) would - # only refer to functions in this file. - - # Take a dependency on all __init__.py files from all imported - # packages unless it's a relative import. If it's a relative - # import, we don't need to take the dependency because Python - # requires that all referenced packages have already been imported, - # which means that the dependency has already been established. - if import_dirs and not is_relative: - for i in range(len(import_dirs)): - init_components = module_components[:i+1] + ['__init__.py'] - init_path = os.path.join(search_path, *(init_components)) - if os.path.isfile(init_path): - nodes.append(init_path) - break - - return sorted(nodes) - - -PythonSuffixes = ['.py'] -PythonScanner = SCons.Scanner.Base(scan, name='PythonScanner', - skeys=PythonSuffixes, - path_function=path_function, recursive=1) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/RC.py b/scons/scons-local-4.1.0/SCons/Scanner/RC.py deleted file mode 100644 index 12e431d6b..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/RC.py +++ /dev/null @@ -1,57 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for RC (Interface Definition Language) files.""" - - -import SCons.Node.FS -import SCons.Scanner - - -def no_tlb(nodes): - """Filter out .tlb files as they are binary and shouldn't be scanned.""" - - # print("Nodes:%s"%[str(n) for n in nodes]) - return [n for n in nodes if str(n)[-4:] != '.tlb'] - - -def RCScan(): - """Return a prototype Scanner instance for scanning RC source files""" - - res_re = ( - r'^(?:\s*#\s*(?:include)|' - r'.*?\s+(?:ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)' - r'\s*.*?)' - r'\s*(<|"| )([^>"\s]+)(?:[>"\s])*$' - ) - resScanner = SCons.Scanner.ClassicCPP( - "ResourceScanner", "$RCSUFFIXES", "CPPPATH", res_re, recursive=no_tlb - ) - - return resScanner - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/SWIG.py b/scons/scons-local-4.1.0/SCons/Scanner/SWIG.py deleted file mode 100644 index 5a60c7444..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/SWIG.py +++ /dev/null @@ -1,39 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Dependency scanner for SWIG code.""" - -import SCons.Scanner - -SWIGSuffixes = [ '.i' ] - -def SWIGScanner(): - expr = r'^[ \t]*%[ \t]*(?:include|import|extern)[ \t]*(<|"?)([^>\s"]+)(?:>|"?)' - scanner = SCons.Scanner.ClassicCPP("SWIGScanner", ".i", "SWIGPATH", expr) - return scanner - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Scanner/__init__.py b/scons/scons-local-4.1.0/SCons/Scanner/__init__.py deleted file mode 100644 index d98f65154..000000000 --- a/scons/scons-local-4.1.0/SCons/Scanner/__init__.py +++ /dev/null @@ -1,417 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""The Scanner package for the SCons software construction utility.""" - -import re - -import SCons.Node.FS -import SCons.Util - - -class _Null: - pass - -# This is used instead of None as a default argument value so None can be -# used as an actual argument value. -_null = _Null - -def Scanner(function, *args, **kw): - """Factory function to create a Scanner Object. - - Creates the appropriate Scanner based on the type of "function". - - TODO: Deprecate this some day. We've moved the functionality - inside the Base class and really don't need this factory function - any more. It was, however, used by some of our Tool modules, so - the call probably ended up in various people's custom modules - patterned on SCons code. - - """ - if SCons.Util.is_Dict(function): - return Selector(function, *args, **kw) - else: - return Base(function, *args, **kw) - - -class FindPathDirs: - """Class to bind a specific E{*}PATH variable name to a function that - will return all of the E{*}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[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)) - - - -class Base: - """Base class for dependency scanners. - - This implements straightforward, single-pass scanning of a single file. - """ - def __init__( - self, - function, - name="NONE", - argument=_null, - skeys=_null, - path_function=None, - # Node.FS.Base so that, by default, it's okay for a - # scanner to return a Dir, File or Entry. - node_class=SCons.Node.FS.Base, - node_factory=None, - scan_check=None, - recursive=None, - ): - """Construct a new scanner object given a scanner function. - - The scanner function's first argument will be a Node that should - be scanned for dependencies, the second argument will be an - Environment object, the third argument will be the tuple of paths - returned by the path_function, and the fourth argument will be - the value passed into 'argument', and the returned list should - contain the Nodes for all the direct dependencies of the file. - - Examples: - - s = Scanner(my_scanner_function) - s = Scanner(function = my_scanner_function) - s = Scanner(function = my_scanner_function, argument = 'foo') - - Args: - function: a scanner function taking two or three arguments - and returning a list of strings. - - name: a name for identifying this scanner object. - - argument: an optional argument that, if specified, will be - passed to both the scanner function and the path_function. - - skeys: an optional list argument that can be used - to determine which scanner should be used for a given - Node. In the case of File nodes, for example, the 'skeys' - would be file suffixes. - - path_function: a function that takes four or five arguments - (a construction environment, Node for the directory - containing the SConscript file that defined the primary - target, list of target nodes, list of source nodes, and - optional argument for this instance) and returns a tuple - of the directories that can be searched for implicit - dependency files. May also return a callable() which - is called with no args and returns the tuple (supporting - Bindable class). - - node_class: the class of Nodes which this scan will return. - If node_class is None, then this scanner will not enforce - any Node conversion and will return the raw results from - the underlying scanner function. - - node_factory: the factory function to be called to - translate the raw results returned by the scanner function - into the expected node_class objects. - - scan_check: a function to be called to first check whether - this node really needs to be scanned. - - recursive: specifies that this scanner should be invoked - recursively on all of the implicit dependencies it returns - (the canonical example being #include lines in C source - files). May be a callable, which will be called to filter - the list of nodes found to select a subset for recursive - scanning (the canonical example being only recursively - scanning subdirectories within a directory). - - """ - # Note: this class could easily work with scanner functions that take - # something other than a filename as an argument (e.g. a database - # node) and a dependencies list that aren't file names. All that - # would need to be changed is the documentation. - - self.function = function - self.path_function = path_function - self.name = name - self.argument = argument - - if skeys is _null: - if SCons.Util.is_Dict(function): - skeys = list(function.keys()) - else: - skeys = [] - self.skeys = skeys - - self.node_class = node_class - self.node_factory = node_factory - self.scan_check = scan_check - if callable(recursive): - self.recurse_nodes = recursive - elif recursive: - self.recurse_nodes = self._recurse_all_nodes - else: - self.recurse_nodes = self._recurse_no_nodes - - def path(self, env, dir=None, target=None, source=None): - if not self.path_function: - return () - if self.argument is not _null: - return self.path_function(env, dir, target, source, self.argument) - else: - return self.path_function(env, dir, target, source) - - def __call__(self, node, env, path=()): - """Scans a single object. - - Args: - node: the node that will be passed to the scanner function - env: the environment that will be passed to the scanner function. - - Returns: - A list of direct dependency nodes for the specified node. - - """ - if self.scan_check and not self.scan_check(node, env): - return [] - - self = self.select(node) - - if self.argument is not _null: - node_list = self.function(node, env, path, self.argument) - else: - node_list = self.function(node, env, path) - - kw = {} - if hasattr(node, 'dir'): - kw['directory'] = node.dir - node_factory = env.get_factory(self.node_factory) - nodes = [] - for l in node_list: - if self.node_class and not isinstance(l, self.node_class): - l = node_factory(l, **kw) - nodes.append(l) - return nodes - - def __eq__(self, other): - try: - return self.__dict__ == other.__dict__ - except AttributeError: - # other probably doesn't have a __dict__ - return self.__dict__ == other - - def __hash__(self): - return id(self) - - def __str__(self): - return self.name - - def add_skey(self, skey): - """Add a skey to the list of skeys""" - self.skeys.append(skey) - - def get_skeys(self, env=None): - if env and SCons.Util.is_String(self.skeys): - return env.subst_list(self.skeys)[0] - return self.skeys - - def select(self, node): - if SCons.Util.is_Dict(self.function): - key = node.scanner_key() - try: - return self.function[key] - except KeyError: - return None - else: - return self - - def _recurse_all_nodes(self, nodes): - return nodes - - def _recurse_no_nodes(self, nodes): - return [] - - # recurse_nodes = _recurse_no_nodes - - def add_scanner(self, skey, scanner): - self.function[skey] = scanner - self.add_skey(skey) - - -class Selector(Base): - """ - A class for selecting a more specific scanner based on the - scanner_key() (suffix) for a specific Node. - - TODO: This functionality has been moved into the inner workings of - the Base class, and this class will be deprecated at some point. - (It was never exposed directly as part of the public interface, - although it is used by the Scanner() factory function that was - used by various Tool modules and therefore was likely a template - for custom modules that may be out there.) - """ - def __init__(self, dict, *args, **kw): - Base.__init__(self, None, *args, **kw) - self.dict = dict - self.skeys = list(dict.keys()) - - def __call__(self, node, env, path=()): - return self.select(node)(node, env, path) - - def select(self, node): - try: - return self.dict[node.scanner_key()] - except KeyError: - return None - - def add_scanner(self, skey, scanner): - self.dict[skey] = scanner - self.add_skey(skey) - - -class Current(Base): - """ - A class for scanning files that are source files (have no builder) - or are derived files and are current (which implies that they exist, - either locally or in a repository). - """ - - def __init__(self, *args, **kw): - def current_check(node, env): - return not node.has_builder() or node.is_up_to_date() - kw['scan_check'] = current_check - Base.__init__(self, *args, **kw) - -class Classic(Current): - """ - A Scanner subclass to contain the common logic for classic CPP-style - include scanning, but which can be customized to use different - regular expressions to find the includes. - - Note that in order for this to work "out of the box" (without - overriding the find_include() and sort_key() methods), the regular - expression passed to the constructor must return the name of the - include file in group 0. - """ - - def __init__(self, name, suffixes, path_variable, regex, *args, **kw): - - self.cre = re.compile(regex, re.M) - - def _scan(node, _, path=(), self=self): - node = node.rfile() - if not node.exists(): - return [] - return self.scan(node, path) - - kw['function'] = _scan - kw['path_function'] = FindPathDirs(path_variable) - - # Allow recursive to propagate if child class specifies. - # In this case resource scanner needs to specify a filter on which files - # get recursively processed. Previously was hardcoded to 1 instead of - # defaulted to 1. - kw['recursive'] = kw.get('recursive', 1) - kw['skeys'] = suffixes - kw['name'] = name - - Current.__init__(self, *args, **kw) - - def find_include(self, include, source_dir, path): - n = SCons.Node.FS.find_file(include, (source_dir,) + tuple(path)) - return n, include - - def sort_key(self, include): - return SCons.Node.FS._my_normcase(include) - - def find_include_names(self, node): - return self.cre.findall(node.get_text_contents()) - - def scan(self, node, path=()): - - # cache the includes list in node so we only scan it once: - if node.includes is not None: - includes = node.includes - else: - includes = self.find_include_names(node) - # Intern the names of the include files. Saves some memory - # if the same header is included many times. - node.includes = list(map(SCons.Util.silent_intern, 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() - if callable(path): - path = path() - for include in includes: - n, i = self.find_include(include, 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: - nodes.append((self.sort_key(include), n)) - - return [pair[1] for pair in sorted(nodes)] - -class ClassicCPP(Classic): - """ - A Classic Scanner subclass which takes into account the type of - bracketing used to include the file, and uses classic CPP rules - for searching for the files based on the bracketing. - - Note that in order for this to work, the regular expression passed - to the constructor must return the leading bracket in group 0, and - the contained filename in group 1. - """ - def find_include(self, include, source_dir, path): - include = list(map(SCons.Util.to_str, include)) - if include[0] == '"': - paths = (source_dir,) + tuple(path) - else: - paths = tuple(path) + (source_dir,) - - n = SCons.Node.FS.find_file(include[1], paths) - - i = SCons.Util.silent_intern(include[1]) - return n, i - - def sort_key(self, include): - return SCons.Node.FS._my_normcase(' '.join(include)) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Script/Interactive.py b/scons/scons-local-4.1.0/SCons/Script/Interactive.py deleted file mode 100644 index 26a8bcd75..000000000 --- a/scons/scons-local-4.1.0/SCons/Script/Interactive.py +++ /dev/null @@ -1,372 +0,0 @@ -# MIT License -# -# Copyright 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 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 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 = line.strip() - 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 = line.replace('\\', '\\\\') - 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 node not in seen_nodes - return [child for child in node.children(scan=1) if is_unseen(child)] - - 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.get_next() - while n: - n = walker.get_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') - spaces = re.match(' *', lines[0]).group(0) - def strip_spaces(l, spaces=spaces): - if l[:len(spaces)] == spaces: - l = l[len(spaces):] - return l - lines = list(map(strip_spaces, lines)) - return '\n'.join(lines) - - 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: - # Per "[Python-Dev] subprocess insufficiently platform-independent?" - # http://mail.python.org/pipermail/python-dev/2008-August/081979.html "+ - # Doing the right thing with an argument list currently - # requires different shell= values on Windows and Linux. - p = subprocess.Popen(argv, shell=(sys.platform=='win32')) - except EnvironmentError as 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() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Script/Main.py b/scons/scons-local-4.1.0/SCons/Script/Main.py deleted file mode 100644 index 1f2a455e4..000000000 --- a/scons/scons-local-4.1.0/SCons/Script/Main.py +++ /dev/null @@ -1,1446 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""The main() function used by the scons script. - -Architecturally, this *is* the scons script, and will likely only be -called from the external "scons" wrapper. Consequently, anything here -should not be, or be considered, part of the build engine. If it's -something that we expect other software to want to use, it should go in -some other module. If it's specific to the "scons" script invocation, -it goes here. -""" - -# these define the range of versions SCons supports -unsupported_python_version = (3, 4, 0) -deprecated_python_version = (3, 4, 0) - -import SCons.compat - -import atexit -import importlib.util -import os -import re -import sys -import time -import traceback -import sysconfig -import platform -import threading - -import SCons.CacheDir -import SCons.Debug -import SCons.Defaults -import SCons.Environment -import SCons.Errors -import SCons.Job -import SCons.Node -import SCons.Node.FS -import SCons.Platform -import SCons.Platform.virtualenv -import SCons.SConf -import SCons.Script -import SCons.Taskmaster -import SCons.Util -import SCons.Warnings -import SCons.Script.Interactive - -# Global variables -first_command_start = None -last_command_end = None -print_objects = 0 -print_memoizer = 0 -print_stacktrace = 0 -print_time = 0 -print_action_timestamps = 0 -sconscript_time = 0 -cumulative_command_time = 0 -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 = [] - - -def revert_io(): - # This call is added to revert stderr and stdout to the original - # ones just in case some build rule or something else in the system - # has redirected them elsewhere. - sys.stderr = sys.__stderr__ - sys.stdout = sys.__stdout__ - - -class SConsPrintHelpException(Exception): - pass - - -display = SCons.Util.display -progress_display = SCons.Util.DisplayEngine() - - -class Progressor: - prev = '' - count = 0 - target_string = '$TARGET' - - def __init__(self, obj, interval=1, file=None, overwrite=False): - if file is None: - file = sys.stdout - - self.obj = obj - self.file = file - self.interval = interval - self.overwrite = overwrite - - if callable(obj): - self.func = obj - elif SCons.Util.is_List(obj): - self.func = self.spinner - elif obj.find(self.target_string) != -1: - self.func = self.replace_string - else: - self.func = self.string - - def write(self, s): - self.file.write(s) - self.file.flush() - self.prev = s - - def erase_previous(self): - if self.prev: - length = len(self.prev) - if self.prev[-1] in ('\n', '\r'): - length = length - 1 - self.write(' ' * length + '\r') - self.prev = '' - - def spinner(self, node): - self.write(self.obj[self.count % len(self.obj)]) - - def string(self, node): - self.write(self.obj) - - def replace_string(self, node): - self.write(self.obj.replace(self.target_string, str(node))) - - def __call__(self, node): - self.count = self.count + 1 - if (self.count % self.interval) == 0: - if self.overwrite: - self.erase_previous() - self.func(node) - -ProgressObject = SCons.Util.Null() - -def Progress(*args, **kw): - global ProgressObject - ProgressObject = Progressor(*args, **kw) - -# Task control. -# - -_BuildFailures = [] - - -def GetBuildFailures(): - return _BuildFailures - - -class BuildTask(SCons.Taskmaster.OutOfDateTask): - """An SCons build task.""" - progress = ProgressObject - - def display(self, message): - display('scons: ' + message) - - def prepare(self): - self.progress(self.targets[0]) - return SCons.Taskmaster.OutOfDateTask.prepare(self) - - def needs_execute(self): - if SCons.Taskmaster.OutOfDateTask.needs_execute(self): - return True - if self.top and self.targets[0].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.OutOfDateTask.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 - if print_action_timestamps: - sys.stdout.write("Command execution start timestamp: %s: %f\n"%(str(self.node), start_time)) - sys.stdout.write("Command execution end timestamp: %s: %f\n"%(str(self.node), finish_time)) - sys.stdout.write("Command execution time: %s: %f seconds\n"%(str(self.node), 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.OutOfDateTask.executed(self) - elif self.options.keep_going: - SCons.Taskmaster.OutOfDateTask.fail_continue(self) - exit_status = status - this_build_status = status - else: - SCons.Taskmaster.OutOfDateTask.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(): - if t.__class__.__name__ in ('File', 'Dir', 'Entry'): - errstr="Do not know how to make %s target `%s' (%s)." % (t.__class__.__name__, t, t.get_abspath()) - else: # Alias or Python or ... - errstr="Do not know how to make %s target `%s'." % (t.__class__.__name__, 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) - SCons.Taskmaster.OutOfDateTask.executed(self) - else: - SCons.Taskmaster.OutOfDateTask.executed(self) - - def failed(self): - # Handle the failure of a build task. The primary purpose here - # is to display the various types of Errors and Exceptions - # appropriately. - 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. - 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 - - 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 = ', '.join(map(str, node)) - - errfmt = "scons: *** [%s] %s\n" - sys.stderr.write(errfmt % (nodename, buildError)) - - if (buildError.exc_info[2] and buildError.exc_info[1] and - not isinstance( - buildError.exc_info[1], - (EnvironmentError, SCons.Errors.StopError, - SCons.Errors.UserError))): - type, value, trace = buildError.exc_info - if tb and print_stacktrace: - sys.stderr.write("scons: internal stack trace:\n") - traceback.print_tb(tb, file=sys.stderr) - traceback.print_exception(type, value, trace) - elif tb and print_stacktrace: - sys.stderr.write("scons: internal stack trace:\n") - traceback.print_tb(tb, file=sys.stderr) - - self.exception = (e, buildError, tb) # type, value, traceback - self.do_failed(buildError.exitstatus) - - self.exc_clear() - - def postprocess(self): - if self.top: - t = self.targets[0] - for tp in self.options.tree_printers: - tp.display(t) - if self.options.debug_includes: - tree = t.render_include_tree() - if tree: - print() - print(tree) - SCons.Taskmaster.OutOfDateTask.postprocess(self) - - def make_ready(self): - """Make a task ready for execution""" - SCons.Taskmaster.OutOfDateTask.make_ready(self) - if self.out_of_date and self.options.debug_explain: - explanation = self.out_of_date[0].explain() - if explanation: - sys.stdout.write("scons: " + explanation) - - -class CleanTask(SCons.Taskmaster.AlwaysTask): - """An SCons clean task.""" - def fs_delete(self, path, pathstr, remove=True): - try: - if os.path.lexists(path): - if os.path.isfile(path) or os.path.islink(path): - if remove: os.unlink(path) - display("Removed " + pathstr) - elif os.path.isdir(path) and not os.path.islink(path): - # delete everything in the dir - for e in sorted(os.listdir(path)): - p = os.path.join(path, e) - s = os.path.join(pathstr, e) - if os.path.isfile(p): - if remove: os.unlink(p) - display("Removed " + s) - else: - self.fs_delete(p, s, remove) - # then delete dir itself - if remove: os.rmdir(path) - display("Removed directory " + pathstr) - else: - errstr = "Path '%s' exists but isn't a file or directory." - raise SCons.Errors.UserError(errstr % pathstr) - except SCons.Errors.UserError as e: - print(e) - except (IOError, OSError) as e: - print("scons: Could not remove '%s':" % pathstr, e.strerror) - - def _get_files_to_clean(self): - result = [] - target = self.targets[0] - if target.has_builder() or target.side_effect: - result = [t for t in self.targets if not t.noclean] - return result - - def _clean_targets(self, remove=True): - target = self.targets[0] - if target in SCons.Environment.CleanTargets: - files = SCons.Environment.CleanTargets[target] - for f in files: - self.fs_delete(f.get_abspath(), str(f), remove) - - def show(self): - for t in self._get_files_to_clean(): - if not t.isdir(): - display("Removed " + str(t)) - self._clean_targets(remove=False) - - def remove(self): - for t in self._get_files_to_clean(): - try: - removed = t.remove() - except OSError as e: - # An OSError may indicate something like a permissions - # issue, an IOError would indicate something like - # the file not existing. In either case, print a - # message and keep going to try to remove as many - # targets as possible. - print("scons: Could not remove '{0}'".format(str(t)), e.strerror) - else: - if removed: - display("Removed " + str(t)) - self._clean_targets(remove=True) - - execute = remove - - # We want the Taskmaster to update the Node states (and therefore - # handle reference counts, etc.), but we don't want to call - # back to the Node's post-build methods, which would do things - # we don't want, like store .sconsign information. - executed = SCons.Taskmaster.Task.executed_without_callbacks - - # Have the Taskmaster arrange to "execute" all of the targets, because - # we'll figure out ourselves (in remove() or show() above) whether - # anything really needs to be done. - make_ready = SCons.Taskmaster.Task.make_ready_all - - def prepare(self): - pass - -class QuestionTask(SCons.Taskmaster.AlwaysTask): - """An SCons task for the -q (question) option.""" - def prepare(self): - pass - - def execute(self): - 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): - pass - - -class TreePrinter: - def __init__(self, derived=False, prune=False, status=False, sLineDraw=False): - self.derived = derived - self.prune = prune - self.status = status - self.sLineDraw = sLineDraw - def get_all_children(self, node): - return node.all_children() - def get_derived_children(self, node): - children = node.all_children(None) - return [x for x in children if x.has_builder()] - def display(self, t): - if self.derived: - func = self.get_derived_children - else: - func = self.get_all_children - s = self.status and 2 or 0 - SCons.Util.print_tree(t, func, prune=self.prune, showtags=s, lastChild=True, singleLineDraw=self.sLineDraw) - - -def python_version_string(): - return sys.version.split()[0] - -def python_version_unsupported(version=sys.version_info): - return version < unsupported_python_version - -def python_version_deprecated(version=sys.version_info): - return version < deprecated_python_version - - -class FakeOptionParser: - """ - A do-nothing option parser, used for the initial OptionsParser variable. - - During normal SCons operation, the OptionsParser is created right - away by the main() function. Certain tests scripts however, can - introspect on different Tool modules, the initialization of which - can try to add a new, local option to an otherwise uninitialized - OptionsParser object. This allows that introspection to happen - without blowing up. - - """ - class FakeOptionValues: - def __getattr__(self, attr): - return None - values = FakeOptionValues() - def add_local_option(self, *args, **kw): - pass - -OptionsParser = FakeOptionParser() - -def AddOption(*args, **kw): - if 'default' not in kw: - kw['default'] = None - result = OptionsParser.add_local_option(*args, **kw) - return result - -def GetOption(name): - return getattr(OptionsParser.values, name) - -def SetOption(name, value): - return OptionsParser.values.set_option(name, value) - -def PrintHelp(file=None): - OptionsParser.print_help(file=file) - -class Stats: - def __init__(self): - self.stats = [] - self.labels = [] - self.append = self.do_nothing - self.print_stats = self.do_nothing - def enable(self, outfp): - self.outfp = outfp - self.append = self.do_append - self.print_stats = self.do_print - def do_nothing(self, *args, **kw): - pass - -class CountStats(Stats): - def do_append(self, label): - self.labels.append(label) - self.stats.append(SCons.Debug.fetchLoggedInstances()) - def do_print(self): - stats_table = {} - for s in self.stats: - for n in [t[0] for t in s]: - stats_table[n] = [0, 0, 0, 0] - i = 0 - for s in self.stats: - for n, c in s: - stats_table[n][i] = c - i = i + 1 - self.outfp.write("Object counts:\n") - pre = [" "] - post = [" %s\n"] - l = len(self.stats) - fmt1 = ''.join(pre + [' %7s']*l + post) - fmt2 = ''.join(pre + [' %7d']*l + post) - labels = self.labels[:l] - labels.append(("", "Class")) - self.outfp.write(fmt1 % tuple([x[0] for x in labels])) - self.outfp.write(fmt1 % tuple([x[1] for x in labels])) - for k in sorted(stats_table.keys()): - r = stats_table[k][:l] + [k] - self.outfp.write(fmt2 % tuple(r)) - -count_stats = CountStats() - -class MemStats(Stats): - def do_append(self, label): - self.labels.append(label) - self.stats.append(SCons.Debug.memory()) - def do_print(self): - fmt = 'Memory %-32s %12d\n' - for label, stats in zip(self.labels, self.stats): - self.outfp.write(fmt % (label, stats)) - -memory_stats = MemStats() - -# utility functions - -def _scons_syntax_error(e): - """Handle syntax errors. Print out a message and show where the error - occurred. - """ - etype, value, tb = sys.exc_info() - lines = traceback.format_exception_only(etype, value) - for line in lines: - sys.stderr.write(line+'\n') - sys.exit(2) - -def find_deepest_user_frame(tb): - """ - Find the deepest stack frame that is not part of SCons. - - Input is a "pre-processed" stack trace in the form - returned by traceback.extract_tb() or traceback.extract_stack() - """ - - tb.reverse() - - # find the deepest traceback frame that is not part - # of SCons: - for frame in tb: - filename = frame[0] - if filename.find(os.sep+'SCons'+os.sep) == -1: - return frame - return tb[0] - -def _scons_user_error(e): - """Handle user errors. Print out a message and a description of the - error, along with the line number and routine where it occured. - The file and line number will be the deepest stack frame that is - not part of SCons itself. - """ - global print_stacktrace - etype, value, tb = sys.exc_info() - if print_stacktrace: - traceback.print_exception(etype, value, tb) - filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb)) - sys.stderr.write("\nscons: *** %s\n" % value) - sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) - sys.exit(2) - -def _scons_user_warning(e): - """Handle user warnings. Print out a message and a description of - the warning, along with the line number and routine where it occured. - The file and line number will be the deepest stack frame that is - not part of SCons itself. - """ - etype, value, tb = sys.exc_info() - filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb)) - sys.stderr.write("\nscons: warning: %s\n" % e) - sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) - -def _scons_internal_warning(e): - """Slightly different from _scons_user_warning in that we use the - *current call stack* rather than sys.exc_info() to get our stack trace. - This is used by the warnings framework to print warnings.""" - filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_stack()) - sys.stderr.write("\nscons: warning: %s\n" % e.args[0]) - sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) - -def _scons_internal_error(): - """Handle all errors but user errors. Print out a message telling - the user what to do in this case and print a normal trace. - """ - print('internal error') - traceback.print_exc() - sys.exit(2) - -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. - """ - if not filelist: - filelist = ['SConstruct', 'Sconstruct', 'sconstruct', 'SConstruct.py', 'Sconstruct.py', 'sconstruct.py'] - for file in filelist: - sfile = os.path.join(dirname, file) - if os.path.isfile(sfile): - return sfile - if not os.path.isabs(sfile): - for rep in repositories: - if os.path.isfile(os.path.join(rep, sfile)): - return sfile - return None - -def _set_debug_values(options): - global print_memoizer, print_objects, print_stacktrace, print_time, print_action_timestamps - - debug_values = options.debug - - if "count" in debug_values: - # All of the object counts are within "if track_instances:" blocks, - # which get stripped when running optimized (with python -O or - # from compiled *.pyo files). Provide a warning if __debug__ is - # stripped, so it doesn't just look like --debug=count is broken. - enable_count = False - if __debug__: enable_count = True - if enable_count: - count_stats.enable(sys.stdout) - SCons.Debug.track_instances = True - else: - msg = "--debug=count is not supported when running SCons\n" + \ - "\twith the python -O option or optimized (.pyo) modules." - SCons.Warnings.warn(SCons.Warnings.NoObjectCountWarning, msg) - if "dtree" in debug_values: - options.tree_printers.append(TreePrinter(derived=True)) - options.debug_explain = ("explain" in debug_values) - if "findlibs" in debug_values: - SCons.Scanner.Prog.print_find_libs = "findlibs" - options.debug_includes = ("includes" in debug_values) - print_memoizer = ("memoizer" in debug_values) - if "memory" in debug_values: - memory_stats.enable(sys.stdout) - print_objects = ("objects" in debug_values) - if print_objects: - SCons.Debug.track_instances = True - if "presub" in debug_values: - SCons.Action.print_actions_presub = 1 - if "stacktrace" in debug_values: - print_stacktrace = 1 - if "stree" in debug_values: - options.tree_printers.append(TreePrinter(status=True)) - if "time" in debug_values: - print_time = 1 - if "action-timestamps" in debug_values: - print_time = 1 - print_action_timestamps = 1 - if "tree" in debug_values: - options.tree_printers.append(TreePrinter()) - if "prepare" in debug_values: - SCons.Taskmaster.print_prepare = 1 - if "duplicate" in debug_values: - SCons.Node.print_duplicate = 1 - -def _create_path(plist): - path = '.' - for d in plist: - if os.path.isabs(d): - path = d - else: - path = path + '/' + d - return path - -def _load_site_scons_dir(topdir, site_dir_name=None): - """Load the site directory under topdir. - - If a site dir name is supplied use it, else use default "site_scons" - Prepend site dir to sys.path. - If a "site_tools" subdir exists, prepend to toolpath. - Import "site_init.py" from site dir if it exists. - """ - if site_dir_name: - err_if_not_found = True # user specified: err if missing - else: - site_dir_name = "site_scons" - err_if_not_found = False # scons default: okay to be missing - site_dir = os.path.join(topdir, site_dir_name) - - if not os.path.exists(site_dir): - if err_if_not_found: - raise SCons.Errors.UserError("site dir %s not found." % site_dir) - return - sys.path.insert(0, os.path.abspath(site_dir)) - - site_init_filename = "site_init.py" - site_init_modname = "site_init" - site_tools_dirname = "site_tools" - site_init_file = os.path.join(site_dir, site_init_filename) - site_tools_dir = os.path.join(site_dir, site_tools_dirname) - - if os.path.exists(site_tools_dir): - SCons.Tool.DefaultToolpath.insert(0, os.path.abspath(site_tools_dir)) - - if not os.path.exists(site_init_file): - return - - # "import" the site_init.py file into the SCons.Script namespace. - # This is a variant on the basic Python import flow in that the globals - # dict for the compile step is prepopulated from the SCons.Script - # module object; on success the SCons.Script globals are refilled - # from the site_init globals so it all appears in SCons.Script - # instead of as a separate module. - try: - try: - m = sys.modules['SCons.Script'] - except KeyError: - fmt = 'cannot import {}: missing SCons.Script module' - raise SCons.Errors.InternalError(fmt.format(site_init_file)) - - spec = importlib.util.spec_from_file_location(site_init_modname, site_init_file) - site_m = { - "__file__": spec.origin, - "__name__": spec.name, - "__doc__": None, - } - re_dunder = re.compile(r"__[^_]+__") - # update site dict with all but magic (dunder) methods - for k, v in m.__dict__.items(): - if not re_dunder.match(k): - site_m[k] = v - - with open(spec.origin, 'r') as f: - code = f.read() - try: - codeobj = compile(code, spec.name, "exec") - exec(codeobj, site_m) - except KeyboardInterrupt: - raise - except Exception: - fmt = "*** Error loading site_init file {}:\n" - sys.stderr.write(fmt.format(site_init_file)) - raise - else: - # now refill globals with site_init's symbols - for k, v in site_m.items(): - if not re_dunder.match(k): - m.__dict__[k] = v - except KeyboardInterrupt: - raise - except Exception: - fmt = "*** cannot import site init file {}:\n" - sys.stderr.write(fmt.format(site_init_file)) - raise - - -def _load_all_site_scons_dirs(topdir, verbose=None): - """Load all of the predefined site_scons dir. - Order is significant; we load them in order from most generic - (machine-wide) to most specific (topdir). - The verbose argument is only for testing. - """ - platform = SCons.Platform.platform_default() - - def homedir(d): - return os.path.expanduser('~/'+d) - - if platform == 'win32' or platform == 'cygwin': - # Note we use $ here instead of %...% because older - # pythons (prior to 2.6?) didn't expand %...% on Windows. - # This set of dirs should work on XP, Vista, 7 and later. - sysdirs=[ - os.path.expandvars('$ALLUSERSPROFILE\\Application Data\\scons'), - os.path.expandvars('$USERPROFILE\\Local Settings\\Application Data\\scons')] - appdatadir = os.path.expandvars('$APPDATA\\scons') - if appdatadir not in sysdirs: - sysdirs.append(appdatadir) - sysdirs.append(homedir('.scons')) - - elif platform == 'darwin': # MacOS X - sysdirs=['/Library/Application Support/SCons', - '/opt/local/share/scons', # (for MacPorts) - '/sw/share/scons', # (for Fink) - homedir('Library/Application Support/SCons'), - homedir('.scons')] - elif platform == 'sunos': # Solaris - sysdirs=['/opt/sfw/scons', - '/usr/share/scons', - homedir('.scons')] - else: # Linux, HPUX, etc. - # assume posix-like, i.e. platform == 'posix' - sysdirs=['/usr/share/scons', - homedir('.scons')] - - dirs = sysdirs + [topdir] - for d in dirs: - if verbose: # this is used by unit tests. - print("Loading site dir ", d) - _load_site_scons_dir(d) - -def test_load_all_site_scons_dirs(d): - _load_all_site_scons_dirs(d, True) - -def version_string(label, module): - version = module.__version__ - build = module.__build__ - if build: - if build[0] != '.': - build = '.' + build - version = version + build - fmt = "\t%s: v%s, %s, by %s on %s\n" - return fmt % (label, - version, - module.__date__, - module.__developer__, - module.__buildsys__) - -def path_string(label, module): - path = module.__path__ - return "\t%s path: %s\n"%(label,path) - -def _main(parser): - global exit_status - global this_build_status - - options = parser.values - - # Here's where everything really happens. - - # First order of business: set up default warnings and then - # handle the user's warning options, so that we can issue (or - # suppress) appropriate warnings about anything that might happen, - # as configured by the user. - - default_warnings = [ SCons.Warnings.WarningOnByDefault, - SCons.Warnings.DeprecatedWarning, - ] - - for warning in default_warnings: - SCons.Warnings.enableWarningClass(warning) - SCons.Warnings._warningOut = _scons_internal_warning - 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 - # occurred while the command-line options were getting parsed. - try: - dw = options.delayed_warnings - except AttributeError: - pass - else: - delayed_warnings.extend(dw) - for warning_type, message in delayed_warnings: - SCons.Warnings.warn(warning_type, message) - - if not SCons.Platform.virtualenv.virtualenv_enabled_by_default: - if options.enable_virtualenv: - SCons.Platform.virtualenv.enable_virtualenv = True - - if options.ignore_virtualenv: - SCons.Platform.virtualenv.ignore_virtualenv = True - - if options.diskcheck: - SCons.Node.FS.set_diskcheck(options.diskcheck) - - # Next, we want to create the FS object that represents the outside - # world's file system, as that's central to a lot of initialization. - # To do this, however, we need to be in the directory from which we - # want to start everything, which means first handling any relevant - # options that might cause us to chdir somewhere (-C, -D, -U, -u). - if options.directory: - script_dir = os.path.abspath(_create_path(options.directory)) - else: - script_dir = os.getcwd() - - target_top = None - if options.climb_up: - target_top = '.' # directory to prepend to targets - 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 and script_dir != os.getcwd(): - if not options.silent: - display("scons: Entering directory `%s'" % script_dir) - try: - os.chdir(script_dir) - except OSError: - sys.stderr.write("Could not change directory to %s\n" % script_dir) - - # Now that we're in the top-level SConstruct directory, go ahead - # and initialize the FS object that represents the file system, - # and make it the build engine default. - fs = SCons.Node.FS.get_default_fs() - - for rep in options.repository: - fs.Repository(rep) - - # Now that we have the FS object, the next order of business is to - # check for an SConstruct file (or other specified config file). - # If there isn't one, we can bail before doing any more work. - scripts = [] - if options.file: - scripts.extend(options.file) - if not scripts: - sfile = _SConstruct_exists(repositories=options.repository, - filelist=options.file) - if sfile: - scripts.append(sfile) - - if not scripts: - if options.help: - # There's no SConstruct, but they specified -h. - # Give them the options usage now, before we fail - # trying to read a non-existent SConstruct file. - raise SConsPrintHelpException - raise SCons.Errors.UserError("No SConstruct file found.") - - if scripts[0] == "-": - d = fs.getcwd() - else: - d = fs.File(scripts[0]).dir - fs.set_SConstruct_dir(d) - - _set_debug_values(options) - 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 - if options.question: - SCons.SConf.dryrun = 1 - if options.clean: - SCons.SConf.SetBuildType('clean') - if options.help: - SCons.SConf.SetBuildType('help') - SCons.SConf.SetCacheMode(options.config) - SCons.SConf.SetProgressDisplay(progress_display) - - if options.no_progress or options.silent: - progress_display.set_mode(0) - - if options.site_dir: - _load_site_scons_dir(d.get_internal_path(), options.site_dir) - elif not options.no_site_dir: - _load_all_site_scons_dirs(d.get_internal_path()) - - if options.include_dir: - sys.path = options.include_dir + sys.path - - # If we're about to start SCons in the interactive mode, - # inform the FS about this right here. Else, the release_target_info - # method could get called on some nodes, like the used "gcc" compiler, - # when using the Configure methods within the SConscripts. - # This would then cause subtle bugs, as already happened in #2971. - if options.interactive: - SCons.Node.interactive = True - - # That should cover (most of) the options. Next, set up the variables - # that hold command-line arguments, so the SConscript files that we - # read and execute have access to them. - targets = [] - xmit_args = [] - for a in parser.largs: - if a[:1] == '-': - continue - if '=' in a: - xmit_args.append(a) - else: - targets.append(a) - SCons.Script._Add_Targets(targets + parser.rargs) - SCons.Script._Add_Arguments(xmit_args) - - # 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 hasattr(sys.stdout, 'isatty') or not sys.stdout.isatty(): - sys.stdout = SCons.Util.Unbuffered(sys.stdout) - if not hasattr(sys.stderr, 'isatty') or not sys.stderr.isatty(): - sys.stderr = SCons.Util.Unbuffered(sys.stderr) - - memory_stats.append('before reading SConscript files:') - count_stats.append(('pre-', 'read')) - - # And here's where we (finally) read the SConscript files. - - progress_display("scons: Reading SConscript files ...") - - start_time = time.time() - try: - for script in scripts: - SCons.Script._SConscript._SConscript(fs, script) - except SCons.Errors.StopError as e: - # We had problems reading an SConscript file, such as it - # 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. - revert_io() - sys.stderr.write("scons: *** %s Stop.\n" % e) - sys.exit(2) - global sconscript_time - sconscript_time = time.time() - start_time - - progress_display("scons: done reading SConscript files.") - - 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 explicitly 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-%s Python version (%s) is deprecated.\n" + \ - " If this will cause hardship, contact scons-dev@scons.org" - deprecated_version_string = ".".join(map(str, deprecated_python_version)) - SCons.Warnings.warn(SCons.Warnings.PythonVersionWarning, - msg % (deprecated_version_string, python_version_string())) - - if not options.help: - # [ ] Clarify why we need to create Builder here at all, and - # why it is created in DefaultEnvironment - # https://bitbucket.org/scons/scons/commits/d27a548aeee8ad5e67ea75c2d19a7d305f784e30 - if SCons.SConf.NeedConfigHBuilder(): - SCons.SConf.CreateConfigHBuilder(SCons.Defaults.DefaultEnvironment()) - - # Now re-parse the command-line options (any to the left of a '--' - # argument, that is) with any user-defined command-line options that - # the SConscript files may have added to the parser object. This will - # emit the appropriate error message and exit if any unknown option - # was specified on the command line. - - parser.preserve_unknown_options = False - parser.parse_args(parser.largs, options) - - if options.help: - help_text = SCons.Script.help_text - if help_text is None: - # They specified -h, but there was no Help() inside the - # SConscript files. Give them the options usage. - raise SConsPrintHelpException - else: - print(help_text) - print("Use scons -H for help about command-line options.") - exit_status = 0 - return - - # 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 VariantDir() and changing - # directories and the like, so it can go ahead and start memoizing - # the string values of file system nodes. - - fs.chdir(fs.Top) - - SCons.Node.FS.save_strings(1) - - # Now that we've read the SConscripts we can set the options - # that are SConscript settable: - SCons.Node.implicit_cache = options.implicit_cache - 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 * 1024 - - 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: - revert_io() - print('Found nothing to build') - 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.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_readonly = options.cache_readonly - 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 - # BUILD_TARGETS in the SConscript file(s), so if they used -u, - # -U or -D, we have to look up targets relative to the top, - # but we build whatever they specified. - if target_top: - lookup_top = fs.Dir(target_top) - target_top = None - - targets = SCons.Script.BUILD_TARGETS - else: - # There are no targets specified on the command line, - # so if they used -u, -U or -D, we may have to restrict - # what actually gets built. - d = None - if target_top: - if options.climb_up == 1: - # -u, local directory and below - target_top = fs.Dir(target_top) - lookup_top = target_top - elif options.climb_up == 2: - # -D, all Default() targets - target_top = None - lookup_top = None - elif options.climb_up == 3: - # -U, local SConscript Default() targets - target_top = fs.Dir(target_top) - def check_dir(x, target_top=target_top): - if hasattr(x, 'cwd') and x.cwd is not None: - cwd = x.cwd.srcnode() - return cwd == target_top - else: - # x doesn't have a cwd, so it's either not a target, - # or not a file, so go ahead and keep it as a default - # target and let the engine sort it out: - return 1 - d = [tgt for tgt in SCons.Script.DEFAULT_TARGETS if check_dir(tgt)] - SCons.Script.DEFAULT_TARGETS[:] = d - target_top = None - lookup_top = None - - targets = SCons.Script._Get_Default_Targets(d, fs) - - if not targets: - sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n") - return None - - def Entry(x, ltop=lookup_top, ttop=target_top, fs=fs): - if isinstance(x, SCons.Node.Node): - node = x - else: - node = None - # Why would ltop be None? Unfortunately this happens. - if ltop is None: ltop = '' - # Curdir becomes important when SCons is called with -u, -C, - # or similar option that changes directory, and so the paths - # of targets given on the command line need to be adjusted. - curdir = os.path.join(os.getcwd(), str(ltop)) - for lookup in SCons.Node.arg2nodes_lookups: - node = lookup(x, curdir=curdir) - if node is not None: - break - if node is None: - node = fs.Entry(x, directory=ltop, create=1) - if ttop and not node.is_under(ttop): - if isinstance(node, SCons.Node.FS.Dir) and ttop.is_under(node): - node = ttop - else: - node = None - return node - - nodes = [_f for _f in map(Entry, targets) if _f] - - task_class = BuildTask # default action is to build targets - opening_message = "Building targets ..." - closing_message = "done building targets." - if options.keep_going: - failure_message = "done building targets (errors occurred during build)." - else: - failure_message = "building terminated because of errors." - if options.question: - task_class = QuestionTask - try: - if options.clean: - task_class = CleanTask - opening_message = "Cleaning targets ..." - closing_message = "done cleaning targets." - if options.keep_going: - failure_message = "done cleaning targets (errors occurred during clean)." - else: - failure_message = "cleaning terminated because of errors." - except AttributeError: - pass - - task_class.progress = ProgressObject - - if options.random: - def order(dependencies): - """Randomize the dependencies.""" - import random - random.shuffle(dependencies) - return dependencies - else: - def order(dependencies): - """Leave the order of dependencies alone.""" - return dependencies - - def tmtrace_cleanup(tfile): - tfile.close() - - if options.taskmastertrace_file == '-': - tmtrace = sys.stdout - elif options.taskmastertrace_file: - tmtrace = open(options.taskmastertrace_file, 'w') - atexit.register(tmtrace_cleanup, tmtrace) - else: - tmtrace = None - taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, order, tmtrace) - - # Let the BuildTask objects get at the options to respond to the - # various print_* settings, tree_printer list, etc. - BuildTask.options = options - - - is_pypy = platform.python_implementation() == 'PyPy' - # As of 3.7, python removed support for threadless platforms. - # See https://www.python.org/dev/peps/pep-0011/ - is_37_or_later = sys.version_info >= (3, 7) - # python_has_threads = sysconfig.get_config_var('WITH_THREAD') or is_pypy or is_37_or_later - - # As of python 3.4 threading has a dummy_threading module for use when there is no threading - # it's get_ident() will allways return -1, while real threading modules get_ident() will - # always return a positive integer - python_has_threads = threading.get_ident() != -1 - # to check if python configured with threads. - global num_jobs - num_jobs = options.num_jobs - jobs = SCons.Job.Jobs(num_jobs, taskmaster) - if num_jobs > 1: - msg = None - if jobs.num_jobs == 1 or not python_has_threads: - msg = "parallel builds are unsupported by this version of Python;\n" + \ - "\tignoring -j or num_jobs option.\n" - if msg: - SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg) - - memory_stats.append('before building targets:') - count_stats.append(('pre-', 'build')) - - def jobs_postfunc( - jobs=jobs, - options=options, - closing_message=closing_message, - failure_message=failure_message - ): - if jobs.were_interrupted(): - if not options.no_progress and not options.silent: - sys.stderr.write("scons: Build interrupted.\n") - 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 = sconsflags.split() + sys.argv[1:] - - options, args = parser.parse_args(all_args, values) - - if isinstance(options.debug, list) and "pdb" in options.debug: - import pdb - pdb.Pdb().runcall(_main, parser) - elif options.profile_file: - from cProfile import Profile - - prof = Profile() - try: - prof.runcall(_main, parser) - finally: - prof.dump_stats(options.profile_file) - else: - _main(parser) - -def main(): - global OptionsParser - 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 SCons - parts.append(version_string("SCons", SCons)) - 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(path_string("SCons", SCons)) - parts.append(SCons.__copyright__) - version = ''.join(parts) - - from . import SConsOptions - parser = SConsOptions.Parser(version) - values = SConsOptions.SConsValues(parser.get_default_values()) - - OptionsParser = parser - - try: - try: - _exec_main(parser, values) - finally: - revert_io() - except SystemExit as s: - if s: - exit_status = s.code - except KeyboardInterrupt: - print("scons: Build interrupted.") - sys.exit(2) - except SyntaxError as e: - _scons_syntax_error(e) - except SCons.Errors.InternalError: - _scons_internal_error() - except SCons.Errors.UserError as e: - _scons_user_error(e) - except SConsPrintHelpException: - parser.print_help() - exit_status = 0 - except SCons.Errors.BuildError as e: - print(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 - # problem was and where it happened. - SCons.Script._SConscript.SConscript_exception() - sys.exit(2) - - memory_stats.print_stats() - count_stats.print_stats() - - if print_objects: - SCons.Debug.listLoggedInstances('*') - #SCons.Debug.dumpLoggedInstances('*') - - if print_memoizer: - SCons.Memoize.Dump("Memoizer (memory cache) hits and misses:") - - # Dump any development debug info that may have been enabled. - # These are purely for internal debugging during development, so - # there's no need to control them with --debug= options; they're - # controlled by changing the source code. - SCons.Debug.dump_caller_counts() - SCons.Taskmaster.dump_stats() - - if print_time: - total_time = time.time() - SCons.Script.start_time - if num_jobs == 1: - ct = cumulative_command_time - else: - if last_command_end is None or first_command_start is None: - ct = 0.0 - else: - ct = last_command_end - first_command_start - scons_time = total_time - sconscript_time - ct - print("Total build time: %f seconds"%total_time) - print("Total SConscript file execution time: %f seconds"%sconscript_time) - print("Total SCons execution time: %f seconds"%scons_time) - print("Total command execution time: %f seconds"%ct) - - sys.exit(exit_status) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Script/SConsOptions.py b/scons/scons-local-4.1.0/SCons/Script/SConsOptions.py deleted file mode 100644 index 7b7929296..000000000 --- a/scons/scons-local-4.1.0/SCons/Script/SConsOptions.py +++ /dev/null @@ -1,983 +0,0 @@ -# MIT License -# -# Copyright 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. - -import optparse -import re -import sys -import textwrap - -no_hyphen_re = re.compile(r'(\s+|(?<=[\w!\"\'&.,?])-{2,}(?=\w))') - -import gettext -_ = gettext.gettext - -import SCons.Node.FS -import SCons.Platform.virtualenv -import SCons.Warnings - -OptionValueError = optparse.OptionValueError -SUPPRESS_HELP = optparse.SUPPRESS_HELP - -diskcheck_all = SCons.Node.FS.diskcheck_types() - -def diskcheck_convert(value): - if value is None: - return [] - if not SCons.Util.is_List(value): - value = value.split(',') - result = [] - for v in value: - v = v.lower() - if v == 'all': - result = diskcheck_all - elif v == 'none': - result = [] - elif v in diskcheck_all: - result.append(v) - else: - raise ValueError(v) - return result - - -class SConsValues(optparse.Values): - """ - Holder class for uniform access to SCons options, regardless - of whether or not they can be set on the command line or in the - SConscript files (using the SetOption() function). - - A SCons option value can originate three different ways: - - 1) set on the command line; - 2) set in an SConscript file; - 3) the default setting (from the the op.add_option() - calls in the Parser() function, below). - - The command line always overrides a value set in a SConscript file, - which in turn always overrides default settings. Because we want - to support user-specified options in the SConscript file itself, - though, we may not know about all of the options when the command - line is first parsed, so we can't make all the necessary precedence - decisions at the time the option is configured. - - The solution implemented in this class is to keep these different sets - of settings separate (command line, SConscript file, and default) - and to override the __getattr__() method to check them in turn. - This should allow the rest of the code to just fetch values as - attributes of an instance of this class, without having to worry - about where they came from. - - Note that not all command line options are settable from SConscript - files, and the ones that are must be explicitly added to the - "settable" list in this class, and optionally validated and coerced - in the set_option() method. - """ - - def __init__(self, defaults): - self.__dict__['__defaults__'] = defaults - self.__dict__['__SConscript_settings__'] = {} - - def __getattr__(self, attr): - """ - Fetches an options value, checking first for explicit settings - from the command line (which are direct attributes), then the - SConscript file settings, then the default values. - """ - try: - return self.__dict__[attr] - except KeyError: - try: - return self.__dict__['__SConscript_settings__'][attr] - except KeyError: - try: - return getattr(self.__dict__['__defaults__'], attr) - except KeyError: - # Added because with py3 this is a new class, - # not a classic class, and due to the way - # In that case it will create an object without - # __defaults__, and then query for __setstate__ - # which will throw an exception of KeyError - # deepcopy() is expecting AttributeError if __setstate__ - # is not available. - raise AttributeError(attr) - - # keep this list in sync with the SetOption doc in SCons/Script/Main.xml - # search for UPDATE_SETOPTION_DOCS there. - settable = [ - 'clean', - 'diskcheck', - 'duplicate', - 'help', - 'implicit_cache', - 'max_drift', - 'md5_chunksize', - 'no_exec', - 'num_jobs', - 'random', - 'stack_size', - 'warn', - 'silent', - 'no_progress' - ] - - def set_option(self, name, value): - """ - Sets an option from an SConscript file. - """ - if name not in self.settable: - raise SCons.Errors.UserError("This option is not settable from a SConscript file: %s"%name) - - if name == 'num_jobs': - try: - value = int(value) - if value < 1: - raise ValueError - except ValueError: - raise SCons.Errors.UserError("A positive integer is required: %s"%repr(value)) - elif name == 'max_drift': - try: - value = int(value) - except ValueError: - raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) - elif name == 'duplicate': - try: - value = str(value) - except ValueError: - raise SCons.Errors.UserError("A string is required: %s"%repr(value)) - if value not in SCons.Node.FS.Valid_Duplicates: - raise SCons.Errors.UserError("Not a valid duplication style: %s" % value) - # Set the duplicate style right away so it can affect linking - # of SConscript files. - SCons.Node.FS.set_duplicate(value) - elif name == 'diskcheck': - try: - value = diskcheck_convert(value) - except ValueError as v: - raise SCons.Errors.UserError("Not a valid diskcheck value: %s"%v) - if 'diskcheck' not in self.__dict__: - # No --diskcheck= option was specified on the command line. - # 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) - elif name == 'no_progress': - SCons.Script.Main.progress_display.set_mode(False) - - - self.__SConscript_settings__[name] = value - - -class SConsOption(optparse.Option): - def convert_value(self, opt, value): - if value is not None: - if self.nargs in (1, '?'): - return self.check_value(opt, value) - else: - return tuple([self.check_value(opt, v) for v in value]) - - def process(self, opt, value, values, parser): - - # First, convert the value(s) to the right type. Howl if any - # value(s) are bogus. - value = self.convert_value(opt, value) - - # And then take whatever action is expected of us. - # This is a separate method to make life easier for - # subclasses to add new actions. - return self.take_action( - self.action, self.dest, opt, value, values, parser) - - def _check_nargs_optional(self): - if self.nargs == '?' and self._short_opts: - fmt = "option %s: nargs='?' is incompatible with short options" - raise SCons.Errors.UserError(fmt % self._short_opts[0]) - - CHECK_METHODS = optparse.Option.CHECK_METHODS + [_check_nargs_optional] - CONST_ACTIONS = optparse.Option.CONST_ACTIONS + optparse.Option.TYPED_ACTIONS - -class SConsOptionGroup(optparse.OptionGroup): - """ - A subclass for SCons-specific option groups. - - The only difference between this and the base class is that we print - the group's help text flush left, underneath their own title but - lined up with the normal "SCons Options". - """ - def format_help(self, formatter): - """ - Format an option group's help text, outdenting the title so it's - flush with the "SCons Options" title we print at the top. - """ - formatter.dedent() - result = formatter.format_heading(self.title) - formatter.indent() - result = result + optparse.OptionContainer.format_help(self, formatter) - return result - -class SConsOptionParser(optparse.OptionParser): - preserve_unknown_options = False - - def error(self, msg): - # overridden OptionValueError exception handler - self.print_usage(sys.stderr) - sys.stderr.write("SCons Error: %s\n" % msg) - sys.exit(2) - - def _process_long_opt(self, rargs, values): - """ - SCons-specific processing of long options. - - This is copied directly from the normal - optparse._process_long_opt() method, except that, if configured - to do so, we catch the exception thrown when an unknown option - is encountered and just stick it back on the "leftover" arguments - for later (re-)processing. - """ - arg = rargs.pop(0) - - # Value explicitly attached to arg? Pretend it's the next argument. - if "=" in arg: - (opt, next_arg) = arg.split("=", 1) - rargs.insert(0, next_arg) - had_explicit_value = True - else: - opt = arg - had_explicit_value = False - - try: - if opt != self._match_long_opt(opt): - raise optparse.BadOptionError( - "'%s'. Did you mean '%s'?" - % (opt, self._match_long_opt(opt)) - ) - except optparse.BadOptionError: - if self.preserve_unknown_options: - # SCons-specific: if requested, add unknown options to - # the "leftover arguments" list for later processing. - self.largs.append(arg) - if had_explicit_value: - # The unknown option will be re-processed later, - # so undo the insertion of the explicit value. - rargs.pop(0) - return - raise - - option = self._long_opt[opt] - if option.takes_value(): - nargs = option.nargs - if nargs == '?': - if had_explicit_value: - value = rargs.pop(0) - else: - value = option.const - elif len(rargs) < nargs: - if nargs == 1: - if not option.choices: - self.error(_("%s option requires an argument") % opt) - else: - msg = _("%s option requires an argument " % opt) - msg += _("(choose from %s)" - % ', '.join(option.choices)) - self.error(msg) - else: - self.error(_("%s option requires %d arguments") - % (opt, nargs)) - elif nargs == 1: - value = rargs.pop(0) - else: - value = tuple(rargs[0:nargs]) - del rargs[0:nargs] - - elif had_explicit_value: - self.error(_("%s option does not take a value") % opt) - - else: - value = None - - option.process(opt, value, values, self) - - def reparse_local_options(self): - """ Re-parse the leftover command-line options. - - Parse options stored in `self.largs`, so that any value - overridden on the command line is immediately available - if the user turns around and does a :func:`GetOption` right away. - - We mimic the processing of the single args - in the original OptionParser :func:`_process_args`, but here we - allow exact matches for long-opts only (no partial argument names!). - Otherwise there could be problems in :func:`add_local_option` - below. When called from there, we try to reparse the - command-line arguments that - - 1. haven't been processed so far (`self.largs`), but - 2. are possibly not added to the list of options yet. - - So, when we only have a value for "--myargument" so far, - a command-line argument of "--myarg=test" would set it, - per the behaviour of :func:`_match_long_opt`, - which allows for partial matches of the option name, - as long as the common prefix appears to be unique. - This would lead to further confusion, because we might want - to add another option "--myarg" later on (see issue #2929). - - """ - rargs = [] - largs_restore = [] - # Loop over all remaining arguments - skip = False - for l in self.largs: - if skip: - # Accept all remaining arguments as they are - largs_restore.append(l) - else: - if len(l) > 2 and l[0:2] == "--": - # Check long option - lopt = (l,) - if "=" in l: - # Split into option and value - lopt = l.split("=", 1) - - if lopt[0] in self._long_opt: - # Argument is already known - rargs.append('='.join(lopt)) - else: - # Not known yet, so reject for now - largs_restore.append('='.join(lopt)) - else: - if l == "--" or l == "-": - # Stop normal processing and don't - # process the rest of the command-line opts - largs_restore.append(l) - skip = True - else: - rargs.append(l) - - # Parse the filtered list - self.parse_args(rargs, self.values) - # Restore the list of remaining arguments for the - # next call of AddOption/add_local_option... - self.largs = self.largs + largs_restore - - def add_local_option(self, *args, **kw): - """ - Adds a local option to the parser. - - This is initiated by an AddOption() call to add a user-defined - command-line option. We add the option to a separate option - group for the local options, creating the group if necessary. - """ - try: - group = self.local_option_group - except AttributeError: - group = SConsOptionGroup(self, 'Local Options') - group = self.add_option_group(group) - self.local_option_group = group - - result = group.add_option(*args, **kw) - - if result: - # The option was added successfully. We now have to add the - # default value to our object that holds the default values - # (so that an attempt to fetch the option's attribute will - # yield the default value when not overridden) and then - # we re-parse the leftover command-line options, so that - # any value overridden on the command line is immediately - # available if the user turns around and does a GetOption() - # right away. - setattr(self.values.__defaults__, result.dest, result.default) - self.reparse_local_options() - - return result - -class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): - def format_usage(self, usage): - return "usage: %s\n" % usage - - def format_heading(self, heading): - """ - This translates any heading of "options" or "Options" into - "SCons Options." Unfortunately, we have to do this here, - because those titles are hard-coded in the optparse calls. - """ - if heading == 'Options': - heading = "SCons Options" - return optparse.IndentedHelpFormatter.format_heading(self, heading) - - def format_option(self, option): - """ - A copy of the normal optparse.IndentedHelpFormatter.format_option() - 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 - # eg. ("-x", or "-fFILENAME, --file=FILENAME") - # * the user-supplied help string - # eg. ("turn on expert mode", "read data from FILENAME") - # - # If possible, we write both of these on the same line: - # -x turn on expert mode - # - # But if the opt string list is too long, we put the help - # string on a second line, indented to the same column it would - # start in if it fit on the first line. - # -fFILENAME, --file=FILENAME - # read data from FILENAME - result = [] - - opts = self.option_strings[option] - opt_width = self.help_position - self.current_indent - 2 - if len(opts) > opt_width: - 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) - indent_first = 0 - result.append(opts) - if option.help: - - help_text = self.expand_default(option) - - # SCons: indent every line of the help text but the first. - 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)) - elif opts[-1] != "\n": - result.append("\n") - return "".join(result) - -def Parser(version): - """ - Returns an options parser object initialized with the standard - SCons options. - """ - - formatter = SConsIndentedHelpFormatter(max_help_position=30) - - op = SConsOptionParser(option_class=SConsOption, - add_help_option=False, - formatter=formatter, - usage="usage: scons [OPTION] [TARGET] ...",) - - op.preserve_unknown_options = True - op.version = version - - # Add the options to the parser we just created. - # - # These are in the order we want them to show up in the -H help - # text, basically alphabetical. Each op.add_option() call below - # should have a consistent format: - # - # op.add_option("-L", "--long-option-name", - # nargs=1, type="string", - # dest="long_option_name", default='foo', - # action="callback", callback=opt_long_option, - # help="help text goes here", - # metavar="VAR") - # - # Even though the optparse module constructs reasonable default - # destination names from the long option names, we're going to be - # explicit about each one for easier readability and so this code - # will at least show up when grepping the source for option attribute - # names, or otherwise browsing the source code. - - # options ignored for compatibility - def opt_ignore(option, opt, value, parser): - sys.stderr.write("Warning: ignoring %s option\n" % opt) - 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.") - - op.add_option('-c', '--clean', '--remove', - dest="clean", default=False, - action="store_true", - help="Remove specified targets and dependencies.") - - op.add_option('-C', '--directory', - nargs=1, type="string", - dest="directory", default=[], - action="append", - help="Change to DIR before doing anything.", - metavar="DIR") - - op.add_option('--cache-debug', - nargs=1, - dest="cache_debug", default=None, - action="store", - help="Print CacheDir debug info to FILE.", - metavar="FILE") - - op.add_option('--cache-disable', '--no-cache', - dest='cache_disable', default=False, - action="store_true", - help="Do not retrieve built targets from CacheDir.") - - op.add_option('--cache-force', '--cache-populate', - dest='cache_force', default=False, - action="store_true", - help="Copy already-built targets into the CacheDir.") - - op.add_option('--cache-readonly', - dest='cache_readonly', default=False, - action="store_true", - help="Do not update CacheDir with built targets.") - - op.add_option('--cache-show', - dest='cache_show', default=False, - action="store_true", - help="Print build actions for files from CacheDir.") - - def opt_invalid(group, value, options): - """report an invalid option from a group""" - errmsg = "`%s' is not a valid %s option type, try:\n" % (value, group) - return errmsg + " %s" % ", ".join(options) - - def opt_invalid_rm(group, value, msg): - """report an invalid option from a group: recognized but removed""" - errmsg = "`%s' is not a valid %s option type " % (value, group) - return errmsg + msg - - config_options = ["auto", "force" ,"cache"] - - opt_config_help = "Controls Configure subsystem: %s." \ - % ", ".join(config_options) - - op.add_option('--config', - nargs=1, choices=config_options, - dest="config", default="auto", - help = opt_config_help, - metavar="MODE") - - 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.") - - deprecated_debug_options = {} - - removed_debug_options = { - "dtree" : '; please use --tree=derived instead', - "nomemoizer" : '; there is no replacement', - "stree" : '; please use --tree=all,status instead', - "tree" : '; please use --tree=all instead', - } - - debug_options = ["count", "duplicate", "explain", "findlibs", - "includes", "memoizer", "memory", "objects", - "pdb", "prepare", "presub", "stacktrace", - "time", "action-timestamps"] - - def opt_debug(option, opt, value__, parser, - debug_options=debug_options, - deprecated_debug_options=deprecated_debug_options, - removed_debug_options=removed_debug_options): - for value in value__.split(','): - if value in debug_options: - parser.values.debug.append(value) - elif value in deprecated_debug_options: - parser.values.debug.append(value) - 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.DeprecatedDebugOptionsWarning, w) - parser.values.delayed_warnings.append(t) - elif value in removed_debug_options: - msg = removed_debug_options[value] - raise OptionValueError(opt_invalid_rm('debug', value, msg)) - else: - raise OptionValueError(opt_invalid('debug', value, debug_options)) - - opt_debug_help = "Print various types of debugging information: %s." \ - % ", ".join(debug_options) - op.add_option('--debug', - nargs=1, type="string", - dest="debug", default=[], - action="callback", callback=opt_debug, - help=opt_debug_help, - metavar="TYPE") - - def opt_diskcheck(option, opt, value, parser): - try: - diskcheck_value = diskcheck_convert(value) - except ValueError as e: - raise OptionValueError("`%s' is not a valid diskcheck type" % e) - setattr(parser.values, option.dest, diskcheck_value) - - op.add_option('--diskcheck', - nargs=1, type="string", - dest='diskcheck', default=None, - action="callback", callback=opt_diskcheck, - help="Enable specific on-disk checks.", - metavar="TYPE") - - def opt_duplicate(option, opt, value, parser): - if value not in SCons.Node.FS.Valid_Duplicates: - raise OptionValueError(opt_invalid('duplication', value, - SCons.Node.FS.Valid_Duplicates)) - setattr(parser.values, option.dest, value) - # Set the duplicate style right away so it can affect linking - # of SConscript files. - SCons.Node.FS.set_duplicate(value) - - opt_duplicate_help = "Set the preferred duplication methods. Must be one of " \ - + ", ".join(SCons.Node.FS.Valid_Duplicates) - - op.add_option('--duplicate', - nargs=1, type="string", - dest="duplicate", default='hard-soft-copy', - action="callback", callback=opt_duplicate, - help=opt_duplicate_help) - - if not SCons.Platform.virtualenv.virtualenv_enabled_by_default: - op.add_option('--enable-virtualenv', - dest="enable_virtualenv", - action="store_true", - help="Import certain virtualenv variables to SCons") - - op.add_option('-f', '--file', '--makefile', '--sconstruct', - nargs=1, type="string", - dest="file", default=[], - action="append", - help="Read FILE as the top-level SConstruct file.") - - op.add_option('-h', '--help', - dest="help", default=False, - action="store_true", - help="Print defined help message, or this one.") - - op.add_option("-H", "--help-options", - action="help", - help="Print this message and exit.") - - op.add_option('-i', '--ignore-errors', - dest='ignore_errors', default=False, - action="store_true", - help="Ignore errors from build actions.") - - op.add_option('-I', '--include-dir', - nargs=1, - dest='include_dir', default=[], - action="append", - help="Search DIR for imported Python modules.", - metavar="DIR") - - op.add_option('--ignore-virtualenv', - dest="ignore_virtualenv", - action="store_true", - help="Do not import virtualenv variables to SCons") - - op.add_option('--implicit-cache', - dest='implicit_cache', default=False, - action="store_true", - help="Cache implicit dependencies") - - def opt_implicit_deps(option, opt, value, parser): - setattr(parser.values, 'implicit_cache', True) - setattr(parser.values, option.dest, True) - - op.add_option('--implicit-deps-changed', - dest="implicit_deps_changed", default=False, - action="callback", callback=opt_implicit_deps, - help="Ignore cached implicit dependencies.") - - op.add_option('--implicit-deps-unchanged', - dest="implicit_deps_unchanged", default=False, - 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, - action="store", - help="Allow N jobs at once.", - metavar="N") - - op.add_option('-k', '--keep-going', - dest='keep_going', default=False, - action="store_true", - help="Keep going when a target can't be made.") - - op.add_option('--max-drift', - nargs=1, type="int", - dest='max_drift', default=SCons.Node.FS.default_max_drift, - action="store", - 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", - help="Don't build; just print commands.") - - op.add_option('--no-site-dir', - dest='no_site_dir', default=False, - action="store_true", - help="Don't search or use the usual site_scons dir.") - - op.add_option('--profile', - nargs=1, - dest="profile_file", default=None, - action="store", - help="Profile SCons and put results in FILE.", - metavar="FILE") - - op.add_option('-q', '--question', - dest="question", default=False, - action="store_true", - help="Don't build; exit status says if up to date.") - - op.add_option('-Q', - dest='no_progress', default=False, - action="store_true", - help="Suppress \"Reading/Building\" progress messages.") - - op.add_option('--random', - dest="random", default=False, - action="store_true", - help="Build dependencies in random order.") - - op.add_option('-s', '--silent', '--quiet', - dest="silent", default=False, - action="store_true", - help="Don't print commands.") - - op.add_option('--site-dir', - nargs=1, - dest='site_dir', default=None, - action="store", - 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, - action="store", - help="Trace Node evaluation to FILE.", - metavar="FILE") - - tree_options = ["all", "derived", "prune", "status", "linedraw"] - - def opt_tree(option, opt, value, parser, tree_options=tree_options): - from . import Main - tp = Main.TreePrinter() - for o in value.split(','): - if o == 'all': - tp.derived = False - elif o == 'derived': - tp.derived = True - elif o == 'prune': - tp.prune = True - elif o == 'status': - tp.status = True - elif o == 'linedraw': - tp.sLineDraw = True - else: - raise OptionValueError(opt_invalid('--tree', o, tree_options)) - parser.values.tree_printers.append(tp) - - opt_tree_help = "Print a dependency tree in various formats: %s." \ - % ", ".join(tree_options) - - op.add_option('--tree', - nargs=1, type="string", - dest="tree_printers", default=[], - action="callback", callback=opt_tree, - help=opt_tree_help, - metavar="OPTIONS") - - op.add_option('-u', '--up', '--search-up', - dest="climb_up", default=0, - action="store_const", const=1, - help="Search up directory tree for SConstruct, " - "build targets at or below current directory.") - - op.add_option('-U', - dest="climb_up", default=0, - action="store_const", const=3, - help="Search up directory tree for SConstruct, " - "build Default() targets from local SConscript.") - - 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 = value.split(',') - parser.values.warn.extend(value) - - op.add_option('--warn', '--warning', - nargs=1, type="string", - dest="warn", default=[], - action="callback", callback=opt_warn, - help="Enable or disable warnings.", - metavar="WARNING-SPEC") - - op.add_option('-Y', '--repository', '--srcdir', - nargs=1, - dest="repository", default=[], - action="append", - help="Search REPOSITORY for source and target files.") - - - # Options from Make and Cons classic that we do not yet support, - # but which we may support someday and whose (potential) meanings - # 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. - - def opt_not_yet(option, opt, value, parser): - msg = "Warning: the %s option is not yet implemented\n" % opt - sys.stderr.write(msg) - - op.add_option('-l', '--load-average', '--max-load', - nargs=1, type="float", - dest="load_average", default=0, - action="callback", callback=opt_not_yet, - # action="store", - # help="Don't start multiple jobs unless load is below " - # "LOAD-AVERAGE." - help=SUPPRESS_HELP) - op.add_option('--list-actions', - dest="list_actions", - action="callback", callback=opt_not_yet, - # help="Don't build; list files and build actions." - help=SUPPRESS_HELP) - op.add_option('--list-derived', - dest="list_derived", - action="callback", callback=opt_not_yet, - # help="Don't build; list files that would be built." - help=SUPPRESS_HELP) - op.add_option('--list-where', - dest="list_where", - action="callback", callback=opt_not_yet, - # help="Don't build; list files and where defined." - help=SUPPRESS_HELP) - op.add_option('-o', '--old-file', '--assume-old', - nargs=1, type="string", - dest="old_file", default=[], - action="callback", callback=opt_not_yet, - # action="append", - # help = "Consider FILE to be old; don't rebuild it." - help=SUPPRESS_HELP) - op.add_option('--override', - nargs=1, type="string", - action="callback", callback=opt_not_yet, - dest="override", - # help="Override variables as specified in FILE." - help=SUPPRESS_HELP) - op.add_option('-p', - action="callback", callback=opt_not_yet, - dest="p", - # help="Print internal environments/objects." - help=SUPPRESS_HELP) - op.add_option('-r', '-R', '--no-builtin-rules', '--no-builtin-variables', - action="callback", callback=opt_not_yet, - dest="no_builtin_rules", - # help="Clear default environments and variables." - help=SUPPRESS_HELP) - op.add_option('--write-filenames', - nargs=1, type="string", - dest="write_filenames", - action="callback", callback=opt_not_yet, - # help="Write all filenames examined into FILE." - help=SUPPRESS_HELP) - op.add_option('-W', '--new-file', '--assume-new', '--what-if', - nargs=1, type="string", - dest="new_file", - action="callback", callback=opt_not_yet, - # help="Consider FILE to be changed." - help=SUPPRESS_HELP) - op.add_option('--warn-undefined-variables', - dest="warn_undefined_variables", - action="callback", callback=opt_not_yet, - # help="Warn when an undefined variable is referenced." - help=SUPPRESS_HELP) - return op - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Script/SConscript.py b/scons/scons-local-4.1.0/SCons/Script/SConscript.py deleted file mode 100644 index b8dfd938a..000000000 --- a/scons/scons-local-4.1.0/SCons/Script/SConscript.py +++ /dev/null @@ -1,680 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""This module defines the Python API provided to SConscript files.""" - -import SCons -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Environment -import SCons.Errors -import SCons.Node -import SCons.Node.Alias -import SCons.Node.FS -import SCons.Platform -import SCons.SConf -import SCons.Script.Main -import SCons.Tool -from SCons.Util import is_List, is_String, is_Dict, flatten -from SCons.Node import SConscriptNodes -from . import Main - -import os -import os.path -import re -import sys -import traceback -import time - -class SConscriptReturn(Exception): - pass - -launch_dir = os.path.abspath(os.curdir) - -GlobalDict = None - -# global exports set by Export(): -global_exports = {} - -# chdir flag -sconscript_chdir = 1 - -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: - # 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() - # or SConscript() call to be in this file, so that we can identify - # the first non-Script.SConscript frame as the user's local calling - # environment, and the locals and globals dictionaries from that - # frame as the calling namespaces. See the comment below preceding - # the DefaultEnvironmentCall block for even more explanation. - while frame.f_globals.get("__name__") == __name__: - frame = frame.f_back - - return frame.f_locals, frame.f_globals - - -def compute_exports(exports): - """Compute a dictionary of exports given one of the parameters - to the Export() function or the exports argument to SConscript().""" - - loc, glob = get_calling_namespaces() - - retval = {} - try: - for export in exports: - if is_Dict(export): - retval.update(export) - else: - try: - retval[export] = loc[export] - except KeyError: - retval[export] = glob[export] - except KeyError as x: - raise SCons.Errors.UserError("Export of non-existent variable '%s'"%x) - - return retval - -class Frame: - """A frame on the SConstruct/SConscript call stack""" - def __init__(self, fs, exports, sconscript): - self.globals = BuildDefaultGlobals() - self.retval = None - self.prev_dir = fs.getcwd() - self.exports = compute_exports(exports) # exports from the calling SConscript - # make sure the sconscript attr is a Node. - if isinstance(sconscript, SCons.Node.Node): - self.sconscript = sconscript - elif sconscript == '-': - self.sconscript = None - else: - self.sconscript = fs.File(str(sconscript)) - -# the SConstruct/SConscript call stack: -call_stack = [] - -# For documentation on the methods in this file, see the scons man-page - -def Return(*vars, **kw): - retval = [] - try: - fvars = flatten(vars) - for var in fvars: - for v in var.split(): - retval.append(call_stack[-1].globals[v]) - except KeyError as x: - raise SCons.Errors.UserError("Return of non-existent variable '%s'"%x) - - if len(retval) == 1: - call_stack[-1].retval = retval[0] - else: - call_stack[-1].retval = tuple(retval) - - stop = kw.get('stop', True) - - if stop: - raise SConscriptReturn - - -stack_bottom = '% Stack boTTom %' # hard to define a variable w/this name :) - -def handle_missing_SConscript(f, must_exist=None): - """Take appropriate action on missing file in SConscript() call. - - Print a warning or raise an exception on missing file. - On first warning, print a deprecation message. - - Args: - f (str): path of missing configuration file - must_exist (bool): raise exception if file does not exist - - Raises: - UserError if 'must_exist' is True or if global - SCons.Script._no_missing_sconscript is True. - """ - - if must_exist or (SCons.Script._no_missing_sconscript and must_exist is not False): - msg = "Fatal: missing SConscript '%s'" % f.get_internal_path() - raise SCons.Errors.UserError(msg) - - if SCons.Script._warn_missing_sconscript_deprecated and must_exist is None: - msg = "Calling missing SConscript without error is deprecated.\n" + \ - "Transition by adding must_exist=0 to SConscript calls.\n" + \ - "Missing SConscript '%s'" % f.get_internal_path() - SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, msg) - SCons.Script._warn_missing_sconscript_deprecated = False - else: - msg = "Ignoring missing SConscript '%s'" % f.get_internal_path() - SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, msg) - -def _SConscript(fs, *files, **kw): - top = fs.Top - sd = fs.SConstruct_dir.rdir() - exports = kw.get('exports', []) - - # evaluate each SConscript file - results = [] - for fn in files: - call_stack.append(Frame(fs, exports, fn)) - old_sys_path = sys.path - try: - SCons.Script.sconscript_reading = SCons.Script.sconscript_reading + 1 - if fn == "-": - exec(sys.stdin.read(), call_stack[-1].globals) - else: - if isinstance(fn, SCons.Node.Node): - f = fn - else: - f = fs.File(str(fn)) - _file_ = None - SConscriptNodes.add(f) - - # Change directory to the top of the source - # tree to make sure the os's cwd and the cwd of - # fs match so we can open the SConscript. - fs.chdir(top, change_os_dir=1) - if f.rexists(): - actual = f.rfile() - _file_ = open(actual.get_abspath(), "rb") - elif f.srcnode().rexists(): - actual = f.srcnode().rfile() - _file_ = open(actual.get_abspath(), "rb") - elif f.has_src_builder(): - # The SConscript file apparently exists in a source - # code management system. Build it, but then clear - # the builder so that it doesn't get built *again* - # during the actual build phase. - f.build() - f.built() - f.builder_set(None) - if f.exists(): - _file_ = open(f.get_abspath(), "rb") - if _file_: - # Chdir to the SConscript directory. Use a path - # name relative to the SConstruct file so that if - # we're using the -f option, we're essentially - # creating a parallel SConscript directory structure - # in our local directory tree. - # - # XXX This is broken for multiple-repository cases - # where the SConstruct and SConscript files might be - # in different Repositories. For now, cross that - # bridge when someone comes to it. - try: - src_dir = kw['src_dir'] - except KeyError: - ldir = fs.Dir(f.dir.get_path(sd)) - else: - ldir = fs.Dir(src_dir) - if not ldir.is_under(f.dir): - # They specified a source directory, but - # it's above the SConscript directory. - # Do the sensible thing and just use the - # SConcript directory. - ldir = fs.Dir(f.dir.get_path(sd)) - try: - fs.chdir(ldir, change_os_dir=sconscript_chdir) - except OSError: - # There was no local directory, so we should be - # able to chdir to the Repository directory. - # Note that we do this directly, not through - # fs.chdir(), because we still need to - # interpret the stuff within the SConscript file - # relative to where we are logically. - fs.chdir(ldir, change_os_dir=0) - os.chdir(actual.dir.get_abspath()) - - # Append the SConscript directory to the beginning - # of sys.path so Python modules in the SConscript - # directory can be easily imported. - sys.path = [ f.dir.get_abspath() ] + sys.path - - # This is the magic line that actually reads up - # and executes the stuff in the SConscript file. - # The locals for this frame contain the special - # bottom-of-the-stack marker so that any - # exceptions that occur when processing this - # SConscript can base the printed frames at this - # level and not show SCons internals as well. - call_stack[-1].globals.update({stack_bottom:1}) - old_file = call_stack[-1].globals.get('__file__') - try: - del call_stack[-1].globals['__file__'] - except KeyError: - pass - try: - try: - if Main.print_time: - time1 = time.time() - scriptdata = _file_.read() - scriptname = _file_.name - _file_.close() - exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals) - except SConscriptReturn: - pass - finally: - if Main.print_time: - time2 = time.time() - print('SConscript:%s took %0.3f ms' % (f.get_abspath(), (time2 - time1) * 1000.0)) - - if old_file is not None: - call_stack[-1].globals.update({__file__:old_file}) - else: - handle_missing_SConscript(f, kw.get('must_exist', None)) - - finally: - SCons.Script.sconscript_reading = SCons.Script.sconscript_reading - 1 - sys.path = old_sys_path - frame = call_stack.pop() - try: - fs.chdir(frame.prev_dir, change_os_dir=sconscript_chdir) - except OSError: - # There was no local directory, so chdir to the - # Repository directory. Like above, we do this - # directly. - fs.chdir(frame.prev_dir, change_os_dir=0) - rdir = frame.prev_dir.rdir() - rdir._create() # Make sure there's a directory there. - try: - os.chdir(rdir.get_abspath()) - except OSError as 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) - - # if we only have one script, don't return a tuple - if len(results) == 1: - return results[0] - else: - return tuple(results) - -def SConscript_exception(file=sys.stderr): - """Print an exception stack trace just for the SConscript file(s). - This will show users who have Python errors where the problem is, - without cluttering the output with all of the internal calls leading - up to where we exec the SConscript.""" - exc_type, exc_value, exc_tb = sys.exc_info() - tb = exc_tb - while tb and stack_bottom not in tb.tb_frame.f_locals: - tb = tb.tb_next - if not tb: - # We did not find our exec statement, so this was actually a bug - # in SCons itself. Show the whole stack. - tb = exc_tb - stack = traceback.extract_tb(tb) - try: - type = exc_type.__name__ - except AttributeError: - type = str(exc_type) - if type[:11] == "exceptions.": - type = type[11:] - file.write('%s: %s:\n' % (type, exc_value)) - for fname, line, func, text in stack: - file.write(' File "%s", line %d:\n' % (fname, line)) - file.write(' %s\n' % text) - -def annotate(node): - """Annotate a node with the stack frame describing the - SConscript file and line number that created it.""" - tb = sys.exc_info()[2] - while tb and stack_bottom not in tb.tb_frame.f_locals: - tb = tb.tb_next - if not tb: - # We did not find any exec of an SConscript file: what?! - raise SCons.Errors.InternalError("could not find SConscript stack frame") - node.creator = traceback.extract_stack(tb)[0] - -# The following line would cause each Node to be annotated using the -# above function. Unfortunately, this is a *huge* performance hit, so -# leave this disabled until we find a more efficient mechanism. -#SCons.Node.Annotate = annotate - -class SConsEnvironment(SCons.Environment.Base): - """An Environment subclass that contains all of the methods that - are particular to the wrapper SCons interface and which aren't - (or shouldn't be) part of the build engine itself. - - Note that not all of the methods of this class have corresponding - global functions, there are some private methods. - """ - - # - # Private methods of an SConsEnvironment. - # - def _exceeds_version(self, major, minor, v_major, v_minor): - """Return 1 if 'major' and 'minor' are greater than the version - in 'v_major' and 'v_minor', and 0 otherwise.""" - return (major > v_major or (major == v_major and minor > v_minor)) - - def _get_major_minor_revision(self, version_string): - """Split a version string into major, minor and (optionally) - revision parts. - - This is complicated by the fact that a version string can be - something like 3.2b1.""" - version = version_string.split(' ')[0].split('.') - v_major = int(version[0]) - v_minor = int(re.match(r'\d+', version[1]).group()) - if len(version) >= 3: - v_revision = int(re.match(r'\d+', version[2]).group()) - else: - v_revision = 0 - return v_major, v_minor, v_revision - - def _get_SConscript_filenames(self, ls, kw): - """ - Convert the parameters passed to SConscript() calls into a list - of files and export variables. If the parameters are invalid, - throws SCons.Errors.UserError. Returns a tuple (l, e) where l - is a list of SConscript filenames and e is a list of exports. - """ - exports = [] - - if len(ls) == 0: - try: - dirs = kw["dirs"] - except KeyError: - raise SCons.Errors.UserError("Invalid SConscript usage - no parameters") - - if not is_List(dirs): - dirs = [ dirs ] - dirs = list(map(str, dirs)) - - name = kw.get('name', 'SConscript') - - files = [os.path.join(n, name) for n in dirs] - - elif len(ls) == 1: - - files = ls[0] - - elif len(ls) == 2: - - files = ls[0] - exports = self.Split(ls[1]) - - else: - - raise SCons.Errors.UserError("Invalid SConscript() usage - too many arguments") - - if not is_List(files): - files = [ files ] - - if kw.get('exports'): - exports.extend(self.Split(kw['exports'])) - - variant_dir = kw.get('variant_dir') - if variant_dir: - if len(files) != 1: - raise SCons.Errors.UserError("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(variant_dir), fname)] - else: - if not isinstance(src_dir, SCons.Node.Node): - src_dir = self.fs.Dir(src_dir) - fn = files[0] - if not isinstance(fn, SCons.Node.Node): - fn = self.fs.File(fn) - if fn.is_under(src_dir): - # Get path relative to the source directory. - fname = fn.get_path(src_dir) - files = [os.path.join(str(variant_dir), fname)] - else: - files = [fn.get_abspath()] - kw['src_dir'] = variant_dir - self.fs.VariantDir(variant_dir, src_dir, duplicate) - - return (files, exports) - - # - # Public methods of an SConsEnvironment. These get - # entry points in the global namespace so they can be called - # as global functions. - # - - def Configure(self, *args, **kw): - if not SCons.Script.sconscript_reading: - raise SCons.Errors.UserError("Calling Configure from Builders is not supported.") - kw['_depth'] = kw.get('_depth', 0) + 1 - return SCons.Environment.Base.Configure(self, *args, **kw) - - def Default(self, *targets): - SCons.Script._Set_Default_Targets(self, targets) - - def EnsureSConsVersion(self, major, minor, revision=0): - """Exit abnormally if the SCons version is not late enough.""" - # split string to avoid replacement during build process - if SCons.__version__ == '__' + 'VERSION__': - SCons.Warnings.warn(SCons.Warnings.DevelopmentVersionWarning, - "EnsureSConsVersion is ignored for development version") - return - scons_ver = self._get_major_minor_revision(SCons.__version__) - if scons_ver < (major, minor, revision): - if revision: - scons_ver_string = '%d.%d.%d' % (major, minor, revision) - else: - scons_ver_string = '%d.%d' % (major, minor) - print("SCons %s or greater required, but you have SCons %s" % \ - (scons_ver_string, SCons.__version__)) - sys.exit(2) - - def EnsurePythonVersion(self, major, minor): - """Exit abnormally if the Python version is not late enough.""" - if sys.version_info < (major, minor): - v = sys.version.split()[0] - print("Python %d.%d or greater required, but you have Python %s" %(major,minor,v)) - sys.exit(2) - - def Exit(self, value=0): - sys.exit(value) - - def Export(self, *vars, **kw): - for var in vars: - global_exports.update(compute_exports(self.Split(var))) - global_exports.update(kw) - - def GetLaunchDir(self): - global launch_dir - return launch_dir - - def GetOption(self, name): - name = self.subst(name) - return SCons.Script.Main.GetOption(name) - - def Help(self, text, append=False): - text = self.subst(text, raw=1) - SCons.Script.HelpFunction(text, append=append) - - def Import(self, *vars): - try: - frame = call_stack[-1] - globals = frame.globals - exports = frame.exports - for var in vars: - var = self.Split(var) - for v in var: - if v == '*': - globals.update(global_exports) - globals.update(exports) - else: - if v in exports: - globals[v] = exports[v] - else: - globals[v] = global_exports[v] - except KeyError as x: - raise SCons.Errors.UserError("Import of non-existent variable '%s'"%x) - - def SConscript(self, *ls, **kw): - """Execute SCons configuration files. - - Parameters: - *ls (str or list): configuration file(s) to execute. - - Keyword arguments: - dirs (list): execute SConscript in each listed directory. - name (str): execute script 'name' (used only with 'dirs'). - exports (list or dict): locally export variables the - called script(s) can import. - variant_dir (str): mirror sources needed for the build in - a variant directory to allow building in it. - duplicate (bool): physically duplicate sources instead of just - adjusting paths of derived files (used only with 'variant_dir') - (default is True). - must_exist (bool): fail if a requested script is missing - (default is False, default is deprecated). - - Returns: - list of variables returned by the called script - - Raises: - UserError: a script is not found and such exceptions are enabled. - """ - - def subst_element(x, subst=self.subst): - if SCons.Util.is_List(x): - x = list(map(subst, x)) - else: - x = subst(x) - return x - ls = list(map(subst_element, ls)) - subst_kw = {} - for key, val in kw.items(): - if is_String(val): - val = self.subst(val) - elif SCons.Util.is_List(val): - val = [self.subst(v) if is_String(v) else v for v in val] - subst_kw[key] = val - - files, exports = self._get_SConscript_filenames(ls, subst_kw) - subst_kw['exports'] = exports - return _SConscript(self.fs, *files, **subst_kw) - - def SConscriptChdir(self, flag): - global sconscript_chdir - sconscript_chdir = flag - - def SetOption(self, name, value): - name = self.subst(name) - SCons.Script.Main.SetOption(name, value) - -# -# -# -SCons.Environment.Environment = SConsEnvironment - -def Configure(*args, **kw): - if not SCons.Script.sconscript_reading: - raise SCons.Errors.UserError("Calling Configure from Builders is not supported.") - kw['_depth'] = 1 - return SCons.SConf.SConf(*args, **kw) - -# It's very important that the DefaultEnvironmentCall() class stay in this -# file, with the get_calling_namespaces() function, the compute_exports() -# function, the Frame class and the SConsEnvironment.Export() method. -# These things make up the calling stack leading up to the actual global -# Export() or SConscript() call that the user issued. We want to allow -# users to export local variables that they define, like so: -# -# def func(): -# x = 1 -# Export('x') -# -# To support this, the get_calling_namespaces() function assumes that -# the *first* stack frame that's not from this file is the local frame -# for the Export() or SConscript() call. - -_DefaultEnvironmentProxy = None - -def get_DefaultEnvironmentProxy(): - global _DefaultEnvironmentProxy - if not _DefaultEnvironmentProxy: - default_env = SCons.Defaults.DefaultEnvironment() - _DefaultEnvironmentProxy = SCons.Environment.NoSubstitutionProxy(default_env) - return _DefaultEnvironmentProxy - -class DefaultEnvironmentCall: - """A class that implements "global function" calls of - Environment methods by fetching the specified method from the - DefaultEnvironment's class. Note that this uses an intermediate - proxy class instead of calling the DefaultEnvironment method - directly so that the proxy can override the subst() method and - thereby prevent expansion of construction variables (since from - the user's point of view this was called as a global function, - with no associated construction environment).""" - def __init__(self, method_name, subst=0): - self.method_name = method_name - if subst: - self.factory = SCons.Defaults.DefaultEnvironment - else: - self.factory = get_DefaultEnvironmentProxy - def __call__(self, *args, **kw): - env = self.factory() - method = getattr(env, self.method_name) - return method(*args, **kw) - - -def BuildDefaultGlobals(): - """ - Create a dictionary containing all the default globals for - SConstruct and SConscript files. - """ - - global GlobalDict - if GlobalDict is None: - GlobalDict = {} - - import SCons.Script - d = SCons.Script.__dict__ - def not_a_module(m, d=d, mtype=type(SCons.Script)): - return not isinstance(d[m], mtype) - for m in filter(not_a_module, dir(SCons.Script)): - GlobalDict[m] = d[m] - - return GlobalDict.copy() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Script/__init__.py b/scons/scons-local-4.1.0/SCons/Script/__init__.py deleted file mode 100644 index dff15673b..000000000 --- a/scons/scons-local-4.1.0/SCons/Script/__init__.py +++ /dev/null @@ -1,424 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""The main() function used by the scons script. - -Architecturally, this *is* the scons script, and will likely only be -called from the external "scons" wrapper. Consequently, anything here -should not be, or be considered, part of the build engine. If it's -something that we expect other software to want to use, it should go in -some other module. If it's specific to the "scons" script invocation, -it goes here. -""" - -import time -start_time = time.time() - -import collections -import os -from io import StringIO - -import sys - -# Special chicken-and-egg handling of the "--debug=memoizer" flag: -# -# SCons.Memoize contains a metaclass implementation that affects how -# the other classes are instantiated. The Memoizer may add shim methods -# to classes that have methods that cache computed values in order to -# count and report the hits and misses. -# -# If we wait to enable the Memoization until after we've parsed the -# command line options normally, it will be too late, because the Memoizer -# will have already analyzed the classes that it's Memoizing and decided -# to not add the shims. So we use a special-case, up-front check for -# the "--debug=memoizer" flag and enable Memoizer before we import any -# of the other modules that use it. - -_args = sys.argv + os.environ.get('SCONSFLAGS', '').split() -if "--debug=memoizer" in _args: - import SCons.Memoize - import SCons.Warnings - try: - SCons.Memoize.EnableMemoization() - except SCons.Warnings.SConsWarning: - # Some warning was thrown. Arrange for it to be displayed - # or not after warnings are configured. - from . import Main - exc_type, exc_value, tb = sys.exc_info() - Main.delayed_warnings.append((exc_type, exc_value)) -del _args - -import SCons.Action -import SCons.Builder -import SCons.Environment -import SCons.Node.FS -import SCons.Platform -import SCons.Platform.virtualenv -import SCons.Scanner -import SCons.SConf -import SCons.Subst -import SCons.Tool -import SCons.Util -import SCons.Variables -import SCons.Defaults - -from . import Main - -main = Main.main - -# The following are global class definitions and variables that used to -# live directly in this module back before 0.96.90, when it contained -# a lot of code. Some SConscript files in widely-distributed packages -# (Blender is the specific example) actually reached into SCons.Script -# directly to use some of these. Rather than break those SConscript -# files, we're going to propagate these names into the SCons.Script -# namespace here. -# -# Some of these are commented out because it's *really* unlikely anyone -# used them, but we're going to leave the comment here to try to make -# it obvious what to do if the situation arises. -BuildTask = Main.BuildTask -CleanTask = Main.CleanTask -QuestionTask = Main.QuestionTask -#PrintHelp = Main.PrintHelp -#SConscriptSettableOptions = Main.SConscriptSettableOptions - -AddOption = Main.AddOption -PrintHelp = Main.PrintHelp -GetOption = Main.GetOption -SetOption = Main.SetOption -Progress = Main.Progress -GetBuildFailures = Main.GetBuildFailures - -#keep_going_on_error = Main.keep_going_on_error -#print_dtree = Main.print_dtree -#print_explanations = Main.print_explanations -#print_includes = Main.print_includes -#print_objects = Main.print_objects -#print_time = Main.print_time -#print_tree = Main.print_tree -#memory_stats = Main.memory_stats -#ignore_errors = Main.ignore_errors -#sconscript_time = Main.sconscript_time -#command_time = Main.command_time -#exit_status = Main.exit_status -#profiling = Main.profiling -#repositories = Main.repositories - -from . import SConscript -_SConscript = SConscript - -call_stack = _SConscript.call_stack - -# -Action = SCons.Action.Action -AddMethod = SCons.Util.AddMethod -AllowSubstExceptions = SCons.Subst.SetAllowableExceptions -Builder = SCons.Builder.Builder -Configure = _SConscript.Configure -Environment = SCons.Environment.Environment -#OptParser = SCons.SConsOptions.OptParser -FindPathDirs = SCons.Scanner.FindPathDirs -Platform = SCons.Platform.Platform -Virtualenv = SCons.Platform.virtualenv.Virtualenv -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 - - -# Action factories. -Chmod = SCons.Defaults.Chmod -Copy = SCons.Defaults.Copy -Delete = SCons.Defaults.Delete -Mkdir = SCons.Defaults.Mkdir -Move = SCons.Defaults.Move -Touch = SCons.Defaults.Touch - -# Pre-made, public scanners. -CScanner = SCons.Tool.CScanner -DScanner = SCons.Tool.DScanner -DirScanner = SCons.Defaults.DirScanner -ProgramScanner = SCons.Tool.ProgramScanner -SourceFileScanner = SCons.Tool.SourceFileScanner - -# Functions we might still convert to Environment methods. -CScan = SCons.Defaults.CScan -DefaultEnvironment = SCons.Defaults.DefaultEnvironment - -# Other variables we provide. -class TargetList(collections.UserList): - def _do_nothing(self, *args, **kw): - pass - def _add_Default(self, list): - self.extend(list) - def _clear(self): - del self[:] - -ARGUMENTS = {} -ARGLIST = [] -BUILD_TARGETS = TargetList() -COMMAND_LINE_TARGETS = [] -DEFAULT_TARGETS = [] - -# BUILD_TARGETS can be modified in the SConscript files. If so, we -# want to treat the modified BUILD_TARGETS list as if they specified -# targets on the command line. To do that, though, we need to know if -# BUILD_TARGETS was modified through "official" APIs or by hand. We do -# this by updating two lists in parallel, the documented BUILD_TARGETS -# list, above, and this internal _build_plus_default targets list which -# should only have "official" API changes. Then Script/Main.py can -# compare these two afterwards to figure out if the user added their -# own targets to BUILD_TARGETS. -_build_plus_default = TargetList() - -def _Add_Arguments(alist): - for arg in alist: - a, b = arg.split('=', 1) - ARGUMENTS[a] = b - ARGLIST.append((a, b)) - -def _Add_Targets(tlist): - if tlist: - COMMAND_LINE_TARGETS.extend(tlist) - BUILD_TARGETS.extend(tlist) - BUILD_TARGETS._add_Default = BUILD_TARGETS._do_nothing - BUILD_TARGETS._clear = BUILD_TARGETS._do_nothing - _build_plus_default.extend(tlist) - _build_plus_default._add_Default = _build_plus_default._do_nothing - _build_plus_default._clear = _build_plus_default._do_nothing - -def _Set_Default_Targets_Has_Been_Called(d, fs): - return DEFAULT_TARGETS - -def _Set_Default_Targets_Has_Not_Been_Called(d, fs): - if d is None: - d = [fs.Dir('.')] - return d - -_Get_Default_Targets = _Set_Default_Targets_Has_Not_Been_Called - -def _Set_Default_Targets(env, tlist): - global DEFAULT_TARGETS - global _Get_Default_Targets - _Get_Default_Targets = _Set_Default_Targets_Has_Been_Called - for t in tlist: - if t is None: - # Delete the elements from the list in-place, don't - # reassign an empty list to DEFAULT_TARGETS, so that the - # variables will still point to the same object we point to. - del DEFAULT_TARGETS[:] - BUILD_TARGETS._clear() - _build_plus_default._clear() - elif isinstance(t, SCons.Node.Node): - DEFAULT_TARGETS.append(t) - BUILD_TARGETS._add_Default([t]) - _build_plus_default._add_Default([t]) - else: - nodes = env.arg2nodes(t, env.fs.Entry) - DEFAULT_TARGETS.extend(nodes) - BUILD_TARGETS._add_Default(nodes) - _build_plus_default._add_Default(nodes) - -# -help_text = None - -def HelpFunction(text, append=False): - global help_text - if help_text is None: - if append: - s = StringIO() - PrintHelp(s) - help_text = s.getvalue() - s.close() - else: - help_text = "" - - help_text= help_text + text - - -# -# Will be non-zero if we are reading an SConscript file. -sconscript_reading = 0 - -_no_missing_sconscript = False -_warn_missing_sconscript_deprecated = True - -def set_missing_sconscript_error(flag=1): - """Set behavior on missing file in SConscript() call. - - Returns: - previous value - """ - global _no_missing_sconscript - old = _no_missing_sconscript - _no_missing_sconscript = flag - return old - - -def Variables(files=None, args=ARGUMENTS): - return SCons.Variables.Variables(files, args) - - -# The list of global functions to add to the SConscript name space -# that end up calling corresponding methods or Builders in the -# DefaultEnvironment(). -GlobalDefaultEnvironmentFunctions = [ - # Methods from the SConsEnvironment class, above. - 'Default', - 'EnsurePythonVersion', - 'EnsureSConsVersion', - 'Exit', - 'Export', - 'GetLaunchDir', - 'Help', - 'Import', - #'SConscript', is handled separately, below. - 'SConscriptChdir', - - # Methods from the Environment.Base class. - 'AddPostAction', - 'AddPreAction', - 'Alias', - 'AlwaysBuild', - 'CacheDir', - 'Clean', - #The Command() method is handled separately, below. - 'Decider', - 'Depends', - 'Dir', - 'NoClean', - 'NoCache', - 'Entry', - 'Execute', - 'File', - 'FindFile', - 'FindInstalledFiles', - 'FindSourceFiles', - 'Flatten', - 'GetBuildPath', - 'Glob', - 'Ignore', - 'Install', - 'InstallAs', - 'InstallVersionedLib', - 'Literal', - 'Local', - 'ParseDepends', - 'Precious', - 'PyPackageDir', - 'Repository', - 'Requires', - 'SConsignFile', - 'SideEffect', - 'Split', - 'Tag', - 'Value', - 'VariantDir', -] - -GlobalDefaultBuilders = [ - # Supported builders. - 'CFile', - 'CXXFile', - 'DVI', - 'Jar', - 'Java', - 'JavaH', - 'Library', - 'LoadableModule', - 'M4', - 'MSVSProject', - 'Object', - 'PCH', - 'PDF', - 'PostScript', - 'Program', - 'RES', - 'RMIC', - 'SharedLibrary', - 'SharedObject', - 'StaticLibrary', - 'StaticObject', - 'Substfile', - 'Tar', - 'Textfile', - 'TypeLibrary', - 'Zip', - 'Package', -] - -for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders: - exec ("%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))) -del name - -# There are a handful of variables that used to live in the -# Script/SConscript.py module that some SConscript files out there were -# accessing directly as SCons.Script.SConscript.*. The problem is that -# "SConscript" in this namespace is no longer a module, it's a global -# function call--or more precisely, an object that implements a global -# function call through the default Environment. Nevertheless, we can -# maintain backwards compatibility for SConscripts that were reaching in -# this way by hanging some attributes off the "SConscript" object here. -SConscript = _SConscript.DefaultEnvironmentCall('SConscript') - -# Make SConscript look enough like the module it used to be so -# that pychecker doesn't barf. -SConscript.__name__ = 'SConscript' - -SConscript.Arguments = ARGUMENTS -SConscript.ArgList = ARGLIST -SConscript.BuildTargets = BUILD_TARGETS -SConscript.CommandLineTargets = COMMAND_LINE_TARGETS -SConscript.DefaultTargets = DEFAULT_TARGETS - -# The global Command() function must be handled differently than the -# global functions for other construction environment methods because -# we want people to be able to use Actions that must expand $TARGET -# and $SOURCE later, when (and if) the Action is invoked to build -# the target(s). We do this with the subst=1 argument, which creates -# a DefaultEnvironmentCall instance that wraps up a normal default -# construction environment that performs variable substitution, not a -# proxy that doesn't. -# -# There's a flaw here, though, because any other $-variables on a command -# line will *also* be expanded, each to a null string, but that should -# only be a problem in the unusual case where someone was passing a '$' -# on a command line and *expected* the $ to get through to the shell -# because they were calling Command() and not env.Command()... This is -# unlikely enough that we're going to leave this as is and cross that -# bridge if someone actually comes to it. -Command = _SConscript.DefaultEnvironmentCall('Command', subst=1) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Subst.py b/scons/scons-local-4.1.0/SCons/Subst.py deleted file mode 100644 index ea756ffec..000000000 --- a/scons/scons-local-4.1.0/SCons/Subst.py +++ /dev/null @@ -1,972 +0,0 @@ -# MIT License -# -# Copyright 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 string substitution.""" - -import collections -import re -from inspect import signature -import SCons.Errors - -from SCons.Util import is_String, is_Sequence - -# Indexed by the SUBST_* constants below. -_strconv = [ - SCons.Util.to_String_for_subst, - SCons.Util.to_String_for_subst, - SCons.Util.to_String_for_signature, -] - -AllowableExceptions = (IndexError, NameError) - - -def SetAllowableExceptions(*excepts): - global AllowableExceptions - AllowableExceptions = [_f for _f in excepts if _f] - - -def raise_exception(exception, target, s): - name = exception.__class__.__name__ - msg = "%s `%s' trying to evaluate `%s'" % (name, exception, s) - if target: - raise SCons.Errors.BuildError(target[0], msg) - else: - raise SCons.Errors.UserError(msg) - - -class Literal: - """A wrapper for a string. If you use this object wrapped - around a string, then it will be interpreted as literal. - When passed to the command interpreter, all special - characters will be escaped.""" - def __init__(self, lstr): - self.lstr = lstr - - def __str__(self): - return self.lstr - - def escape(self, escape_func): - return escape_func(self.lstr) - - def for_signature(self): - return self.lstr - - def is_literal(self): - return 1 - - def __eq__(self, other): - if not isinstance(other, Literal): - return False - return self.lstr == other.lstr - - def __neq__(self, other): - return not self.__eq__(other) - - def __hash__(self): - return hash(self.lstr) - -class SpecialAttrWrapper: - """This is a wrapper for what we call a 'Node special attribute.' - This is any of the attributes of a Node that we can reference from - Environment variable substitution, such as $TARGET.abspath or - $SOURCES[1].filebase. We implement the same methods as Literal - so we can handle special characters, plus a for_signature method, - such that we can return some canonical string during signature - calculation to avoid unnecessary rebuilds.""" - - def __init__(self, lstr, for_signature=None): - """The for_signature parameter, if supplied, will be the - canonical string we return from for_signature(). Else - we will simply return lstr.""" - self.lstr = lstr - if for_signature: - self.forsig = for_signature - else: - self.forsig = lstr - - def __str__(self): - return self.lstr - - def escape(self, escape_func): - return escape_func(self.lstr) - - def for_signature(self): - return self.forsig - - def is_literal(self): - return 1 - -def quote_spaces(arg): - """Generic function for putting double quotes around any string that - has white space in it.""" - if ' ' in arg or '\t' in arg: - return '"%s"' % arg - else: - return str(arg) - -class CmdStringHolder(collections.UserString): - """This is a special class used to hold strings generated by - scons_subst() and scons_subst_list(). It defines a special method - escape(). When passed a function with an escape algorithm for a - particular platform, it will return the contained string with the - proper escape sequences inserted. - """ - def __init__(self, cmd, literal=None): - collections.UserString.__init__(self, cmd) - self.literal = literal - - def is_literal(self): - return self.literal - - def escape(self, escape_func, quote_func=quote_spaces): - """Escape the string with the supplied function. The - function is expected to take an arbitrary string, then - return it with all special characters escaped and ready - for passing to the command interpreter. - - After calling this function, the next call to str() will - return the escaped string. - """ - - if self.is_literal(): - return escape_func(self.data) - elif ' ' in self.data or '\t' in self.data: - return quote_func(self.data) - else: - return self.data - -def escape_list(mylist, escape_func): - """Escape a list of arguments by running the specified escape_func - on every object in the list that has an escape() method.""" - def escape(obj, escape_func=escape_func): - try: - e = obj.escape - except AttributeError: - return obj - else: - return e(escape_func) - return list(map(escape, mylist)) - -class NLWrapper: - """A wrapper class that delays turning a list of sources or targets - into a NodeList until it's needed. The specified function supplied - when the object is initialized is responsible for turning raw nodes - into proxies that implement the special attributes like .abspath, - .source, etc. This way, we avoid creating those proxies just - "in case" someone is going to use $TARGET or the like, and only - go through the trouble if we really have to. - - In practice, this might be a wash performance-wise, but it's a little - cleaner conceptually... - """ - - def __init__(self, list, func): - self.list = list - self.func = func - def _return_nodelist(self): - return self.nodelist - def _gen_nodelist(self): - mylist = self.list - if mylist is None: - mylist = [] - elif not is_Sequence(mylist): - mylist = [mylist] - # The map(self.func) call is what actually turns - # a list into appropriate proxies. - self.nodelist = SCons.Util.NodeList(list(map(self.func, mylist))) - self._create_nodelist = self._return_nodelist - return self.nodelist - _create_nodelist = _gen_nodelist - - -class Targets_or_Sources(collections.UserList): - """A class that implements $TARGETS or $SOURCES expansions by in turn - 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 collections.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 - collections.UserList methods in practice. - """ - def __init__(self, nl): - self.nl = nl - def __getattr__(self, attr): - nl = self.nl._create_nodelist() - return getattr(nl, attr) - def __getitem__(self, i): - nl = self.nl._create_nodelist() - return nl[i] - def __getslice__(self, i, j): - nl = self.nl._create_nodelist() - i = max(i, 0); j = max(j, 0) - return nl[i:j] - def __str__(self): - nl = self.nl._create_nodelist() - return str(nl) - def __repr__(self): - nl = self.nl._create_nodelist() - return repr(nl) - -class Target_or_Source: - """A class that implements $TARGET or $SOURCE expansions by in turn - wrapping a NLWrapper. This class handles the different methods used - to access an individual proxy Node, calling the NLWrapper to create - a proxy on demand. - """ - def __init__(self, nl): - self.nl = nl - def __getattr__(self, attr): - nl = self.nl._create_nodelist() - try: - nl0 = nl[0] - except IndexError: - # If there is nothing in the list, then we have no attributes to - # pass through, so raise AttributeError for everything. - raise AttributeError("NodeList has no attribute: %s" % attr) - return getattr(nl0, attr) - def __str__(self): - nl = self.nl._create_nodelist() - if nl: - return str(nl[0]) - return '' - def __repr__(self): - nl = self.nl._create_nodelist() - if nl: - return repr(nl[0]) - return '' - -class NullNodeList(SCons.Util.NullSeq): - def __call__(self, *args, **kwargs): return '' - def __str__(self): return '' - -NullNodesList = NullNodeList() - -def subst_dict(target, source): - """Create a dictionary for substitution of special - construction variables. - - This translates the following special arguments: - - target - the target (object or array of objects), - used to generate the TARGET and TARGETS - construction variables - - source - the source (object or array of objects), - used to generate the SOURCES and SOURCE - construction variables - """ - dict = {} - - if target: - 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) - - # This is a total cheat, but hopefully this dictionary goes - # away soon anyway. We just let these expand to $TARGETS - # because that's "good enough" for the use of ToolSurrogates - # (see test/ToolSurrogate.py) to generate documentation. - dict['CHANGED_TARGETS'] = '$TARGETS' - dict['UNCHANGED_TARGETS'] = '$TARGETS' - else: - dict['TARGETS'] = NullNodesList - dict['TARGET'] = NullNodesList - - if source: - def get_src_subst_proxy(node): - try: - rfile = node.rfile - except AttributeError: - pass - else: - node = rfile() - 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) - - # This is a total cheat, but hopefully this dictionary goes - # away soon anyway. We just let these expand to $TARGETS - # because that's "good enough" for the use of ToolSurrogates - # (see test/ToolSurrogate.py) to generate documentation. - dict['CHANGED_SOURCES'] = '$SOURCES' - dict['UNCHANGED_SOURCES'] = '$SOURCES' - else: - dict['SOURCES'] = NullNodesList - dict['SOURCE'] = NullNodesList - - return dict - - -class StringSubber: - """A class to construct the results of a scons_subst() call. - - This binds a specific construction environment, mode, target and - source with two methods (substitute() and expand()) that handle - the expansion. - """ - def __init__(self, env, mode, conv, gvars): - self.env = env - self.mode = mode - self.conv = conv - self.gvars = gvars - - def expand(self, s, lvars): - """Expand a single "token" as necessary, returning an - appropriate string containing the expansion. - - This handles expanding different types of things (strings, - lists, callables) appropriately. It calls the wrapper - substitute() method to re-expand things as necessary, so that - the results of expansions of side-by-side strings still get - re-evaluated separately, not smushed together. - """ - if is_String(s): - try: - s0, s1 = s[:2] - except (IndexError, ValueError): - return s - if s0 != '$': - return s - if s1 == '$': - # In this case keep the double $'s which we'll later - # swap for a single dollar sign as we need to retain - # this information to properly avoid matching "$("" when - # the actual text was "$$("" (or "$)"" when "$$)"" ) - return '$$' - elif s1 in '()': - return s - else: - key = s[1:] - if key[0] == '{' or '.' in key: - if key[0] == '{': - key = key[1:-1] - - # Store for error messages if we fail to expand the - # value - old_s = s - s = None - if key in lvars: - s = lvars[key] - elif key in self.gvars: - s = self.gvars[key] - else: - try: - s = eval(key, self.gvars, lvars) - except KeyboardInterrupt: - raise - except Exception as e: - if e.__class__ in AllowableExceptions: - return '' - raise_exception(e, lvars['TARGETS'], old_s) - - if s is None and NameError not in AllowableExceptions: - raise_exception(NameError(key), lvars['TARGETS'], old_s) - elif s is None: - return '' - - # Before re-expanding the result, handle - # recursive expansion by copying the local - # variable dictionary and overwriting a null - # string for the value of the variable name - # we just expanded. - # - # This could potentially be optimized by only - # copying lvars when s contains more expansions, - # but lvars is usually supposed to be pretty - # small, and deeply nested variable expansions - # are probably more the exception than the norm, - # so it should be tolerable for now. - lv = lvars.copy() - var = key.split('.')[0] - lv[var] = '' - return self.substitute(s, lv) - elif is_Sequence(s): - def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars): - return conv(substitute(l, lvars)) - return list(map(func, s)) - elif callable(s): - # SCons has the unusual Null class where any __getattr__ call returns it's self, - # which does not work the signature module, and the Null class returns an empty - # string if called on, so we make an exception in this condition for Null class - if (isinstance(s, SCons.Util.Null) or - set(signature(s).parameters.keys()) == set(['target', 'source', 'env', 'for_signature'])): - s = s(target=lvars['TARGETS'], - source=lvars['SOURCES'], - env=self.env, - for_signature=(self.mode != SUBST_CMD)) - else: - # This probably indicates that it's a callable - # object that doesn't match our calling arguments - # (like an Action). - if self.mode == SUBST_RAW: - return s - s = self.conv(s) - return self.substitute(s, lvars) - elif s is None: - return '' - else: - return s - - def substitute(self, args, lvars): - """Substitute expansions in an argument or list of arguments. - - This serves as a wrapper for splitting up a string into - 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): - return self.conv(self.expand(match.group(1), lvars)) - result = _dollar_exps.sub(sub_match, args) - except TypeError: - # If the internal conversion routine doesn't return - # strings (it could be overridden to return Nodes, for - # example), then the 1.5.2 re module will throw this - # exception. Back off to a slower, general-purpose - # algorithm that works for all data types. - args = _separate_args.findall(args) - result = [] - for a in args: - result.append(self.conv(self.expand(a, lvars))) - if len(result) == 1: - result = result[0] - else: - result = ''.join(map(str, result)) - return result - else: - return self.expand(args, lvars) - - -class ListSubber(collections.UserList): - """A class to construct the results of a scons_subst_list() call. - - Like StringSubber, this class binds a specific construction - environment, mode, target and source with two methods - (substitute() and expand()) that handle the expansion. - - In addition, however, this class is used to track the state of - the result(s) we're gathering so we can do the appropriate thing - whenever we have to append another word to the result--start a new - line, start a new word, append to the current word, etc. We do - this by setting the "append" attribute to the right method so - that our wrapper methods only need ever call ListSubber.append(), - and the rest of the object takes care of doing the right thing - internally. - """ - def __init__(self, env, mode, conv, gvars): - collections.UserList.__init__(self, []) - self.env = env - self.mode = mode - self.conv = conv - self.gvars = gvars - - if self.mode == SUBST_RAW: - self.add_strip = lambda x: self.append(x) - else: - self.add_strip = lambda x: None - self.in_strip = None - self.next_line() - - def expanded(self, s): - """Determines if the string s requires further expansion. - - Due to the implementation of ListSubber expand will call - itself 2 additional times for an already expanded string. This - method is used to determine if a string is already fully - expanded and if so exit the loop early to prevent these - recursive calls. - """ - if not is_String(s) or isinstance(s, CmdStringHolder): - return False - - s = str(s) # in case it's a UserString - return _separate_args.findall(s) is None - - def expand(self, s, lvars, within_list): - """Expand a single "token" as necessary, appending the - expansion to the current result. - - This handles expanding different types of things (strings, - lists, callables) appropriately. It calls the wrapper - substitute() method to re-expand things as necessary, so that - the results of expansions of side-by-side strings still get - re-evaluated separately, not smushed together. - """ - - if is_String(s): - try: - s0, s1 = s[:2] - except (IndexError, ValueError): - self.append(s) - return - if s0 != '$': - self.append(s) - return - if s1 == '$': - self.append('$') - elif s1 == '(': - self.open_strip('$(') - elif s1 == ')': - self.close_strip('$)') - else: - key = s[1:] - if key[0] == '{' or key.find('.') >= 0: - if key[0] == '{': - key = key[1:-1] - - # Store for error messages if we fail to expand the - # value - old_s = s - s = None - if key in lvars: - s = lvars[key] - elif key in self.gvars: - s = self.gvars[key] - else: - try: - s = eval(key, self.gvars, lvars) - except KeyboardInterrupt: - raise - except Exception as e: - if e.__class__ in AllowableExceptions: - return - raise_exception(e, lvars['TARGETS'], old_s) - - if s is None and NameError not in AllowableExceptions: - raise_exception(NameError(), lvars['TARGETS'], old_s) - elif s is None: - return - - # If the string is already full expanded there's no - # need to continue recursion. - if self.expanded(s): - self.append(s) - return - - # Before re-expanding the result, handle - # recursive expansion by copying the local - # variable dictionary and overwriting a null - # string for the value of the variable name - # we just expanded. - lv = lvars.copy() - var = key.split('.')[0] - lv[var] = '' - self.substitute(s, lv, 0) - self.this_word() - elif is_Sequence(s): - for a in s: - self.substitute(a, lvars, 1) - self.next_word() - elif callable(s): - # SCons has the unusual Null class where any __getattr__ call returns it's self, - # which does not work the signature module, and the Null class returns an empty - # string if called on, so we make an exception in this condition for Null class - if (isinstance(s, SCons.Util.Null) or - set(signature(s).parameters.keys()) == set(['target', 'source', 'env', 'for_signature'])): - s = s(target=lvars['TARGETS'], - source=lvars['SOURCES'], - env=self.env, - for_signature=(self.mode != SUBST_CMD)) - else: - # This probably indicates that it's a callable - # object that doesn't match our calling arguments - # (like an Action). - if self.mode == SUBST_RAW: - self.append(s) - return - s = self.conv(s) - self.substitute(s, lvars, within_list) - elif s is None: - self.this_word() - else: - self.append(s) - - def substitute(self, args, lvars, within_list): - """Substitute expansions in an argument or list of arguments. - - This serves as a wrapper for splitting up a string into - separate tokens. - """ - - 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': - if '\n' in a: - self.next_line() - elif within_list: - self.append(a) - else: - self.next_word() - else: - self.expand(a, lvars, within_list) - else: - self.expand(args, lvars, within_list) - - def next_line(self): - """Arrange for the next word to start a new line. This - is like starting a new word, except that we have to append - another line to the result.""" - collections.UserList.append(self, []) - self.next_word() - - def this_word(self): - """Arrange for the next word to append to the end of the - current last word in the result.""" - self.append = self.add_to_current_word - - def next_word(self): - """Arrange for the next word to start a new word.""" - self.append = self.add_new_word - - def add_to_current_word(self, x): - """Append the string x to the end of the current last word - in the result. If that is not possible, then just add - it as a new word. Make sure the entire concatenated string - inherits the object attributes of x (in particular, the - escape function) by wrapping it as CmdStringHolder.""" - - if not self.in_strip or self.mode != SUBST_SIG: - try: - current_word = self[-1][-1] - except IndexError: - self.add_new_word(x) - else: - # All right, this is a hack and it should probably - # be refactored out of existence in the future. - # The issue is that we want to smoosh words together - # and make one file name that gets escaped if - # we're expanding something like foo$EXTENSION, - # but we don't want to smoosh them together if - # it's something like >$TARGET, because then we'll - # treat the '>' like it's part of the file name. - # So for now, just hard-code looking for the special - # command-line redirection characters... - try: - last_char = str(current_word)[-1] - except IndexError: - last_char = '\0' - if last_char in '<>|': - self.add_new_word(x) - else: - y = current_word + x - - # We used to treat a word appended to a literal - # as a literal itself, but this caused problems - # with interpreting quotes around space-separated - # targets on command lines. Removing this makes - # none of the "substantive" end-to-end tests fail, - # so we'll take this out but leave it commented - # for now in case there's a problem not covered - # by the test cases and we need to resurrect this. - #literal1 = self.literal(self[-1][-1]) - #literal2 = self.literal(x) - y = self.conv(y) - if is_String(y): - #y = CmdStringHolder(y, literal1 or literal2) - y = CmdStringHolder(y, None) - self[-1][-1] = y - - def add_new_word(self, x): - if not self.in_strip or self.mode != SUBST_SIG: - literal = self.literal(x) - x = self.conv(x) - if is_String(x): - x = CmdStringHolder(x, literal) - self[-1].append(x) - self.append = self.add_to_current_word - - def literal(self, x): - try: - l = x.is_literal - except AttributeError: - return None - else: - return l() - - def open_strip(self, x): - """Handle the "open strip" $( token.""" - self.add_strip(x) - self.in_strip = 1 - - def close_strip(self, x): - """Handle the "close strip" $) token.""" - self.add_strip(x) - self.in_strip = None - - -# Constants for the "mode" parameter to scons_subst_list() and -# scons_subst(). SUBST_RAW gives the raw command line. SUBST_CMD -# gives a command line suitable for passing to a shell. SUBST_SIG -# gives a command line appropriate for calculating the signature -# of a command line...if this changes, we should rebuild. -SUBST_CMD = 0 -SUBST_RAW = 1 -SUBST_SIG = 2 - -_rm = re.compile(r'\$[()]') - -# Note the pattern below only matches $( or $) when there is no -# preceeding $. (Thus the (? 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. - - This is *the* main guts of the DAG walk. We loop through the - list of candidates, looking for something that has no un-built - children (i.e., that is a leaf Node or has dependencies that are - all leaf Nodes or up-to-date). Candidate Nodes are re-scanned - (both the target Node itself and its sources, which are always - scanned in the context of a given target) to discover implicit - dependencies. A Node that must wait for some children to be - built will be put back on the candidates list after the children - have finished building. A Node that has been put back on the - candidates list in this way may have itself (or its sources) - re-scanned, in order to handle generated header files (e.g.) and - the implicit dependencies therein. - - Note that this method does not do any signature calculation or - up-to-date check itself. All of that is handled by the Task - class. This is purely concerned with the dependency graph walk. - """ - - self.ready_exc = None - - T = self.trace - if T: T.write('\n' + self.trace_message('Looking for a node to evaluate')) - - while True: - 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.attributes, 'stats'): - node.attributes.stats = Stats() - StatsNodes.append(node) - S = node.attributes.stats - S.considered = S.considered + 1 - else: - S = None - - if T: T.write(self.trace_message(' Considering node %s and its children:' % self.trace_node(node))) - - 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(self.trace_message(' already handled (executed)')) - continue - - executor = node.get_executor() - - try: - children = executor.get_all_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(self.trace_message(' SystemExit')) - return node - except Exception as e: - # We had a problem just trying to figure out the - # children (like a child couldn't be linked in to a - # 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(self.trace_message(' exception %s while scanning children.\n' % e)) - return node - - children_not_visited = [] - children_pending = set() - children_not_ready = [] - children_failed = False - - for child in chain(executor.get_all_prerequisites(), children): - 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). - if children_not_visited: - if len(children_not_visited) > 1: - 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: - for n in executor.get_action_targets(): - n.set_state(NODE_FAILED) - - if S: S.child_failed = S.child_failed + 1 - if T: T.write(self.trace_message('****** %s\n' % self.trace_node(node))) - continue - - 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 - - # 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))))) - - if T: - 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: - wait_side_effects = False - for se in executor.get_action_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 - 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(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 - - def next_task(self): - """ - Returns the next task to be executed. - - This simply asks for the next Node to be evaluated, and then wraps - it in the specific Task subclass with which we were initialized. - """ - node = self._find_next_ready_node() - - if node is None: - return None - - executor = node.get_executor() - if executor is None: - return None - - tlist = executor.get_all_targets() - - task = self.tasker(self, tlist, node in self.original_top, node) - try: - task.make_ready() - except Exception as e : - # We had a problem just trying to get this task ready (like - # a child couldn't be linked 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() - - if self.ready_exc: - task.exception_set(self.ready_exc) - - self.ready_exc = None - - 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 len(to_visit): - node = to_visit.pop() - 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 - # taskmaster 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 - - nclist = [(n, find_cycle([n], set())) for n in self.pending_children] - - genuine_cycles = [ - node for node,cycle in nclist - if cycle or node.get_state() != NODE_EXECUTED - ] - 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 + " " + " -> ".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) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/386asm.py b/scons/scons-local-4.1.0/SCons/Tool/386asm.py deleted file mode 100644 index 51738ebc1..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/386asm.py +++ /dev/null @@ -1,61 +0,0 @@ -"""SCons.Tool.386asm - -Tool specification for the 386ASM assembler for the Phar Lap ETS embedded -operating system. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.PharLapCommon import addPharLapPaths -import SCons.Util - -as_module = __import__('as', globals(), locals(), [], 1) - -def generate(env): - """Add Builders and construction variables for ar to an Environment.""" - as_module.generate(env) - - env['AS'] = '386asm' - env['ASFLAGS'] = SCons.Util.CLVar('') - env['ASPPFLAGS'] = '$ASFLAGS' - env['ASCOM'] = '$AS $ASFLAGS $SOURCES -o $TARGET' - env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES -o $TARGET' - - addPharLapPaths(env) - -def exists(env): - return env.Detect('386asm') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/DCommon.py b/scons/scons-local-4.1.0/SCons/Tool/DCommon.py deleted file mode 100644 index 128e56165..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/DCommon.py +++ /dev/null @@ -1,64 +0,0 @@ -# MIT License -# -# Copyright 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.Tool.DCommon - -Common code for the various D tools. - -Coded by Russel Winder (russel@winder.org.uk) -2012-09-06 -""" - -import os.path - - -def isD(env, source): - if not source: - return 0 - for s in source: - if s.sources: - ext = os.path.splitext(str(s.sources[0]))[1] - if ext == '.d': - return 1 - return 0 - - -def addDPATHToEnv(env, executable): - dPath = env.WhereIs(executable) - if dPath: - phobosDir = dPath[:dPath.rindex(executable)] + '/../src/phobos' - if os.path.isdir(phobosDir): - env.Append(DPATH=[phobosDir]) - - -def allAtOnceEmitter(target, source, env): - if env['DC'] in ('ldc2', 'dmd'): - env.SideEffect(str(target[0]) + '.o', target[0]) - env.Clean(target[0], str(target[0]) + '.o') - return target, source - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/FortranCommon.py b/scons/scons-local-4.1.0/SCons/Tool/FortranCommon.py deleted file mode 100644 index 16b75e26e..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/FortranCommon.py +++ /dev/null @@ -1,279 +0,0 @@ -"""SCons.Tool.FortranCommon - -Stuff for processing Fortran, common to all fortran dialects. - -""" - -# MIT License -# -# Copyright 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. - -import re -import os.path - -import SCons.Action -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 ([], []) - # This has to match the def_regex in the Fortran scanner - mod_regex = r"""(?i)^\s*MODULE\s+(?!PROCEDURE|SUBROUTINE|FUNCTION|PURE|ELEMENTAL)(\w+)""" - cre = re.compile(mod_regex,re.M) - # Retrieve all USE'd module names - modules = cre.findall(node.get_text_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 = [x.lower() + suffix for x in modules] - for m in modules: - target.append(env.fs.File(m, moddir)) - return (target, source) - -def FortranEmitter(target, source, env): - import SCons.Defaults - target, source = _fortranEmitter(target, source, env) - return SCons.Defaults.StaticObjectEmitter(target, source, env) - -def ShFortranEmitter(target, source, env): - import SCons.Defaults - 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 = s.upper() - upper_suffixes = [_.upper() for _ in 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 '%sFLAGS' % dialect not in env: - env['%sFLAGS' % dialect] = SCons.Util.CLVar('') - - if 'SH%sFLAGS' % dialect not in env: - 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 'INC%sPREFIX' % dialect not in env: - env['INC%sPREFIX' % dialect] = '$INCPREFIX' - - if 'INC%sSUFFIX' % dialect not in env: - 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_f03_to_env(env): - """Add Builders and construction variables for f03 to an Environment.""" - try: - F03Suffixes = env['F03FILESUFFIXES'] - except KeyError: - F03Suffixes = ['.f03'] - - #print("Adding %s to f95 suffixes" % F95Suffixes) - try: - F03PPSuffixes = env['F03PPFILESUFFIXES'] - except KeyError: - F03PPSuffixes = [] - - DialectAddToEnv(env, "F03", F03Suffixes, F03PPSuffixes, - support_module = 1) - -def add_f08_to_env(env): - """Add Builders and construction variables for f08 to an Environment.""" - try: - F08Suffixes = env['F08FILESUFFIXES'] - except KeyError: - F08Suffixes = ['.f08'] - - try: - F08PPSuffixes = env['F08PPFILESUFFIXES'] - except KeyError: - F08PPSuffixes = [] - - DialectAddToEnv(env, "F08", F08Suffixes, F08PPSuffixes, - 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) - add_f03_to_env(env) - add_f08_to_env(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/GettextCommon.py b/scons/scons-local-4.1.0/SCons/Tool/GettextCommon.py deleted file mode 100644 index 5da4517b5..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/GettextCommon.py +++ /dev/null @@ -1,469 +0,0 @@ -"""SCons.Tool.GettextCommon module - -Used by several tools of `gettext` toolset. -""" - -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Warnings -import re - - -############################################################################# -class XgettextToolWarning(SCons.Warnings.SConsWarning): pass - - -class XgettextNotFound(XgettextToolWarning): pass - - -class MsginitToolWarning(SCons.Warnings.SConsWarning): pass - - -class MsginitNotFound(MsginitToolWarning): pass - - -class MsgmergeToolWarning(SCons.Warnings.SConsWarning): pass - - -class MsgmergeNotFound(MsgmergeToolWarning): pass - - -class MsgfmtToolWarning(SCons.Warnings.SConsWarning): pass - - -class MsgfmtNotFound(MsgfmtToolWarning): pass - - -############################################################################# -SCons.Warnings.enableWarningClass(XgettextToolWarning) -SCons.Warnings.enableWarningClass(XgettextNotFound) -SCons.Warnings.enableWarningClass(MsginitToolWarning) -SCons.Warnings.enableWarningClass(MsginitNotFound) -SCons.Warnings.enableWarningClass(MsgmergeToolWarning) -SCons.Warnings.enableWarningClass(MsgmergeNotFound) -SCons.Warnings.enableWarningClass(MsgfmtToolWarning) -SCons.Warnings.enableWarningClass(MsgfmtNotFound) - - -############################################################################# - -############################################################################# -class _POTargetFactory: - """ A factory of `PO` target files. - - Factory defaults differ from these of `SCons.Node.FS.FS`. We set `precious` - (this is required by builders and actions gettext) and `noclean` flags by - default for all produced nodes. - """ - - def __init__(self, env, nodefault=True, alias=None, precious=True - , noclean=True): - """ Object constructor. - - **Arguments** - - - *env* (`SCons.Environment.Environment`) - - *nodefault* (`boolean`) - if `True`, produced nodes will be ignored - from default target `'.'` - - *alias* (`string`) - if provided, produced nodes will be automatically - added to this alias, and alias will be set as `AlwaysBuild` - - *precious* (`boolean`) - if `True`, the produced nodes will be set as - `Precious`. - - *noclen* (`boolean`) - if `True`, the produced nodes will be excluded - from `Clean`. - """ - self.env = env - self.alias = alias - self.precious = precious - self.noclean = noclean - self.nodefault = nodefault - - def _create_node(self, name, factory, directory=None, create=1): - """ Create node, and set it up to factory settings. """ - import SCons.Util - node = factory(name, directory, create) - node.set_noclean(self.noclean) - node.set_precious(self.precious) - if self.nodefault: - self.env.Ignore('.', node) - if self.alias: - self.env.AlwaysBuild(self.env.Alias(self.alias, node)) - return node - - def Entry(self, name, directory=None, create=1): - """ Create `SCons.Node.FS.Entry` """ - return self._create_node(name, self.env.fs.Entry, directory, create) - - def File(self, name, directory=None, create=1): - """ Create `SCons.Node.FS.File` """ - return self._create_node(name, self.env.fs.File, directory, create) - - -############################################################################# - -############################################################################# -_re_comment = re.compile(r'(#[^\n\r]+)$', re.M) -_re_lang = re.compile(r'([a-zA-Z0-9_]+)', re.M) - - -############################################################################# -def _read_linguas_from_files(env, linguas_files=None): - """ Parse `LINGUAS` file and return list of extracted languages """ - import SCons.Util - import SCons.Environment - global _re_comment - global _re_lang - if not SCons.Util.is_List(linguas_files) \ - and not SCons.Util.is_String(linguas_files) \ - and not isinstance(linguas_files, SCons.Node.FS.Base) \ - and linguas_files: - # If, linguas_files==True or such, then read 'LINGUAS' file. - linguas_files = ['LINGUAS'] - if linguas_files is None: - return [] - fnodes = env.arg2nodes(linguas_files) - linguas = [] - for fnode in fnodes: - contents = _re_comment.sub("", fnode.get_text_contents()) - ls = [l for l in _re_lang.findall(contents) if l] - linguas.extend(ls) - return linguas - - -############################################################################# - -############################################################################# -from SCons.Builder import BuilderBase - - -############################################################################# -class _POFileBuilder(BuilderBase): - """ `PO` file builder. - - This is multi-target single-source builder. In typical situation the source - is single `POT` file, e.g. `messages.pot`, and there are multiple `PO` - targets to be updated from this `POT`. We must run - `SCons.Builder.BuilderBase._execute()` separatelly for each target to track - dependencies separatelly for each target file. - - **NOTE**: if we call `SCons.Builder.BuilderBase._execute(.., target, ...)` - with target being list of all targets, all targets would be rebuilt each time - one of the targets from this list is missing. This would happen, for example, - when new language `ll` enters `LINGUAS_FILE` (at this moment there is no - `ll.po` file yet). To avoid this, we override - `SCons.Builder.BuilerBase._execute()` and call it separatelly for each - target. Here we also append to the target list the languages read from - `LINGUAS_FILE`. - """ - - # - # * The argument for overriding _execute(): We must use environment with - # builder overrides applied (see BuilderBase.__init__(). Here it comes for - # free. - # * The argument against using 'emitter': The emitter is called too late - # by BuilderBase._execute(). If user calls, for example: - # - # env.POUpdate(LINGUAS_FILE = 'LINGUAS') - # - # the builder throws error, because it is called with target=None, - # source=None and is trying to "generate" sources or target list first. - # If user calls - # - # env.POUpdate(['foo', 'baz'], LINGUAS_FILE = 'LINGUAS') - # - # the env.BuilderWrapper() calls our builder with target=None, - # source=['foo', 'baz']. The BuilderBase._execute() then splits execution - # and execute iterativelly (recursion) self._execute(None, source[i]). - # After that it calls emitter (which is quite too late). The emitter is - # also called in each iteration, what makes things yet worse. - def __init__(self, env, **kw): - if 'suffix' not in kw: - kw['suffix'] = '$POSUFFIX' - if 'src_suffix' not in kw: - kw['src_suffix'] = '$POTSUFFIX' - if 'src_builder' not in kw: - kw['src_builder'] = '_POTUpdateBuilder' - if 'single_source' not in kw: - kw['single_source'] = True - alias = None - if 'target_alias' in kw: - alias = kw['target_alias'] - del kw['target_alias'] - if 'target_factory' not in kw: - kw['target_factory'] = _POTargetFactory(env, alias=alias).File - BuilderBase.__init__(self, **kw) - - def _execute(self, env, target, source, *args, **kw): - """ Execute builder's actions. - - Here we append to `target` the languages read from `$LINGUAS_FILE` and - apply `SCons.Builder.BuilderBase._execute()` separatelly to each target. - The arguments and return value are same as for - `SCons.Builder.BuilderBase._execute()`. - """ - import SCons.Util - import SCons.Node - linguas_files = None - if 'LINGUAS_FILE' in env and env['LINGUAS_FILE']: - linguas_files = env['LINGUAS_FILE'] - # This prevents endless recursion loop (we'll be invoked once for - # each target appended here, we must not extend the list again). - env['LINGUAS_FILE'] = None - linguas = _read_linguas_from_files(env, linguas_files) - if SCons.Util.is_List(target): - target.extend(linguas) - elif target is not None: - target = [target] + linguas - else: - target = linguas - if not target: - # Let the SCons.BuilderBase to handle this patologic situation - return BuilderBase._execute(self, env, target, source, *args, **kw) - # The rest is ours - if not SCons.Util.is_List(target): - target = [target] - result = [] - for tgt in target: - r = BuilderBase._execute(self, env, [tgt], source, *args, **kw) - result.extend(r) - if linguas_files is not None: - env['LINGUAS_FILE'] = linguas_files - return SCons.Node.NodeList(result) - - -############################################################################# - -import SCons.Environment - - -############################################################################# -def _translate(env, target=None, source=SCons.Environment._null, *args, **kw): - """ Function for `Translate()` pseudo-builder """ - if target is None: target = [] - pot = env.POTUpdate(None, source, *args, **kw) - po = env.POUpdate(target, pot, *args, **kw) - return po - - -############################################################################# - -############################################################################# -class RPaths: - """ Callable object, which returns pathnames relative to SCons current - working directory. - - It seems like `SCons.Node.FS.Base.get_path()` returns absolute paths - for nodes that are outside of current working directory (`env.fs.getcwd()`). - Here, we often have `SConscript`, `POT` and `PO` files within `po/` - directory and source files (e.g. `*.c`) outside of it. When generating `POT` - template file, references to source files are written to `POT` template, so - a translator may later quickly jump to appropriate source file and line from - its `PO` editor (e.g. `poedit`). Relative paths in `PO` file are usually - interpreted by `PO` editor as paths relative to the place, where `PO` file - lives. The absolute paths would make resultant `POT` file nonportable, as - the references would be correct only on the machine, where `POT` file was - recently re-created. For such reason, we need a function, which always - returns relative paths. This is the purpose of `RPaths` callable object. - - The `__call__` method returns paths relative to current working directory, but - we assume, that *xgettext(1)* is run from the directory, where target file is - going to be created. - - Note, that this may not work for files distributed over several hosts or - across different drives on windows. We assume here, that single local - filesystem holds both source files and target `POT` templates. - - Intended use of `RPaths` - in `xgettext.py`:: - - def generate(env): - from GettextCommon import RPaths - ... - sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET, SOURCES)} $)' - env.Append( - ... - XGETTEXTCOM = 'XGETTEXT ... ' + sources, - ... - XgettextRPaths = RPaths(env) - ) - """ - - # NOTE: This callable object returns pathnames of dirs/files relative to - # current working directory. The pathname remains relative also for entries - # that are outside of current working directory (node, that - # SCons.Node.FS.File and siblings return absolute path in such case). For - # simplicity we compute path relative to current working directory, this - # seems be enough for our purposes (don't need TARGET variable and - # SCons.Defaults.Variable_Caller stuff). - - def __init__(self, env): - """ Initialize `RPaths` callable object. - - **Arguments**: - - - *env* - a `SCons.Environment.Environment` object, defines *current - working dir*. - """ - self.env = env - - # FIXME: I'm not sure, how it should be implemented (what the *args are in - # general, what is **kw). - def __call__(self, nodes, *args, **kw): - """ Return nodes' paths (strings) relative to current working directory. - - **Arguments**: - - - *nodes* ([`SCons.Node.FS.Base`]) - list of nodes. - - *args* - currently unused. - - *kw* - currently unused. - - **Returns**: - - - Tuple of strings, which represent paths relative to current working - directory (for given environment). - """ - import os - import SCons.Node.FS - rpaths = () - cwd = self.env.fs.getcwd().get_abspath() - for node in nodes: - rpath = None - if isinstance(node, SCons.Node.FS.Base): - rpath = os.path.relpath(node.get_abspath(), cwd) - # FIXME: Other types possible here? - if rpath is not None: - rpaths += (rpath,) - return rpaths - - -############################################################################# - -############################################################################# -def _init_po_files(target, source, env): - """ Action function for `POInit` builder. """ - nop = lambda target, source, env: 0 - if 'POAUTOINIT' in env: - autoinit = env['POAUTOINIT'] - else: - autoinit = False - # Well, if everything outside works well, this loop should do single - # iteration. Otherwise we are rebuilding all the targets even, if just - # one has changed (but is this our fault?). - for tgt in target: - if not tgt.exists(): - if autoinit: - action = SCons.Action.Action('$MSGINITCOM', '$MSGINITCOMSTR') - else: - msg = 'File ' + repr(str(tgt)) + ' does not exist. ' \ - + 'If you are a translator, you can create it through: \n' \ - + '$MSGINITCOM' - action = SCons.Action.Action(nop, msg) - status = action([tgt], source, env) - if status: return status - return 0 - - -############################################################################# - -############################################################################# -def _detect_xgettext(env): - """ Detects *xgettext(1)* binary """ - if 'XGETTEXT' in env: - return env['XGETTEXT'] - xgettext = env.Detect('xgettext') - if xgettext: - return xgettext - raise SCons.Errors.StopError(XgettextNotFound, "Could not detect xgettext") - return None - - -############################################################################# -def _xgettext_exists(env): - return _detect_xgettext(env) - - -############################################################################# - -############################################################################# -def _detect_msginit(env): - """ Detects *msginit(1)* program. """ - if 'MSGINIT' in env: - return env['MSGINIT'] - msginit = env.Detect('msginit') - if msginit: - return msginit - raise SCons.Errors.StopError(MsginitNotFound, "Could not detect msginit") - return None - - -############################################################################# -def _msginit_exists(env): - return _detect_msginit(env) - - -############################################################################# - -############################################################################# -def _detect_msgmerge(env): - """ Detects *msgmerge(1)* program. """ - if 'MSGMERGE' in env: - return env['MSGMERGE'] - msgmerge = env.Detect('msgmerge') - if msgmerge: - return msgmerge - raise SCons.Errors.StopError(MsgmergeNotFound, "Could not detect msgmerge") - return None - - -############################################################################# -def _msgmerge_exists(env): - return _detect_msgmerge(env) - - -############################################################################# - -############################################################################# -def _detect_msgfmt(env): - """ Detects *msgmfmt(1)* program. """ - if 'MSGFMT' in env: - return env['MSGFMT'] - msgfmt = env.Detect('msgfmt') - if msgfmt: - return msgfmt - raise SCons.Errors.StopError(MsgfmtNotFound, "Could not detect msgfmt") - return None - - -############################################################################# -def _msgfmt_exists(env): - return _detect_msgfmt(env) - - -############################################################################# - -############################################################################# -def tool_list(platform, env): - """ List tools that shall be generated by top-level `gettext` tool """ - return ['xgettext', 'msginit', 'msgmerge', 'msgfmt'] - -############################################################################# diff --git a/scons/scons-local-4.1.0/SCons/Tool/JavaCommon.py b/scons/scons-local-4.1.0/SCons/Tool/JavaCommon.py deleted file mode 100644 index d869b38fd..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/JavaCommon.py +++ /dev/null @@ -1,513 +0,0 @@ -"""SCons.Tool.JavaCommon - -Stuff for processing Java. - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import os.path -import re -import glob - -java_parsing = 1 - -default_java_version = '1.4' - -# a switch for which jdk versions to use the Scope state for smarter -# anonymous inner class parsing. -scopeStateVersions = ('1.8',) - -# Glob patterns for use in finding where the JDK is. -# These are pairs, *dir_glob used in the general case, -# *version_dir_glob if matching only a specific version. -# For now only used for Windows. -java_win32_dir_glob = 'C:/Program Files*/Java/jdk*/bin' -# On windows, since Java 9, there is a dash between 'jdk' and the version -# string that wasn't there before. this glob should catch either way. -java_win32_version_dir_glob = 'C:/Program Files*/Java/jdk*%s*/bin' - -# Glob patterns for use in finding where the JDK headers are. -# These are pairs, *dir_glob used in the general case, -# *version_dir_glob if matching only a specific version. -java_macos_include_dir_glob = '/System/Library/Frameworks/JavaVM.framework/Headers/' -java_macos_version_include_dir_glob = '/System/Library/Frameworks/JavaVM.framework/Versions/%s*/Headers/' - -java_linux_include_dirs_glob = [ - '/usr/lib/jvm/default-java/include', - '/usr/lib/jvm/java-*/include' -] -# Need to match path like below (from Centos 7) -# /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64/include/ -java_linux_version_include_dirs_glob = [ - '/usr/lib/jvm/java-*-sun-%s*/include', - '/usr/lib/jvm/java-%s*-openjdk*/include', - '/usr/java/jdk%s*/include' -] - -if java_parsing: - # Parse Java files for class names. - # - # This is a really cool parser from Charles Crain - # that finds appropriate class names in Java source. - - # A regular expression that will find, in a java file: - # newlines; - # double-backslashes; - # a single-line comment "//"; - # single or double quotes preceeded by a backslash; - # 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 "[]". - # Lambda function symbols: -> - _reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"{\};.()]|' + - r'\d*\.\d*|[A-Za-z_][\w$.]*|<[A-Za-z_]\w+>|' + - r'/\*|\*/|\[\]|->)') - - - class OuterState: - """The initial state for parsing a Java file for classes, - interfaces, and anonymous inner classes.""" - - def __init__(self, version=default_java_version): - - if version not in ('1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', - '1.8', '5', '6', '9.0', '10.0', '11.0', '12.0'): - msg = "Java version %s not supported" % version - raise NotImplementedError(msg) - - self.version = version - self.listClasses = [] - self.listOutputs = [] - self.stackBrackets = [] - self.brackets = 0 - self.nextAnon = 1 - self.localClasses = [] - self.stackAnonClassBrackets = [] - self.anonStacksStack = [[0]] - self.package = None - - def trace(self): - pass - - def __getClassState(self): - try: - return self.classState - except AttributeError: - ret = ClassState(self) - self.classState = ret - return ret - - def __getPackageState(self): - try: - return self.packageState - except AttributeError: - ret = PackageState(self) - self.packageState = ret - return ret - - def __getAnonClassState(self): - try: - return self.anonState - except AttributeError: - self.outer_state = self - ret = SkipState(1, AnonClassState(self)) - self.anonState = ret - return ret - - def __getSkipState(self): - try: - return self.skipState - except AttributeError: - ret = SkipState(1, self) - self.skipState = ret - return ret - - def _getAnonStack(self): - return self.anonStacksStack[-1] - - def openBracket(self): - self.brackets = self.brackets + 1 - - def closeBracket(self): - self.brackets = self.brackets - 1 - if len(self.stackBrackets) and \ - self.brackets == self.stackBrackets[-1]: - self.listOutputs.append('$'.join(self.listClasses)) - self.localClasses.pop() - self.listClasses.pop() - self.anonStacksStack.pop() - self.stackBrackets.pop() - if len(self.stackAnonClassBrackets) and \ - self.brackets == self.stackAnonClassBrackets[-1] and \ - self.version not in scopeStateVersions: - self._getAnonStack().pop() - self.stackAnonClassBrackets.pop() - - def parseToken(self, token): - if token[:2] == '//': - return IgnoreState('\n', self) - elif token == '/*': - return IgnoreState('*/', self) - elif token == '{': - self.openBracket() - elif token == '}': - self.closeBracket() - elif token in ['"', "'"]: - return IgnoreState(token, self) - elif token == "new": - # anonymous inner class - if len(self.listClasses) > 0: - return self.__getAnonClassState() - return self.__getSkipState() # Skip the class name - elif token in ['class', 'interface', 'enum']: - if len(self.listClasses) == 0: - self.nextAnon = 1 - self.stackBrackets.append(self.brackets) - return self.__getClassState() - elif token == 'package': - return self.__getPackageState() - elif token == '.': - # Skip the attribute, it might be named "class", in which - # case we don't want to treat the following token as - # an inner class name... - return self.__getSkipState() - return self - - def addAnonClass(self): - """Add an anonymous inner class""" - if self.version in ('1.1', '1.2', '1.3', '1.4'): - clazz = self.listClasses[0] - self.listOutputs.append('%s$%d' % (clazz, self.nextAnon)) - elif self.version in ('1.5', '1.6', '1.7', '1.8', '5', '6', '9.0', '10.0', '11.0', '12.0'): - self.stackAnonClassBrackets.append(self.brackets) - className = [] - className.extend(self.listClasses) - self._getAnonStack()[-1] = self._getAnonStack()[-1] + 1 - for anon in self._getAnonStack(): - className.append(str(anon)) - self.listOutputs.append('$'.join(className)) - - self.nextAnon = self.nextAnon + 1 - self._getAnonStack().append(0) - - def setPackage(self, package): - self.package = package - - - class ScopeState: - """ - A state that parses code within a scope normally, - within the confines of a scope. - """ - - def __init__(self, old_state): - self.outer_state = old_state.outer_state - self.old_state = old_state - self.brackets = 0 - - def __getClassState(self): - try: - return self.classState - except AttributeError: - ret = ClassState(self) - self.classState = ret - return ret - - def __getAnonClassState(self): - try: - return self.anonState - except AttributeError: - ret = SkipState(1, AnonClassState(self)) - self.anonState = ret - return ret - - def __getSkipState(self): - try: - return self.skipState - except AttributeError: - ret = SkipState(1, self) - self.skipState = ret - return ret - - def openBracket(self): - self.brackets = self.brackets + 1 - - def closeBracket(self): - self.brackets = self.brackets - 1 - - def parseToken(self, token): - # if self.brackets == 0: - # return self.old_state.parseToken(token) - if token[:2] == '//': - return IgnoreState('\n', self) - elif token == '/*': - return IgnoreState('*/', self) - elif token == '{': - self.openBracket() - elif token == '}': - self.closeBracket() - if self.brackets == 0: - self.outer_state._getAnonStack().pop() - return self.old_state - elif token in ['"', "'"]: - return IgnoreState(token, self) - elif token == "new": - # anonymous inner class - return self.__getAnonClassState() - elif token == '.': - # Skip the attribute, it might be named "class", in which - # case we don't want to treat the following token as - # an inner class name... - return self.__getSkipState() - return self - - - class AnonClassState: - """A state that looks for anonymous inner classes.""" - - def __init__(self, old_state): - # outer_state is always an instance of OuterState - self.outer_state = old_state.outer_state - self.old_state = old_state - self.brace_level = 0 - - def parseToken(self, token): - # This is an anonymous class if and only if the next - # non-whitespace token is a bracket. Everything between - # braces should be parsed as normal java code. - if token[:2] == '//': - return IgnoreState('\n', self) - elif token == '/*': - 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 - if self.brace_level > 0: - if token == 'new': - # look further for anonymous inner class - return SkipState(1, AnonClassState(self)) - elif token in ['"', "'"]: - return IgnoreState(token, self) - elif token == ')': - self.brace_level = self.brace_level - 1 - return self - if token == '{': - self.outer_state.addAnonClass() - if self.outer_state.version in scopeStateVersions: - return ScopeState(old_state=self.old_state).parseToken(token) - return self.old_state.parseToken(token) - - - class SkipState: - """A state that will skip a specified number of tokens before - reverting to the previous state.""" - - def __init__(self, tokens_to_skip, old_state): - self.tokens_to_skip = tokens_to_skip - self.old_state = old_state - - def parseToken(self, token): - self.tokens_to_skip = self.tokens_to_skip - 1 - if self.tokens_to_skip < 1: - return self.old_state - return self - - - class ClassState: - """A state we go into when we hit a class or interface keyword.""" - - def __init__(self, outer_state): - # outer_state is always an instance of OuterState - self.outer_state = outer_state - - def parseToken(self, token): - # 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' - # https://github.com/SCons/scons/issues/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 - - - class IgnoreState: - """A state that will ignore all tokens until it gets to a - specified token.""" - - def __init__(self, ignore_until, old_state): - self.ignore_until = ignore_until - self.old_state = old_state - - def parseToken(self, token): - if self.ignore_until == token: - return self.old_state - return self - - - class PackageState: - """The state we enter when we encounter the package keyword. - We assume the next token will be the package name.""" - - def __init__(self, outer_state): - # outer_state is always an instance of OuterState - self.outer_state = outer_state - - def parseToken(self, token): - self.outer_state.setPackage(token) - return self.outer_state - - - def parse_java_file(fn, version=default_java_version): - with open(fn, 'r', encoding='utf-8') as f: - data = f.read() - return parse_java(data, version) - - - def parse_java(contents, version=default_java_version, trace=None): - """Parse a .java file and return a double of package directory, - plus a list of .class files that compiling that .java file will - produce""" - package = None - initial = OuterState(version) - currstate = initial - for token in _reToken.findall(contents): - # The regex produces a bunch of groups, but only one will - # have anything in it. - currstate = currstate.parseToken(token) - if trace: trace(token, currstate) - if initial.package: - package = initial.package.replace('.', os.sep) - return (package, initial.listOutputs) - -else: - # Don't actually parse Java files for class names. - # - # We might make this a configurable option in the future if - # Java-file parsing takes too long (although it shouldn't relative - # to how long the Java compiler itself seems to take...). - - def parse_java_file(fn): - """ "Parse" a .java file. - - This actually just splits the file name, so the assumption here - is that the file name matches the public class name, and that - the path to the file is the same as the package name. - """ - return os.path.split(fn) - - -def get_java_install_dirs(platform, version=None): - """ - Find the java jdk installation directories. - - This list is intended to supply as "default paths" for use when looking - up actual java binaries. - - :param platform: selector for search algorithm. - :param version: If specified, only look for java sdk's of this version - :return: list of default paths for java. - """ - - paths = [] - if platform == 'win32': - if version: - paths = glob.glob(java_win32_version_dir_glob % version) - else: - paths = glob.glob(java_win32_dir_glob) - else: - # other platforms, do nothing for now - pass - - return sorted(paths) - - -def get_java_include_paths(env, javac, version): - """ - Find java include paths for JNI building. - - :param env: construction environment, used to extract platform. - :param javac: path to detected javac. - :return: list of paths. - """ - - paths = [] - if not javac: - # there are no paths if we've not detected javac. - pass - elif env['PLATFORM'] == 'win32': - # on Windows, we have the right path to javac, so look locally - javac_bin_dir = os.path.dirname(javac) - java_inc_dir = os.path.normpath(os.path.join(javac_bin_dir, '..', 'include')) - paths = [java_inc_dir, os.path.join(java_inc_dir, 'win32')] - elif env['PLATFORM'] == 'darwin': - if not version: - paths = [java_macos_include_dir_glob] - else: - paths = sorted(glob.glob(java_macos_version_include_dir_glob % version)) - else: - base_paths = [] - if not version: - for p in java_linux_include_dirs_glob: - base_paths.extend(glob.glob(p)) - else: - for p in java_linux_version_include_dirs_glob: - base_paths.extend(glob.glob(p % version)) - - for p in base_paths: - paths.extend([p, os.path.join(p, 'linux')]) - - # print("PATHS:%s"%paths) - return paths - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/README b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/README deleted file mode 100644 index 226865197..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/README +++ /dev/null @@ -1,107 +0,0 @@ -This is the flow of the compiler detection logic: - -External to MSCommon: - - The Tool init modules, in their exists() routines, call -> msvc_exists(env) - -At the moment, those modules are: - SCons/Tool/midl.py - SCons/Tool/mslib.py - SCons/Tool/mslink.py - SCons/Tool/msvc.py - SCons/Tool/msvs.py - -env may contain a version request in MSVC_VERSION, but this is not used -in the detection that follows from msvc_exists(), only in the later -batch that starts with a call to msvc_setup_env(). - -Internal to MSCommon/vc.py: - -+ MSCommon/vc.py:msvc_exists: -| vcs = cached_get_installed_vcs(env) -| returns True if vcs > 0 -| -+-> MSCommon/vc.py:cached_get_installed_vcs: - | checks global if we've run previously, if so return it - | populate the global from -> get_installed_vcs(env) - | - +-> MSCommon/vc.py:get_installed_vcs: - | loop through "known" versions of msvc, granularity is maj.min - | check for product dir -> find_vc_pdir(env, ver) - | - +-> MSCommon/vc.py:find_vc_pdir: - | From the msvc-version to pdir mapping dict, get reg key base and value - | If value is none -> find_vc_pdir_vswhere(ver, env) - | - +-> MSCommon/vc.py:find_vc_pdir_vswhere: - | From the vc-version to VS-version mapping table get string - | Figure out where vswhere is -> msvc_find_vswhere() - | Use subprocess to call vswhere, return first line of match - / - | else get product directory from registry (<= 14.0) - / - | if we found one -> _check_cl_exists_in_vc_dir(env, pdir, ver) - | - +-> MSCommon/vc.py:_check_cl_exists_in_vc_dir: - | Figure out host/target pair - | if version > 14.0 get specific version by looking in - | pdir + Auxiliary/Build/Microsoft/VCToolsVersion/default.txt - | look for pdir + Tools/MSVC/{specver}/bin/host/target/cl.exe - | if 14.0 or less, "do older stuff" - -All of this just got us a yes-no answer on whether /some/ msvc version -exists, but does populate __INSTALLED_VCS_RUN with all of the top-level -versions as noted for get_installed_vcs - -Externally: - - Once a module's exists() has been called (or, in the case of - clang/clangxx, after the compiler has been detected by other means - - those still expect the rest of the msvc chain but not cl.exe) - the module's generate() function calls -> msvc_setup_env_once(env) - -Internally: - -+ MSCommon/vc.py:msvc_setup_env_once: -| checks for environment flag MSVC_SETUP_RUN -| if not, -> msvc_setup_env(env) and set flag -| -+-+ MSCommon/vc.py:msvc_setup_env: - | set ver from -> get_default_version(env) - | - +-+ MSCommon/vc.py:get_default_version: - | if no version specified in env.MSVC_VERSION: - | return first entry from -> cached_get_installed_vcs(env) - | else return requested version - / - | get script from MSVC_USE_SCRIPT if set to a filename - | -> script_env(script) - | - +-+ MSCommon/vc.py:script_env: - | return (possibly cached) script variables matching script arg - / - | else -> msvc_find_valid_batch_script(env, version) - | - +-+ MSCommon/vc.py:msvc_find_valid_batch_script: - | Build a list of plausible target values, and loop through - | look for host + target -> find_batch_file(env, ver, host, target) - | - +-+ MSCommon/vc.py:find_batch_file: - | call -> find_vc_pdir (see above) - | use the return to construct a version-biased batfile path, check - / - | if not found, try sdk scripts (unknown if this is still useful) - - -Problems: -- For VS >= 2017, VS and VS are not 1:1, there can be many VC for one VS -- For vswhere-ready versions, detection does not proceed beyond the - product level ("2019") into individual "features" (individual msvc) -- As documented for MSVC_VERSION, compilers can only be requested if versions - are from the set in _VCVER, so 14.1 but not 14.16 or 14.16.27023 -- Information found in the first pass (msvs_exists) isn't really - available anywhere except the cached version list, since we just - return true/false. -- Since msvc_exists chain of calls does not look at version, we - can proceed to compiler setup if *any* msvc was found, even if the - one requested wasn't found. diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/__init__.py b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/__init__.py deleted file mode 100644 index ee8f2bd3e..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -__doc__ = """ -Common functions for Microsoft Visual Studio and Visual C/C++. -""" - - -import SCons.Errors -import SCons.Platform.win32 -import SCons.Util - -from SCons.Tool.MSCommon.sdk import mssdk_exists, \ - mssdk_setup_env - -from SCons.Tool.MSCommon.vc import msvc_exists, \ - msvc_setup_env, \ - msvc_setup_env_once, \ - msvc_version_to_maj_min, \ - msvc_find_vswhere - -from SCons.Tool.MSCommon.vs import get_default_version, \ - get_vs_by_version, \ - merge_default_version, \ - msvs_exists, \ - query_versions - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/arch.py b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/arch.py deleted file mode 100644 index 0032422ef..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/arch.py +++ /dev/null @@ -1,66 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -__doc__ = """Module to define supported Windows chip architectures. -""" - - -class ArchDefinition: - """ - A class for defining architecture-specific settings and logic. - """ - def __init__(self, arch, synonyms=[]): - self.arch = arch - self.synonyms = synonyms - -SupportedArchitectureList = [ - ArchDefinition( - 'x86', - ['i386', 'i486', 'i586', 'i686'], - ), - - ArchDefinition( - 'x86_64', - ['AMD64', 'amd64', 'em64t', 'EM64T', 'x86_64'], - ), - - ArchDefinition( - 'ia64', - ['IA64'], - ), - - ArchDefinition( - 'arm', - ['ARM'], - ), - -] - -SupportedArchitectureMap = {} -for a in SupportedArchitectureList: - SupportedArchitectureMap[a.arch] = a - for s in a.synonyms: - SupportedArchitectureMap[s] = a - diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/common.py b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/common.py deleted file mode 100644 index 81004df81..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/common.py +++ /dev/null @@ -1,353 +0,0 @@ -""" -Common helper functions for working with the Microsoft tool chain. -""" -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import copy -import json -import os -import re -import subprocess -import sys - -import SCons.Util - -# SCONS_MSCOMMON_DEBUG is internal-use so undocumented: -# set to '-' to print to console, else set to filename to log to -LOGFILE = os.environ.get('SCONS_MSCOMMON_DEBUG') -if LOGFILE == '-': - def debug(message): - print(message) -elif LOGFILE: - import logging - modulelist = ( - # root module and parent/root module - 'MSCommon', 'Tool', - # python library and below: correct iff scons does not have a lib folder - 'lib', - # scons modules - 'SCons', 'test', 'scons' - ) - def get_relative_filename(filename, module_list): - if not filename: - return filename - for module in module_list: - try: - ind = filename.rindex(module) - return filename[ind:] - except ValueError: - pass - return filename - class _Debug_Filter(logging.Filter): - # custom filter for module relative filename - def filter(self, record): - relfilename = get_relative_filename(record.pathname, modulelist) - relfilename = relfilename.replace('\\', '/') - record.relfilename = relfilename - return True - logging.basicConfig( - # This looks like: - # 00109ms:MSCommon/vc.py:find_vc_pdir#447: - format=( - '%(relativeCreated)05dms' - ':%(relfilename)s' - ':%(funcName)s' - '#%(lineno)s' - ':%(message)s: ' - ), - filename=LOGFILE, - level=logging.DEBUG) - logger = logging.getLogger(name=__name__) - logger.addFilter(_Debug_Filter()) - debug = logger.debug -else: - def debug(x): return None - - -# SCONS_CACHE_MSVC_CONFIG is public, and is documented. -CONFIG_CACHE = os.environ.get('SCONS_CACHE_MSVC_CONFIG') -if CONFIG_CACHE in ('1', 'true', 'True'): - CONFIG_CACHE = os.path.join(os.path.expanduser('~'), '.scons_msvc_cache') - - -def read_script_env_cache(): - """ fetch cached msvc env vars if requested, else return empty dict """ - envcache = {} - if CONFIG_CACHE: - try: - with open(CONFIG_CACHE, 'r') as f: - envcache = json.load(f) - except FileNotFoundError: - # don't fail if no cache file, just proceed without it - pass - return envcache - - -def write_script_env_cache(cache): - """ write out cache of msvc env vars if requested """ - if CONFIG_CACHE: - try: - with open(CONFIG_CACHE, 'w') as f: - json.dump(cache, f, indent=2) - except TypeError: - # data can't serialize to json, don't leave partial file - os.remove(CONFIG_CACHE) - except IOError: - # can't write the file, just skip - pass - - -_is_win64 = None - - -def is_win64(): - """Return true if running on windows 64 bits. - - Works whether python itself runs in 64 bits or 32 bits.""" - # Unfortunately, python does not provide a useful way to determine - # if the underlying Windows OS is 32-bit or 64-bit. Worse, whether - # the Python itself is 32-bit or 64-bit affects what it returns, - # so nothing in sys.* or os.* help. - - # Apparently the best solution is to use env vars that Windows - # sets. If PROCESSOR_ARCHITECTURE is not x86, then the python - # process is running in 64 bit mode (on a 64-bit OS, 64-bit - # hardware, obviously). - # If this python is 32-bit but the OS is 64, Windows will set - # ProgramW6432 and PROCESSOR_ARCHITEW6432 to non-null. - # (Checking for HKLM\Software\Wow6432Node in the registry doesn't - # work, because some 32-bit installers create it.) - global _is_win64 - if _is_win64 is None: - # I structured these tests to make it easy to add new ones or - # add exceptions in the future, because this is a bit fragile. - _is_win64 = False - if os.environ.get('PROCESSOR_ARCHITECTURE', 'x86') != 'x86': - _is_win64 = True - if os.environ.get('PROCESSOR_ARCHITEW6432'): - _is_win64 = True - if os.environ.get('ProgramW6432'): - _is_win64 = True - return _is_win64 - - -def read_reg(value, hkroot=SCons.Util.HKEY_LOCAL_MACHINE): - return SCons.Util.RegGetValue(hkroot, value)[0] - - -def has_reg(value): - """Return True if the given key exists in HKEY_LOCAL_MACHINE, False - otherwise.""" - try: - SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, value) - ret = True - except SCons.Util.WinError: - ret = False - return ret - -# Functions for fetching environment variable settings from batch files. - - -def normalize_env(env, keys, force=False): - """Given a dictionary representing a shell environment, add the variables - from os.environ needed for the processing of .bat files; the keys are - controlled by the keys argument. - - It also makes sure the environment values are correctly encoded. - - If force=True, then all of the key values that exist are copied - into the returned dictionary. If force=false, values are only - copied if the key does not already exist in the copied dictionary. - - Note: the environment is copied.""" - normenv = {} - if env: - for k, v in env.items(): - normenv[k] = copy.deepcopy(v) - - for k in keys: - if k in os.environ and (force or k not in normenv): - normenv[k] = os.environ[k] - - # add some things to PATH to prevent problems: - # Shouldn't be necessary to add system32, since the default environment - # should include it, but keep this here to be safe (needed for reg.exe) - sys32_dir = os.path.join( - os.environ.get("SystemRoot", os.environ.get("windir", r"C:\Windows")), "System32" -) - if sys32_dir not in normenv["PATH"]: - normenv["PATH"] = normenv["PATH"] + os.pathsep + sys32_dir - - # Without Wbem in PATH, vcvarsall.bat has a "'wmic' is not recognized" - # error starting with Visual Studio 2017, although the script still - # seems to work anyway. - sys32_wbem_dir = os.path.join(sys32_dir, 'Wbem') - if sys32_wbem_dir not in normenv['PATH']: - normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_wbem_dir - - # Without Powershell in PATH, an internal call to a telemetry - # function (starting with a VS2019 update) can fail - # Note can also set VSCMD_SKIP_SENDTELEMETRY to avoid this. - sys32_ps_dir = os.path.join(sys32_dir, r'WindowsPowerShell\v1.0') - if sys32_ps_dir not in normenv['PATH']: - normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_ps_dir - - debug("PATH: %s" % normenv['PATH']) - return normenv - - -def get_output(vcbat, args=None, env=None): - """Parse the output of given bat file, with given args.""" - - if env is None: - # Create a blank environment, for use in launching the tools - env = SCons.Environment.Environment(tools=[]) - - # TODO: Hard-coded list of the variables that (may) need to be - # imported from os.environ[] for the chain of development batch - # files to execute correctly. One call to vcvars*.bat may - # end up running a dozen or more scripts, changes not only with - # each release but with what is installed at the time. We think - # in modern installations most are set along the way and don't - # need to be picked from the env, but include these for safety's sake. - # Any VSCMD variables definitely are picked from the env and - # control execution in interesting ways. - # Note these really should be unified - either controlled by vs.py, - # or synced with the the common_tools_var # settings in vs.py. - vs_vc_vars = [ - 'COMSPEC', # path to "shell" - 'VS160COMNTOOLS', # path to common tools for given version - 'VS150COMNTOOLS', - 'VS140COMNTOOLS', - 'VS120COMNTOOLS', - 'VS110COMNTOOLS', - 'VS100COMNTOOLS', - 'VS90COMNTOOLS', - 'VS80COMNTOOLS', - 'VS71COMNTOOLS', - 'VS70COMNTOOLS', - 'VS60COMNTOOLS', - 'VSCMD_DEBUG', # enable logging and other debug aids - 'VSCMD_SKIP_SENDTELEMETRY', - ] - env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False) - - if args: - debug("Calling '%s %s'" % (vcbat, args)) - popen = SCons.Action._subproc(env, - '"%s" %s & set' % (vcbat, args), - stdin='devnull', - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - else: - debug("Calling '%s'" % vcbat) - popen = SCons.Action._subproc(env, - '"%s" & set' % vcbat, - stdin='devnull', - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - - # Use the .stdout and .stderr attributes directly because the - # .communicate() method uses the threading module on Windows - # and won't work under Pythons not built with threading. - with popen.stdout: - stdout = popen.stdout.read() - with popen.stderr: - stderr = popen.stderr.read() - - # Extra debug logic, uncomment if necessary - # debug('stdout:%s' % stdout) - # debug('stderr:%s' % stderr) - - # Ongoing problems getting non-corrupted text led to this - # changing to "oem" from "mbcs" - the scripts run presumably - # attached to a console, so some particular rules apply. - # Unfortunately, "oem" not defined in Python 3.5, so get another way - if sys.version_info.major == 3 and sys.version_info.minor < 6: - from ctypes import windll - - OEM = "cp{}".format(windll.kernel32.GetConsoleOutputCP()) - else: - OEM = "oem" - if stderr: - # TODO: find something better to do with stderr; - # this at least prevents errors from getting swallowed. - sys.stderr.write(stderr.decode(OEM)) - if popen.wait() != 0: - raise IOError(stderr.decode(OEM)) - - return stdout.decode(OEM) - - -KEEPLIST = ( - "INCLUDE", - "LIB", - "LIBPATH", - "PATH", - "VSCMD_ARG_app_plat", - "VCINSTALLDIR", # needed by clang -VS 2017 and newer - "VCToolsInstallDir", # needed by clang - VS 2015 and older -) - - -def parse_output(output, keep=KEEPLIST): - """ - Parse output from running visual c++/studios vcvarsall.bat and running set - To capture the values listed in keep - """ - - # dkeep is a dict associating key: path_list, where key is one item from - # keep, and path_list the associated list of paths - dkeep = dict([(i, []) for i in keep]) - - # rdk will keep the regex to match the .bat file output line starts - rdk = {} - for i in keep: - rdk[i] = re.compile('%s=(.*)' % i, re.I) - - def add_env(rmatch, key, dkeep=dkeep): - path_list = rmatch.group(1).split(os.pathsep) - for path in path_list: - # Do not add empty paths (when a var ends with ;) - if path: - # XXX: For some reason, VC98 .bat file adds "" around the PATH - # values, and it screws up the environment later, so we strip - # it. - path = path.strip('"') - dkeep[key].append(str(path)) - - for line in output.splitlines(): - for k, value in rdk.items(): - match = value.match(line) - if match: - add_env(match, k) - - return dkeep - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/netframework.py b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/netframework.py deleted file mode 100644 index b40576a87..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/netframework.py +++ /dev/null @@ -1,83 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -__doc__ = """ -""" - -import os -import re -import SCons.Util - -from .common import read_reg, debug - -# Original value recorded by dcournapeau -_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot' -# On SGK's system -_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\Microsoft SDKs\.NETFramework\v2.0\InstallationFolder' - -def find_framework_root(): - # XXX: find it from environment (FrameworkDir) - try: - froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT) - debug("Found framework install root in registry: {}".format(froot)) - except SCons.Util.WinError as e: - debug("Could not read reg key {}".format(_FRAMEWORKDIR_HKEY_ROOT)) - return None - - if not os.path.exists(froot): - debug("{} not found on fs".format(froot)) - return None - - return froot - -def query_versions(): - froot = find_framework_root() - if froot: - contents = os.listdir(froot) - - l = re.compile('v[0-9]+.*') - versions = [e for e in contents if l.match(e)] - - def versrt(a,b): - # since version numbers aren't really floats... - aa = a[1:] - bb = b[1:] - aal = aa.split('.') - bbl = bb.split('.') - # sequence comparison in python is lexicographical - # which is exactly what we want. - # Note we sort backwards so the highest version is first. - return (aal > bbl) - (aal < bbl) - - versions.sort(versrt) - else: - versions = [] - - return versions - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/sdk.py b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/sdk.py deleted file mode 100644 index b76fbddf4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/sdk.py +++ /dev/null @@ -1,411 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -__doc__ = """Module to detect the Platform/Windows SDK - -PSDK 2003 R1 is the earliest version detected. -""" - -import os - -import SCons.Errors -import SCons.Util - -from .common import debug, read_reg - -# SDK Checks. This is of course a mess as everything else on MS platforms. Here -# is what we do to detect the SDK: -# -# For Windows SDK >= 6.0: just look into the registry entries: -# HKLM\Software\Microsoft\Microsoft SDKs\Windows -# All the keys in there are the available versions. -# -# For Platform SDK before 6.0 (2003 server R1 and R2, etc...), there does not -# seem to be any sane registry key, so the precise location is hardcoded. -# -# For versions below 2003R1, it seems the PSDK is included with Visual Studio? -# -# Also, per the following: -# http://benjamin.smedbergs.us/blog/tag/atl/ -# VC++ Professional comes with the SDK, VC++ Express does not. - -# Location of the SDK (checked for 6.1 only) -_CURINSTALLED_SDK_HKEY_ROOT = \ - r"Software\Microsoft\Microsoft SDKs\Windows\CurrentInstallFolder" - - -class SDKDefinition: - """ - An abstract base class for trying to find installed SDK directories. - """ - def __init__(self, version, **kw): - self.version = version - self.__dict__.update(kw) - - def find_sdk_dir(self): - """Try to find the MS SDK from the registry. - - Return None if failed or the directory does not exist. - """ - if not SCons.Util.can_read_reg: - debug('find_sdk_dir(): can not read registry') - return None - - hkey = self.HKEY_FMT % self.hkey_data - debug('find_sdk_dir(): checking registry:{}'.format(hkey)) - - try: - sdk_dir = read_reg(hkey) - except SCons.Util.WinError as e: - debug('find_sdk_dir(): no SDK registry key {}'.format(repr(hkey))) - return None - - debug('find_sdk_dir(): Trying SDK Dir: {}'.format(sdk_dir)) - - if not os.path.exists(sdk_dir): - debug('find_sdk_dir(): {} not on file system'.format(sdk_dir)) - return None - - ftc = os.path.join(sdk_dir, self.sanity_check_file) - if not os.path.exists(ftc): - debug("find_sdk_dir(): sanity check {} not found".format(ftc)) - return None - - return sdk_dir - - def get_sdk_dir(self): - """Return the MSSSDK given the version string.""" - try: - return self._sdk_dir - except AttributeError: - sdk_dir = self.find_sdk_dir() - self._sdk_dir = sdk_dir - return sdk_dir - - def get_sdk_vc_script(self,host_arch, target_arch): - """ Return the script to initialize the VC compiler installed by SDK - """ - - if host_arch == 'amd64' and target_arch == 'x86': - # No cross tools needed compiling 32 bits on 64 bit machine - host_arch=target_arch - - arch_string=target_arch - if host_arch != target_arch: - arch_string='%s_%s'%(host_arch,target_arch) - - debug("get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string, - host_arch, - target_arch)) - file=self.vc_setup_scripts.get(arch_string,None) - debug("get_sdk_vc_script():file:%s"%file) - return file - -class WindowsSDK(SDKDefinition): - """ - A subclass for trying to find installed Windows SDK directories. - """ - HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder' - def __init__(self, *args, **kw): - SDKDefinition.__init__(self, *args, **kw) - self.hkey_data = self.version - -class PlatformSDK(SDKDefinition): - """ - A subclass for trying to find installed Platform SDK directories. - """ - HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir' - def __init__(self, *args, **kw): - SDKDefinition.__init__(self, *args, **kw) - self.hkey_data = self.uuid - -# -# The list of VC initialization scripts installed by the SDK -# These should be tried if the vcvarsall.bat TARGET_ARCH fails -preSDK61VCSetupScripts = { 'x86' : r'bin\vcvars32.bat', - 'amd64' : r'bin\vcvarsamd64.bat', - 'x86_amd64': r'bin\vcvarsx86_amd64.bat', - 'x86_ia64' : r'bin\vcvarsx86_ia64.bat', - 'ia64' : r'bin\vcvarsia64.bat'} - -SDK61VCSetupScripts = {'x86' : r'bin\vcvars32.bat', - 'amd64' : r'bin\amd64\vcvarsamd64.bat', - 'x86_amd64': r'bin\x86_amd64\vcvarsx86_amd64.bat', - 'x86_ia64' : r'bin\x86_ia64\vcvarsx86_ia64.bat', - 'ia64' : r'bin\ia64\vcvarsia64.bat'} - -SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat', - 'amd64' : r'bin\vcvars64.bat', - 'x86_amd64': r'bin\vcvarsx86_amd64.bat', - 'x86_ia64' : r'bin\vcvarsx86_ia64.bat', - 'ia64' : r'bin\vcvarsia64.bat'} - -SDK100VCSetupScripts = {'x86' : r'bin\vcvars32.bat', - 'amd64' : r'bin\vcvars64.bat', - 'x86_amd64': r'bin\x86_amd64\vcvarsx86_amd64.bat', - 'x86_arm' : r'bin\x86_arm\vcvarsx86_arm.bat'} - - -# The list of support SDKs which we know how to detect. -# -# The first SDK found in the list is the one used by default if there -# are multiple SDKs installed. Barring good reasons to the contrary, -# this means we should list SDKs from most recent to oldest. -# -# If you update this list, update the documentation in Tool/mssdk.xml. -SupportedSDKList = [ - WindowsSDK('10.0A', - sanity_check_file=r'bin\SetEnv.Cmd', - include_subdir='include', - lib_subdir={ - 'x86' : ['lib'], - 'x86_64' : [r'lib\x64'], - 'ia64' : [r'lib\ia64'], - }, - vc_setup_scripts = SDK70VCSetupScripts, - ), - WindowsSDK('10.0', - sanity_check_file=r'bin\SetEnv.Cmd', - include_subdir='include', - lib_subdir={ - 'x86' : ['lib'], - 'x86_64' : [r'lib\x64'], - 'ia64' : [r'lib\ia64'], - }, - vc_setup_scripts = SDK70VCSetupScripts, - ), - WindowsSDK('7.1', - sanity_check_file=r'bin\SetEnv.Cmd', - include_subdir='include', - lib_subdir={ - 'x86' : ['lib'], - 'x86_64' : [r'lib\x64'], - 'ia64' : [r'lib\ia64'], - }, - vc_setup_scripts = SDK70VCSetupScripts, - ), - WindowsSDK('7.0A', - sanity_check_file=r'bin\SetEnv.Cmd', - include_subdir='include', - lib_subdir={ - 'x86' : ['lib'], - 'x86_64' : [r'lib\x64'], - 'ia64' : [r'lib\ia64'], - }, - vc_setup_scripts = SDK70VCSetupScripts, - ), - WindowsSDK('7.0', - sanity_check_file=r'bin\SetEnv.Cmd', - include_subdir='include', - lib_subdir={ - 'x86' : ['lib'], - 'x86_64' : [r'lib\x64'], - 'ia64' : [r'lib\ia64'], - }, - vc_setup_scripts = SDK70VCSetupScripts, - ), - WindowsSDK('6.1', - sanity_check_file=r'bin\SetEnv.Cmd', - include_subdir='include', - lib_subdir={ - 'x86' : ['lib'], - 'x86_64' : [r'lib\x64'], - 'ia64' : [r'lib\ia64'], - }, - vc_setup_scripts = SDK61VCSetupScripts, - ), - - WindowsSDK('6.0A', - sanity_check_file=r'include\windows.h', - include_subdir='include', - lib_subdir={ - 'x86' : ['lib'], - 'x86_64' : [r'lib\x64'], - 'ia64' : [r'lib\ia64'], - }, - vc_setup_scripts = preSDK61VCSetupScripts, - ), - - WindowsSDK('6.0', - sanity_check_file=r'bin\gacutil.exe', - include_subdir='include', - lib_subdir='lib', - vc_setup_scripts = preSDK61VCSetupScripts, - ), - - PlatformSDK('2003R2', - sanity_check_file=r'SetEnv.Cmd', - uuid="D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1", - vc_setup_scripts = preSDK61VCSetupScripts, - ), - - PlatformSDK('2003R1', - sanity_check_file=r'SetEnv.Cmd', - uuid="8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3", - vc_setup_scripts = preSDK61VCSetupScripts, - ), -] - -SupportedSDKMap = {} -for sdk in SupportedSDKList: - SupportedSDKMap[sdk.version] = sdk - - -# Finding installed SDKs isn't cheap, because it goes not only to the -# registry but also to the disk to sanity-check that there is, in fact, -# an SDK installed there and that the registry entry isn't just stale. -# Find this information once, when requested, and cache it. - -InstalledSDKList = None -InstalledSDKMap = None - -def get_installed_sdks(): - global InstalledSDKList - global InstalledSDKMap - debug('get_installed_sdks()') - if InstalledSDKList is None: - InstalledSDKList = [] - InstalledSDKMap = {} - for sdk in SupportedSDKList: - debug('trying to find SDK %s' % sdk.version) - if sdk.get_sdk_dir(): - debug('found SDK %s' % sdk.version) - InstalledSDKList.append(sdk) - InstalledSDKMap[sdk.version] = sdk - return InstalledSDKList - - -# We may be asked to update multiple construction environments with -# SDK information. When doing this, we check on-disk for whether -# the SDK has 'mfc' and 'atl' subdirectories. Since going to disk -# is expensive, cache results by directory. - -SDKEnvironmentUpdates = {} - -def set_sdk_by_directory(env, sdk_dir): - global SDKEnvironmentUpdates - debug('set_sdk_by_directory: Using dir:%s'%sdk_dir) - try: - env_tuple_list = SDKEnvironmentUpdates[sdk_dir] - except KeyError: - env_tuple_list = [] - SDKEnvironmentUpdates[sdk_dir] = env_tuple_list - - include_path = os.path.join(sdk_dir, 'include') - mfc_path = os.path.join(include_path, 'mfc') - atl_path = os.path.join(include_path, 'atl') - - if os.path.exists(mfc_path): - env_tuple_list.append(('INCLUDE', mfc_path)) - if os.path.exists(atl_path): - env_tuple_list.append(('INCLUDE', atl_path)) - env_tuple_list.append(('INCLUDE', include_path)) - - env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib'))) - env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib'))) - env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin'))) - - for variable, directory in env_tuple_list: - env.PrependENVPath(variable, directory) - -def get_sdk_by_version(mssdk): - if mssdk not in SupportedSDKMap: - raise SCons.Errors.UserError("SDK version {} is not supported".format(repr(mssdk))) - get_installed_sdks() - return InstalledSDKMap.get(mssdk) - -def get_default_sdk(): - """Set up the default Platform/Windows SDK.""" - get_installed_sdks() - if not InstalledSDKList: - return None - return InstalledSDKList[0] - -def mssdk_setup_env(env): - debug('mssdk_setup_env()') - if 'MSSDK_DIR' in env: - sdk_dir = env['MSSDK_DIR'] - if sdk_dir is None: - return - sdk_dir = env.subst(sdk_dir) - debug('mssdk_setup_env: Using MSSDK_DIR:{}'.format(sdk_dir)) - elif 'MSSDK_VERSION' in env: - sdk_version = env['MSSDK_VERSION'] - if sdk_version is None: - msg = "SDK version is specified as None" - raise SCons.Errors.UserError(msg) - sdk_version = env.subst(sdk_version) - mssdk = get_sdk_by_version(sdk_version) - if mssdk is None: - msg = "SDK version %s is not installed" % sdk_version - raise SCons.Errors.UserError(msg) - sdk_dir = mssdk.get_sdk_dir() - debug('mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir) - elif 'MSVS_VERSION' in env: - msvs_version = env['MSVS_VERSION'] - debug('mssdk_setup_env:Getting MSVS_VERSION from env:%s'%msvs_version) - if msvs_version is None: - debug('mssdk_setup_env thinks msvs_version is None') - return - msvs_version = env.subst(msvs_version) - from . import vs - msvs = vs.get_vs_by_version(msvs_version) - debug('mssdk_setup_env:msvs is :%s'%msvs) - if not msvs: - debug('mssdk_setup_env: no VS version detected, bailingout:%s'%msvs) - return - sdk_version = msvs.sdk_version - debug('msvs.sdk_version is %s'%sdk_version) - if not sdk_version: - return - mssdk = get_sdk_by_version(sdk_version) - if not mssdk: - mssdk = get_default_sdk() - if not mssdk: - return - sdk_dir = mssdk.get_sdk_dir() - debug('mssdk_setup_env: Using MSVS_VERSION:%s'%sdk_dir) - else: - mssdk = get_default_sdk() - if not mssdk: - return - sdk_dir = mssdk.get_sdk_dir() - debug('mssdk_setup_env: not using any env values. sdk_dir:%s'%sdk_dir) - - set_sdk_by_directory(env, sdk_dir) - - #print "No MSVS_VERSION: this is likely to be a bug" - -def mssdk_exists(version=None): - sdks = get_installed_sdks() - if version is None: - return len(sdks) > 0 - return version in sdks - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/vc.py b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/vc.py deleted file mode 100644 index 87a1064c4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/vc.py +++ /dev/null @@ -1,955 +0,0 @@ -# -# MIT License -# -# Copyright 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. -# -"""Module for Visual C/C++ detection and configuration. - -# TODO: -# * gather all the information from a single vswhere call instead -# of calling repeatedly (use json format?) -# * support passing/setting location for vswhere in env. -# * supported arch for versions: for old versions of batch file without -# argument, giving bogus argument cannot be detected, so we have to hardcode -# this here -# * print warning when msvc version specified but not found -# * find out why warning do not print -# * test on 64 bits XP + VS 2005 (and VS 6 if possible) -# * SDK -# * Assembly -""" - -import SCons.compat -import SCons.Util - -import subprocess -import os -import platform -from string import digits as string_digits -from subprocess import PIPE - -import SCons.Warnings -from SCons.Tool import find_program_path - -from . import common -from .common import CONFIG_CACHE, debug -from .sdk import get_installed_sdks - - -class VisualCException(Exception): - pass - -class UnsupportedVersion(VisualCException): - pass - -class MSVCUnsupportedHostArch(VisualCException): - pass - -class MSVCUnsupportedTargetArch(VisualCException): - pass - -class MissingConfiguration(VisualCException): - pass - -class NoVersionFound(VisualCException): - pass - -class BatchFileExecutionError(VisualCException): - pass - -# Dict to 'canonalize' the arch -_ARCH_TO_CANONICAL = { - "amd64" : "amd64", - "emt64" : "amd64", - "i386" : "x86", - "i486" : "x86", - "i586" : "x86", - "i686" : "x86", - "ia64" : "ia64", # deprecated - "itanium" : "ia64", # deprecated - "x86" : "x86", - "x86_64" : "amd64", - "arm" : "arm", - "arm64" : "arm64", - "aarch64" : "arm64", -} - -# Starting with 14.1 (aka VS2017), the tools are organized by host directory. -# subdirs for each target. They are now in .../VC/Auxuiliary/Build. -# Note 2017 Express uses Hostx86 even if it's on 64-bit Windows, -# not reflected in this table. -_HOST_TARGET_TO_CL_DIR_GREATER_THAN_14 = { - ("amd64","amd64") : ("Hostx64","x64"), - ("amd64","x86") : ("Hostx64","x86"), - ("amd64","arm") : ("Hostx64","arm"), - ("amd64","arm64") : ("Hostx64","arm64"), - ("x86","amd64") : ("Hostx86","x64"), - ("x86","x86") : ("Hostx86","x86"), - ("x86","arm") : ("Hostx86","arm"), - ("x86","arm64") : ("Hostx86","arm64"), -} - -# before 14.1 (VS2017): the original x86 tools are in the tools dir, -# any others are in a subdir named by the host/target pair, -# or just a single word if host==target -_HOST_TARGET_TO_CL_DIR = { - ("amd64","amd64") : "amd64", - ("amd64","x86") : "amd64_x86", - ("amd64","arm") : "amd64_arm", - ("amd64","arm64") : "amd64_arm64", - ("x86","amd64") : "x86_amd64", - ("x86","x86") : "", - ("x86","arm") : "x86_arm", - ("x86","arm64") : "x86_arm64", - ("arm","arm") : "arm", -} - -# 14.1 (VS2017) and later: -# Given a (host, target) tuple, return the batch file to look for. -# We can't rely on returning an arg to use for vcvarsall.bat, -# because that script will run even if given a pair that isn't installed. -# Targets that already look like a pair are pseudo targets that -# effectively mean to skip whatever the host was specified as. -_HOST_TARGET_TO_BAT_ARCH_GT14 = { - ("amd64", "amd64"): "vcvars64.bat", - ("amd64", "x86"): "vcvarsamd64_x86.bat", - ("amd64", "x86_amd64"): "vcvarsx86_amd64.bat", - ("amd64", "x86_x86"): "vcvars32.bat", - ("amd64", "arm"): "vcvarsamd64_arm.bat", - ("amd64", "x86_arm"): "vcvarsx86_arm.bat", - ("amd64", "arm64"): "vcvarsamd64_arm64.bat", - ("amd64", "x86_arm64"): "vcvarsx86_arm64.bat", - ("x86", "x86"): "vcvars32.bat", - ("x86", "amd64"): "vcvarsx86_amd64.bat", - ("x86", "x86_amd64"): "vcvarsx86_amd64.bat", - ("x86", "arm"): "vcvarsx86_arm.bat", - ("x86", "x86_arm"): "vcvarsx86_arm.bat", - ("x86", "arm64"): "vcvarsx86_arm64.bat", - ("x86", "x86_arm64"): "vcvarsx86_arm64.bat", -} - -# before 14.1 (VS2017): -# Given a (host, target) tuple, return the argument for the bat file; -# Both host and target should be canoncalized. -# If the target already looks like a pair, return it - these are -# pseudo targets (mainly used by Express versions) -_HOST_TARGET_ARCH_TO_BAT_ARCH = { - ("x86", "x86"): "x86", - ("x86", "amd64"): "x86_amd64", - ("x86", "x86_amd64"): "x86_amd64", - ("amd64", "x86_amd64"): "x86_amd64", # This is present in (at least) VS2012 express - ("amd64", "amd64"): "amd64", - ("amd64", "x86"): "x86", - ("amd64", "x86_x86"): "x86", - ("x86", "ia64"): "x86_ia64", # gone since 14.0 - ("x86", "arm"): "x86_arm", # since 14.0 - ("x86", "arm64"): "x86_arm64", # since 14.1 - ("amd64", "arm"): "amd64_arm", # since 14.0 - ("amd64", "arm64"): "amd64_arm64", # since 14.1 - ("x86", "x86_arm"): "x86_arm", # since 14.0 - ("x86", "x86_arm64"): "x86_arm64", # since 14.1 - ("amd64", "x86_arm"): "x86_arm", # since 14.0 - ("amd64", "x86_arm64"): "x86_arm64", # since 14.1 -} - -_CL_EXE_NAME = 'cl.exe' - -def get_msvc_version_numeric(msvc_version): - """Get the raw version numbers from a MSVC_VERSION string, so it - could be cast to float or other numeric values. For example, '14.0Exp' - would get converted to '14.0'. - - Args: - msvc_version: str - string representing the version number, could contain non - digit characters - - Returns: - str: the value converted to a numeric only string - - """ - return ''.join([x for x in msvc_version if x in string_digits + '.']) - -def get_host_target(env): - host_platform = env.get('HOST_ARCH') - debug("HOST_ARCH:" + str(host_platform)) - if not host_platform: - host_platform = platform.machine() - - # Solaris returns i86pc for both 32 and 64 bit architectures - if host_platform == "i86pc": - if platform.architecture()[0] == "64bit": - host_platform = "amd64" - else: - host_platform = "x86" - - # Retain user requested TARGET_ARCH - req_target_platform = env.get('TARGET_ARCH') - debug("TARGET_ARCH:" + str(req_target_platform)) - if req_target_platform: - # If user requested a specific platform then only try that one. - target_platform = req_target_platform - else: - target_platform = host_platform - - try: - host = _ARCH_TO_CANONICAL[host_platform.lower()] - except KeyError: - msg = "Unrecognized host architecture %s" - raise MSVCUnsupportedHostArch(msg % repr(host_platform)) - - try: - target = _ARCH_TO_CANONICAL[target_platform.lower()] - except KeyError: - all_archs = str(list(_ARCH_TO_CANONICAL.keys())) - raise MSVCUnsupportedTargetArch( - "Unrecognized target architecture %s\n\tValid architectures: %s" - % (target_platform, all_archs) - ) - - return (host, target, req_target_platform) - -# If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the -# MSVC_VERSION documentation in Tool/msvc.xml. -_VCVER = ["14.2", "14.1", "14.1Exp", "14.0", "14.0Exp", "12.0", "12.0Exp", "11.0", "11.0Exp", "10.0", "10.0Exp", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"] - -# if using vswhere, configure command line arguments to probe for installed VC editions -_VCVER_TO_VSWHERE_VER = { - '14.2': [ - ["-version", "[16.0, 17.0)", ], # default: Enterprise, Professional, Community (order unpredictable?) - ["-version", "[16.0, 17.0)", "-products", "Microsoft.VisualStudio.Product.BuildTools"], # BuildTools - ], - '14.1': [ - ["-version", "[15.0, 16.0)", ], # default: Enterprise, Professional, Community (order unpredictable?) - ["-version", "[15.0, 16.0)", "-products", "Microsoft.VisualStudio.Product.BuildTools"], # BuildTools - ], - '14.1Exp': [ - ["-version", "[15.0, 16.0)", "-products", "Microsoft.VisualStudio.Product.WDExpress"], # Express - ], -} - -_VCVER_TO_PRODUCT_DIR = { - '14.2': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'')], # not set by this version - '14.1': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'')], # not set by this version - '14.1Exp': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'')], # not set by this version - '14.0' : [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir')], - '14.0Exp' : [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\14.0\Setup\VC\ProductDir')], - '12.0' : [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\12.0\Setup\VC\ProductDir'), - ], - '12.0Exp' : [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\12.0\Setup\VC\ProductDir'), - ], - '11.0': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\11.0\Setup\VC\ProductDir'), - ], - '11.0Exp' : [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\11.0\Setup\VC\ProductDir'), - ], - '10.0': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\10.0\Setup\VC\ProductDir'), - ], - '10.0Exp' : [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\10.0\Setup\VC\ProductDir'), - ], - '9.0': [ - (SCons.Util.HKEY_CURRENT_USER, r'Microsoft\DevDiv\VCForPython\9.0\installdir',), - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir',), - ], - '9.0Exp' : [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir'), - ], - '8.0': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir'), - ], - '8.0Exp': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir'), - ], - '7.1': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir'), - ], - '7.0': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir'), - ], - '6.0': [ - (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir'), - ] -} - - -def msvc_version_to_maj_min(msvc_version): - msvc_version_numeric = get_msvc_version_numeric(msvc_version) - - t = msvc_version_numeric.split(".") - if not len(t) == 2: - raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric)) - try: - maj = int(t[0]) - min = int(t[1]) - return maj, min - except ValueError as e: - raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric)) - - -def is_host_target_supported(host_target, msvc_version): - """Check if (host, target) pair is supported for a VC version. - - Only checks whether a given version *may* support the given - (host, target) pair, not that the toolchain is actually on the machine. - - Args: - host_target: canonalized host-target pair, e.g. - ("x86", "amd64") for cross compilation from 32- to 64-bit Windows. - msvc_version: Visual C++ version (major.minor), e.g. "10.0" - - Returns: - True or False - - """ - # We assume that any Visual Studio version supports x86 as a target - if host_target[1] != "x86": - maj, min = msvc_version_to_maj_min(msvc_version) - if maj < 8: - return False - return True - - -VSWHERE_PATHS = [os.path.join(p,'vswhere.exe') for p in [ - os.path.expandvars(r"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer"), - os.path.expandvars(r"%ProgramFiles%\Microsoft Visual Studio\Installer"), - os.path.expandvars(r"%ChocolateyInstall%\bin"), -]] - -def msvc_find_vswhere(): - """ Find the location of vswhere """ - # For bug 3333: support default location of vswhere for both - # 64 and 32 bit windows installs. - # For bug 3542: also accommodate not being on C: drive. - # NB: this gets called from testsuite on non-Windows platforms. - # Whether that makes sense or not, don't break it for those. - vswhere_path = None - for pf in VSWHERE_PATHS: - if os.path.exists(pf): - vswhere_path = pf - break - - return vswhere_path - -def find_vc_pdir_vswhere(msvc_version, env=None): - """ Find the MSVC product directory using the vswhere program. - - Args: - msvc_version: MSVC version to search for - env: optional to look up VSWHERE variable - - Returns: - MSVC install dir or None - - Raises: - UnsupportedVersion: if the version is not known by this file - - """ - try: - vswhere_version = _VCVER_TO_VSWHERE_VER[msvc_version] - except KeyError: - debug("Unknown version of MSVC: %s" % msvc_version) - raise UnsupportedVersion("Unknown version %s" % msvc_version) - - if env is None or not env.get('VSWHERE'): - vswhere_path = msvc_find_vswhere() - else: - vswhere_path = env.subst('$VSWHERE') - - if vswhere_path is None: - return None - - debug('VSWHERE: %s' % vswhere_path) - for vswhere_version_args in vswhere_version: - - vswhere_cmd = [vswhere_path] + vswhere_version_args + ["-property", "installationPath"] - - debug("running: %s" % vswhere_cmd) - - #cp = subprocess.run(vswhere_cmd, capture_output=True) # 3.7+ only - cp = subprocess.run(vswhere_cmd, stdout=PIPE, stderr=PIPE) - - if cp.stdout: - # vswhere could return multiple lines, e.g. if Build Tools - # and {Community,Professional,Enterprise} are both installed. - # We could define a way to pick the one we prefer, but since - # this data is currently only used to make a check for existence, - # returning the first hit should be good enough. - lines = cp.stdout.decode("mbcs").splitlines() - return os.path.join(lines[0], 'VC') - else: - # We found vswhere, but no install info available for this version - pass - - return None - - -def find_vc_pdir(env, msvc_version): - """Find the MSVC product directory for the given version. - - Tries to look up the path using a registry key from the table - _VCVER_TO_PRODUCT_DIR; if there is no key, calls find_vc_pdir_wshere - for help instead. - - Args: - msvc_version: str - msvc version (major.minor, e.g. 10.0) - - Returns: - str: Path found in registry, or None - - Raises: - UnsupportedVersion: if the version is not known by this file. - MissingConfiguration: found version but the directory is missing. - - Both exceptions inherit from VisualCException. - - """ - root = 'Software\\' - try: - hkeys = _VCVER_TO_PRODUCT_DIR[msvc_version] - except KeyError: - debug("Unknown version of MSVC: %s" % msvc_version) - raise UnsupportedVersion("Unknown version %s" % msvc_version) - - for hkroot, key in hkeys: - try: - comps = None - if not key: - comps = find_vc_pdir_vswhere(msvc_version, env) - if not comps: - debug('no VC found for version {}'.format(repr(msvc_version))) - raise SCons.Util.WinError - debug('VC found: {}'.format(repr(msvc_version))) - return comps - else: - if common.is_win64(): - try: - # ordinarily at win64, try Wow6432Node first. - comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot) - except SCons.Util.WinError as e: - # at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node - pass - if not comps: - # not Win64, or Microsoft Visual Studio for Python 2.7 - comps = common.read_reg(root + key, hkroot) - except SCons.Util.WinError as e: - debug('no VC registry key {}'.format(repr(key))) - else: - debug('found VC in registry: {}'.format(comps)) - if os.path.exists(comps): - return comps - else: - debug('reg says dir is {}, but it does not exist. (ignoring)'.format(comps)) - raise MissingConfiguration("registry dir {} not found on the filesystem".format(comps)) - return None - -def find_batch_file(env,msvc_version,host_arch,target_arch): - """ - Find the location of the batch script which should set up the compiler - for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress - - In newer (2017+) compilers, make use of the fact there are vcvars - scripts named with a host_target pair that calls vcvarsall.bat properly, - so use that and return an indication we don't need the argument - we would have computed to run vcvarsall.bat. - """ - pdir = find_vc_pdir(env, msvc_version) - if pdir is None: - raise NoVersionFound("No version of Visual Studio found") - debug('looking in {}'.format(pdir)) - - # filter out e.g. "Exp" from the version name - msvc_ver_numeric = get_msvc_version_numeric(msvc_version) - use_arg = True - vernum = float(msvc_ver_numeric) - if 7 <= vernum < 8: - pdir = os.path.join(pdir, os.pardir, "Common7", "Tools") - batfilename = os.path.join(pdir, "vsvars32.bat") - elif vernum < 7: - pdir = os.path.join(pdir, "Bin") - batfilename = os.path.join(pdir, "vcvars32.bat") - elif 8 <= vernum <= 14: - batfilename = os.path.join(pdir, "vcvarsall.bat") - else: # vernum >= 14.1 VS2017 and above - batfiledir = os.path.join(pdir, "Auxiliary", "Build") - targ = _HOST_TARGET_TO_BAT_ARCH_GT14[(host_arch, target_arch)] - batfilename = os.path.join(batfiledir, targ) - use_arg = False - - if not os.path.exists(batfilename): - debug("Not found: %s" % batfilename) - batfilename = None - - installed_sdks = get_installed_sdks() - for _sdk in installed_sdks: - sdk_bat_file = _sdk.get_sdk_vc_script(host_arch,target_arch) - if not sdk_bat_file: - debug("batch file not found:%s" % _sdk) - else: - sdk_bat_file_path = os.path.join(pdir,sdk_bat_file) - if os.path.exists(sdk_bat_file_path): - debug('sdk_bat_file_path:%s' % sdk_bat_file_path) - return (batfilename, use_arg, sdk_bat_file_path) - return (batfilename, use_arg, None) - - -__INSTALLED_VCS_RUN = None -_VC_TOOLS_VERSION_FILE_PATH = ['Auxiliary', 'Build', 'Microsoft.VCToolsVersion.default.txt'] -_VC_TOOLS_VERSION_FILE = os.sep.join(_VC_TOOLS_VERSION_FILE_PATH) - -def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version): - """Return status of finding a cl.exe to use. - - Locates cl in the vc_dir depending on TARGET_ARCH, HOST_ARCH and the - msvc version. TARGET_ARCH and HOST_ARCH can be extracted from the - passed env, unless it is None, in which case the native platform is - assumed for both host and target. - - Args: - env: Environment - a construction environment, usually if this is passed its - because there is a desired TARGET_ARCH to be used when searching - for a cl.exe - vc_dir: str - the path to the VC dir in the MSVC installation - msvc_version: str - msvc version (major.minor, e.g. 10.0) - - Returns: - bool: - - """ - - # determine if there is a specific target platform we want to build for and - # use that to find a list of valid VCs, default is host platform == target platform - # and same for if no env is specified to extract target platform from - if env: - (host_platform, target_platform, req_target_platform) = get_host_target(env) - else: - host_platform = platform.machine().lower() - target_platform = host_platform - - host_platform = _ARCH_TO_CANONICAL[host_platform] - target_platform = _ARCH_TO_CANONICAL[target_platform] - - debug('host platform %s, target platform %s for version %s' % (host_platform, target_platform, msvc_version)) - - ver_num = float(get_msvc_version_numeric(msvc_version)) - - # make sure the cl.exe exists meaning the tool is installed - if ver_num > 14: - # 2017 and newer allowed multiple versions of the VC toolset to be - # installed at the same time. This changes the layout. - # Just get the default tool version for now - #TODO: support setting a specific minor VC version - default_toolset_file = os.path.join(vc_dir, _VC_TOOLS_VERSION_FILE) - try: - with open(default_toolset_file) as f: - vc_specific_version = f.readlines()[0].strip() - except IOError: - debug('failed to read ' + default_toolset_file) - return False - except IndexError: - debug('failed to find MSVC version in ' + default_toolset_file) - return False - - host_trgt_dir = _HOST_TARGET_TO_CL_DIR_GREATER_THAN_14.get((host_platform, target_platform), None) - if host_trgt_dir is None: - debug('unsupported host/target platform combo: (%s,%s)'%(host_platform, target_platform)) - return False - - cl_path = os.path.join(vc_dir, 'Tools','MSVC', vc_specific_version, 'bin', host_trgt_dir[0], host_trgt_dir[1], _CL_EXE_NAME) - debug('checking for ' + _CL_EXE_NAME + ' at ' + cl_path) - if os.path.exists(cl_path): - debug('found ' + _CL_EXE_NAME + '!') - return True - - elif host_platform == "amd64" and host_trgt_dir[0] == "Hostx64": - # Special case: fallback to Hostx86 if Hostx64 was tried - # and failed. This is because VS 2017 Express running on amd64 - # will look to our probe like the host dir should be Hostx64, - # but Express uses Hostx86 anyway. - # We should key this off the "x86_amd64" and related pseudo - # targets, but we don't see those in this function. - host_trgt_dir = ("Hostx86", host_trgt_dir[1]) - cl_path = os.path.join(vc_dir, 'Tools','MSVC', vc_specific_version, 'bin', host_trgt_dir[0], host_trgt_dir[1], _CL_EXE_NAME) - debug('checking for ' + _CL_EXE_NAME + ' at ' + cl_path) - if os.path.exists(cl_path): - debug('found ' + _CL_EXE_NAME + '!') - return True - - elif 14 >= ver_num >= 8: - # Set default value to be -1 as "", which is the value for x86/x86, - # yields true when tested if not host_trgt_dir - host_trgt_dir = _HOST_TARGET_TO_CL_DIR.get((host_platform, target_platform), None) - if host_trgt_dir is None: - debug('unsupported host/target platform combo') - return False - - cl_path = os.path.join(vc_dir, 'bin', host_trgt_dir, _CL_EXE_NAME) - debug('checking for ' + _CL_EXE_NAME + ' at ' + cl_path) - - cl_path_exists = os.path.exists(cl_path) - if not cl_path_exists and host_platform == 'amd64': - # older versions of visual studio only had x86 binaries, - # so if the host platform is amd64, we need to check cross - # compile options (x86 binary compiles some other target on a 64 bit os) - - # Set default value to be -1 as "" which is the value for x86/x86 yields true when tested - # if not host_trgt_dir - host_trgt_dir = _HOST_TARGET_TO_CL_DIR.get(('x86', target_platform), None) - if host_trgt_dir is None: - return False - - cl_path = os.path.join(vc_dir, 'bin', host_trgt_dir, _CL_EXE_NAME) - debug('checking for ' + _CL_EXE_NAME + ' at ' + cl_path) - cl_path_exists = os.path.exists(cl_path) - - if cl_path_exists: - debug('found ' + _CL_EXE_NAME + '!') - return True - - elif 8 > ver_num >= 6: - # quick check for vc_dir/bin and vc_dir/ before walk - # need to check root as the walk only considers subdirectories - for cl_dir in ('bin', ''): - cl_path = os.path.join(vc_dir, cl_dir, _CL_EXE_NAME) - if os.path.exists(cl_path): - debug(_CL_EXE_NAME + ' found %s' % cl_path) - return True - # not in bin or root: must be in a subdirectory - for cl_root, cl_dirs, _ in os.walk(vc_dir): - for cl_dir in cl_dirs: - cl_path = os.path.join(cl_root, cl_dir, _CL_EXE_NAME) - if os.path.exists(cl_path): - debug(_CL_EXE_NAME + ' found %s' % cl_path) - return True - return False - else: - # version not support return false - debug('unsupported MSVC version: ' + str(ver_num)) - - return False - -def get_installed_vcs(env=None): - global __INSTALLED_VCS_RUN - - if __INSTALLED_VCS_RUN is not None: - return __INSTALLED_VCS_RUN - - installed_versions = [] - - for ver in _VCVER: - debug('trying to find VC %s' % ver) - try: - VC_DIR = find_vc_pdir(env, ver) - if VC_DIR: - debug('found VC %s' % ver) - if _check_cl_exists_in_vc_dir(env, VC_DIR, ver): - installed_versions.append(ver) - else: - debug('no compiler found %s' % ver) - else: - debug('return None for ver %s' % ver) - except (MSVCUnsupportedTargetArch, MSVCUnsupportedHostArch): - # Allow this exception to propagate further as it should cause - # SCons to exit with an error code - raise - except VisualCException as e: - debug('did not find VC %s: caught exception %s' % (ver, str(e))) - - __INSTALLED_VCS_RUN = installed_versions - return __INSTALLED_VCS_RUN - -def reset_installed_vcs(): - """Make it try again to find VC. This is just for the tests.""" - global __INSTALLED_VCS_RUN - __INSTALLED_VCS_RUN = None - -# Running these batch files isn't cheap: most of the time spent in -# msvs.generate() is due to vcvars*.bat. In a build that uses "tools='msvs'" -# in multiple environments, for example: -# env1 = Environment(tools='msvs') -# env2 = Environment(tools='msvs') -# we can greatly improve the speed of the second and subsequent Environment -# (or Clone) calls by memoizing the environment variables set by vcvars*.bat. -# -# Updated: by 2018, vcvarsall.bat had gotten so expensive (vs2017 era) -# it was breaking CI builds because the test suite starts scons so many -# times and the existing memo logic only helped with repeated calls -# within the same scons run. Windows builds on the CI system were split -# into chunks to get around single-build time limits. -# With VS2019 it got even slower and an optional persistent cache file -# was introduced. The cache now also stores only the parsed vars, -# not the entire output of running the batch file - saves a bit -# of time not parsing every time. - -script_env_cache = None - -def script_env(script, args=None): - global script_env_cache - - if script_env_cache is None: - script_env_cache = common.read_script_env_cache() - cache_key = "{}--{}".format(script, args) - cache_data = script_env_cache.get(cache_key, None) - if cache_data is None: - stdout = common.get_output(script, args) - - # Stupid batch files do not set return code: we take a look at the - # beginning of the output for an error message instead - olines = stdout.splitlines() - if olines[0].startswith("The specified configuration type is missing"): - raise BatchFileExecutionError("\n".join(olines[:2])) - - cache_data = common.parse_output(stdout) - script_env_cache[cache_key] = cache_data - # once we updated cache, give a chance to write out if user wanted - common.write_script_env_cache(script_env_cache) - - return cache_data - -def get_default_version(env): - msvc_version = env.get('MSVC_VERSION') - msvs_version = env.get('MSVS_VERSION') - debug('msvc_version:%s msvs_version:%s' % (msvc_version, msvs_version)) - - if msvs_version and not msvc_version: - SCons.Warnings.warn( - SCons.Warnings.DeprecatedWarning, - "MSVS_VERSION is deprecated: please use MSVC_VERSION instead ") - return msvs_version - elif msvc_version and msvs_version: - if not msvc_version == msvs_version: - SCons.Warnings.warn( - SCons.Warnings.VisualVersionMismatch, - "Requested msvc version (%s) and msvs version (%s) do " \ - "not match: please use MSVC_VERSION only to request a " \ - "visual studio version, MSVS_VERSION is deprecated" \ - % (msvc_version, msvs_version)) - return msvs_version - - if not msvc_version: - installed_vcs = get_installed_vcs(env) - debug('installed_vcs:%s' % installed_vcs) - if not installed_vcs: - #msg = 'No installed VCs' - #debug('msv %s' % repr(msg)) - #SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) - debug('No installed VCs') - return None - msvc_version = installed_vcs[0] - debug('using default installed MSVC version %s' % repr(msvc_version)) - else: - debug('using specified MSVC version %s' % repr(msvc_version)) - - return msvc_version - -def msvc_setup_env_once(env): - try: - has_run = env["MSVC_SETUP_RUN"] - except KeyError: - has_run = False - - if not has_run: - msvc_setup_env(env) - env["MSVC_SETUP_RUN"] = True - -def msvc_find_valid_batch_script(env, version): - """Find and execute appropriate batch script to set up build env. - - The MSVC build environment depends heavily on having the shell - environment set. SCons does not inherit that, and does not count - on that being set up correctly anyway, so it tries to find the right - MSVC batch script, or the right arguments to the generic batch script - vcvarsall.bat, and run that, so we have a valid environment to build in. - There are dragons here: the batch scripts don't fail (see comments - elsewhere), they just leave you with a bad setup, so try hard to - get it right. - """ - - # Find the host, target, and if present the requested target: - platforms = get_host_target(env) - debug("host_platform %s, target_platform %s req_target_platform %s" % platforms) - host_platform, target_platform, req_target_platform = platforms - - # Most combinations of host + target are straightforward. - # While all MSVC / Visual Studio tools are pysically 32-bit, they - # make it look like there are 64-bit tools if the host is 64-bit, - # so you can invoke the environment batch script to set up to build, - # say, amd64 host -> x86 target. Express versions are an exception: - # they always look 32-bit, so the batch scripts with 64-bit - # host parts are absent. We try to fix that up in a couple of ways. - # One is here: we make a table of "targets" to try, with the extra - # targets being tags that tell us to try a different "host" instead - # of the deduced host. - try_target_archs = [target_platform] - if req_target_platform in ('amd64', 'x86_64'): - try_target_archs.append('x86_amd64') - elif req_target_platform in ('x86',): - try_target_archs.append('x86_x86') - elif req_target_platform in ('arm',): - try_target_archs.append('x86_arm') - elif req_target_platform in ('arm64',): - try_target_archs.append('x86_arm64') - elif not req_target_platform: - if target_platform in ('amd64', 'x86_64'): - try_target_archs.append('x86_amd64') - # If the user hasn't specifically requested a TARGET_ARCH, - # and the TARGET_ARCH is amd64 then also try 32 bits - # if there are no viable 64 bit tools installed - try_target_archs.append('x86') - - debug("host_platform: %s, try_target_archs: %s"%(host_platform, try_target_archs)) - - d = None - for tp in try_target_archs: - # Set to current arch. - env['TARGET_ARCH'] = tp - - debug("trying target_platform:%s" % tp) - host_target = (host_platform, tp) - if not is_host_target_supported(host_target, version): - warn_msg = "host, target = %s not supported for MSVC version %s" % \ - (host_target, version) - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) - arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target] - - # Try to locate a batch file for this host/target platform combo - try: - (vc_script, use_arg, sdk_script) = find_batch_file(env, version, host_platform, tp) - debug('vc_script:%s sdk_script:%s'%(vc_script,sdk_script)) - except VisualCException as e: - msg = str(e) - debug('Caught exception while looking for batch file (%s)' % msg) - warn_msg = "VC version %s not installed. " + \ - "C/C++ compilers are most likely not set correctly.\n" + \ - " Installed versions are: %s" - warn_msg = warn_msg % (version, get_installed_vcs(env)) - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) - continue - - # Try to use the located batch file for this host/target platform combo - debug('use_script 2 %s, args:%s' % (repr(vc_script), arg)) - found = None - if vc_script: - if not use_arg: - arg = '' # bat file will supply platform type - # Get just version numbers - maj, min = msvc_version_to_maj_min(version) - # VS2015+ - if maj >= 14: - if env.get('MSVC_UWP_APP') == '1': - # Initialize environment variables with store/UWP paths - arg = (arg + ' store').lstrip() - - try: - d = script_env(vc_script, args=arg) - found = vc_script - except BatchFileExecutionError as e: - debug('use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e)) - vc_script=None - continue - if not vc_script and sdk_script: - debug('use_script 4: trying sdk script: %s' % sdk_script) - try: - d = script_env(sdk_script) - found = sdk_script - except BatchFileExecutionError as e: - debug('use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script), e)) - continue - elif not vc_script and not sdk_script: - debug('use_script 6: Neither VC script nor SDK script found') - continue - - debug("Found a working script/target: %s/%s"%(repr(found),arg)) - break # We've found a working target_platform, so stop looking - - # If we cannot find a viable installed compiler, reset the TARGET_ARCH - # To it's initial value - if not d: - env['TARGET_ARCH']=req_target_platform - - return d - - -def msvc_setup_env(env): - debug('called') - version = get_default_version(env) - if version is None: - warn_msg = "No version of Visual Studio compiler found - C/C++ " \ - "compilers most likely not set correctly" - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) - return None - - # XXX: we set-up both MSVS version for backward - # compatibility with the msvs tool - env['MSVC_VERSION'] = version - env['MSVS_VERSION'] = version - env['MSVS'] = {} - - - use_script = env.get('MSVC_USE_SCRIPT', True) - if SCons.Util.is_String(use_script): - debug('use_script 1 %s' % repr(use_script)) - d = script_env(use_script) - elif use_script: - d = msvc_find_valid_batch_script(env,version) - debug('use_script 2 %s' % d) - if not d: - return d - else: - debug('MSVC_USE_SCRIPT set to False') - warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \ - "set correctly." - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) - return None - - for k, v in d.items(): - env.PrependENVPath(k, v, delete_existing=True) - debug("env['ENV']['%s'] = %s" % (k, env['ENV'][k])) - - # final check to issue a warning if the compiler is not present - if not find_program_path(env, 'cl'): - debug("did not find " + _CL_EXE_NAME) - if CONFIG_CACHE: - propose = "SCONS_CACHE_MSVC_CONFIG caching enabled, remove cache file {} if out of date.".format(CONFIG_CACHE) - else: - propose = "It may need to be installed separately with Visual Studio." - warn_msg = "Could not find MSVC compiler 'cl'. {}".format(propose) - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) - -def msvc_exists(env=None, version=None): - vcs = get_installed_vcs(env) - if version is None: - return len(vcs) > 0 - return version in vcs diff --git a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/vs.py b/scons/scons-local-4.1.0/SCons/Tool/MSCommon/vs.py deleted file mode 100644 index 0d22e2942..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/MSCommon/vs.py +++ /dev/null @@ -1,597 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -__doc__ = """Module to detect Visual Studio and/or Visual C/C++ -""" - -import os - -import SCons.Errors -import SCons.Util - -from .common import debug, \ - get_output, \ - is_win64, \ - normalize_env, \ - parse_output, \ - read_reg - -import SCons.Tool.MSCommon.vc - -class VisualStudio: - """ - An abstract base class for trying to find installed versions of - Visual Studio. - """ - def __init__(self, version, **kw): - self.version = version - kw['vc_version'] = kw.get('vc_version', version) - kw['sdk_version'] = kw.get('sdk_version', version) - self.__dict__.update(kw) - self._cache = {} - - def find_batch_file(self): - vs_dir = self.get_vs_dir() - if not vs_dir: - debug('no vs_dir') - return None - batch_file = os.path.join(vs_dir, self.batch_file_path) - batch_file = os.path.normpath(batch_file) - if not os.path.isfile(batch_file): - debug('%s not on file system' % batch_file) - return None - return batch_file - - def find_vs_dir_by_vc(self, env): - SCons.Tool.MSCommon.vc.get_installed_vcs(env) - dir = SCons.Tool.MSCommon.vc.find_vc_pdir(env, self.vc_version) - if not dir: - debug('no installed VC %s' % self.vc_version) - return None - return os.path.abspath(os.path.join(dir, os.pardir)) - - def find_vs_dir_by_reg(self, env): - root = 'Software\\' - - if is_win64(): - root = root + 'Wow6432Node\\' - for key in self.hkeys: - if key=='use_dir': - return self.find_vs_dir_by_vc(env) - key = root + key - try: - comps = read_reg(key) - except SCons.Util.WinError as e: - debug('no VS registry key {}'.format(repr(key))) - else: - debug('found VS in registry: {}'.format(comps)) - return comps - return None - - def find_vs_dir(self, env): - """ Can use registry or location of VC to find vs dir - First try to find by registry, and if that fails find via VC dir - """ - - vs_dir=self.find_vs_dir_by_reg(env) - if not vs_dir: - vs_dir = self.find_vs_dir_by_vc(env) - debug('found VS in ' + str(vs_dir )) - return vs_dir - - def find_executable(self, env): - vs_dir = self.get_vs_dir(env) - if not vs_dir: - debug('no vs_dir ({})'.format(vs_dir)) - return None - executable = os.path.join(vs_dir, self.executable_path) - executable = os.path.normpath(executable) - if not os.path.isfile(executable): - debug('{} not on file system'.format(executable)) - return None - return executable - - def get_batch_file(self): - try: - return self._cache['batch_file'] - except KeyError: - batch_file = self.find_batch_file() - self._cache['batch_file'] = batch_file - return batch_file - - def get_executable(self, env=None): - try: - debug('using cache:%s'%self._cache['executable']) - return self._cache['executable'] - except KeyError: - executable = self.find_executable(env) - self._cache['executable'] = executable - debug('not in cache:%s'%executable) - return executable - - def get_vs_dir(self, env): - try: - return self._cache['vs_dir'] - except KeyError: - vs_dir = self.find_vs_dir(env) - self._cache['vs_dir'] = vs_dir - return vs_dir - - def get_supported_arch(self): - try: - return self._cache['supported_arch'] - except KeyError: - # RDEVE: for the time being use hardcoded lists - # supported_arch = self.find_supported_arch() - self._cache['supported_arch'] = self.supported_arch - return self.supported_arch - - def reset(self): - self._cache = {} - -# The list of supported Visual Studio versions we know how to detect. -# -# How to look for .bat file ? -# - VS 2008 Express (x86): -# * from registry key productdir, gives the full path to vsvarsall.bat. In -# HKEY_LOCAL_MACHINE): -# Software\Microsoft\VCEpress\9.0\Setup\VC\productdir -# * from environmnent variable VS90COMNTOOLS: the path is then ..\..\VC -# relatively to the path given by the variable. -# -# - VS 2008 Express (WoW6432: 32 bits on windows x64): -# Software\Wow6432Node\Microsoft\VCEpress\9.0\Setup\VC\productdir -# -# - VS 2005 Express (x86): -# * from registry key productdir, gives the full path to vsvarsall.bat. In -# HKEY_LOCAL_MACHINE): -# Software\Microsoft\VCEpress\8.0\Setup\VC\productdir -# * from environmnent variable VS80COMNTOOLS: the path is then ..\..\VC -# relatively to the path given by the variable. -# -# - VS 2005 Express (WoW6432: 32 bits on windows x64): does not seem to have a -# productdir ? -# -# - VS 2003 .Net (pro edition ? x86): -# * from registry key productdir. The path is then ..\Common7\Tools\ -# relatively to the key. The key is in HKEY_LOCAL_MACHINE): -# Software\Microsoft\VisualStudio\7.1\Setup\VC\productdir -# * from environmnent variable VS71COMNTOOLS: the path is the full path to -# vsvars32.bat -# -# - VS 98 (VS 6): -# * from registry key productdir. The path is then Bin -# relatively to the key. The key is in HKEY_LOCAL_MACHINE): -# Software\Microsoft\VisualStudio\6.0\Setup\VC98\productdir -# -# The first version found in the list is the one used by default if -# there are multiple versions installed. Barring good reasons to -# the contrary, this means we should list versions from most recent -# to oldest. Pro versions get listed before Express versions on the -# assumption that, by default, you'd rather use the version you paid -# good money for in preference to whatever Microsoft makes available -# for free. -# -# If you update this list, update _VCVER and _VCVER_TO_PRODUCT_DIR in -# Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml. - -SupportedVSList = [ - # Visual Studio 2019 - VisualStudio('14.2', - vc_version='14.2', - sdk_version='10.0A', - hkeys=[], - common_tools_var='VS160COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - # should be a fallback, prefer use vswhere installationPath - batch_file_path=r'Common7\Tools\VsDevCmd.bat', - supported_arch=['x86', 'amd64', "arm"], - ), - - # Visual Studio 2017 - VisualStudio('14.1', - vc_version='14.1', - sdk_version='10.0A', - hkeys=[], - common_tools_var='VS150COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - # should be a fallback, prefer use vswhere installationPath - batch_file_path=r'Common7\Tools\VsDevCmd.bat', - supported_arch=['x86', 'amd64', "arm"], - ), - - # Visual C++ 2017 Express Edition (for Desktop) - VisualStudio('14.1Exp', - vc_version='14.1', - sdk_version='10.0A', - hkeys=[], - common_tools_var='VS150COMNTOOLS', - executable_path=r'Common7\IDE\WDExpress.exe', - # should be a fallback, prefer use vswhere installationPath - batch_file_path=r'Common7\Tools\VsDevCmd.bat', - supported_arch=['x86', 'amd64', "arm"], - ), - - # Visual Studio 2015 - VisualStudio('14.0', - vc_version='14.0', - sdk_version='10.0', - hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'], - common_tools_var='VS140COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64', "arm"], - ), - - # Visual C++ 2015 Express Edition (for Desktop) - VisualStudio('14.0Exp', - vc_version='14.0', - sdk_version='10.0A', - hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'], - common_tools_var='VS140COMNTOOLS', - executable_path=r'Common7\IDE\WDExpress.exe', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64', "arm"], - ), - - # Visual Studio 2013 - VisualStudio('12.0', - vc_version='12.0', - sdk_version='8.1A', - hkeys=[r'Microsoft\VisualStudio\12.0\Setup\VS\ProductDir'], - common_tools_var='VS120COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64'], - ), - - # Visual C++ 2013 Express Edition (for Desktop) - VisualStudio('12.0Exp', - vc_version='12.0', - sdk_version='8.1A', - hkeys=[r'Microsoft\VisualStudio\12.0\Setup\VS\ProductDir'], - common_tools_var='VS120COMNTOOLS', - executable_path=r'Common7\IDE\WDExpress.exe', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64'], - ), - - # Visual Studio 2012 - VisualStudio('11.0', - sdk_version='8.0A', - hkeys=[r'Microsoft\VisualStudio\11.0\Setup\VS\ProductDir'], - common_tools_var='VS110COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64'], - ), - - # Visual C++ 2012 Express Edition (for Desktop) - VisualStudio('11.0Exp', - vc_version='11.0', - sdk_version='8.0A', - hkeys=[r'Microsoft\VisualStudio\11.0\Setup\VS\ProductDir'], - common_tools_var='VS110COMNTOOLS', - executable_path=r'Common7\IDE\WDExpress.exe', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64'], - ), - - # Visual Studio 2010 - VisualStudio('10.0', - sdk_version='7.0A', - hkeys=[r'Microsoft\VisualStudio\10.0\Setup\VS\ProductDir'], - common_tools_var='VS100COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64'], - ), - - # Visual C++ 2010 Express Edition - VisualStudio('10.0Exp', - vc_version='10.0', - sdk_version='7.0A', - hkeys=[r'Microsoft\VCExpress\10.0\Setup\VS\ProductDir'], - common_tools_var='VS100COMNTOOLS', - executable_path=r'Common7\IDE\VCExpress.exe', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86'], - ), - - # Visual Studio 2008 - VisualStudio('9.0', - sdk_version='6.0A', - hkeys=[r'Microsoft\VisualStudio\9.0\Setup\VS\ProductDir'], - common_tools_var='VS90COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86', 'amd64'], - ), - - # Visual C++ 2008 Express Edition - VisualStudio('9.0Exp', - vc_version='9.0', - sdk_version='6.0A', - hkeys=[r'Microsoft\VCExpress\9.0\Setup\VS\ProductDir'], - common_tools_var='VS90COMNTOOLS', - executable_path=r'Common7\IDE\VCExpress.exe', - batch_file_path=r'Common7\Tools\vsvars32.bat', - supported_arch=['x86'], - ), - - # Visual Studio 2005 - VisualStudio('8.0', - sdk_version='6.0A', - hkeys=[r'Microsoft\VisualStudio\8.0\Setup\VS\ProductDir'], - common_tools_var='VS80COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - default_dirname='Microsoft Visual Studio 8', - supported_arch=['x86', 'amd64'], - ), - - # Visual C++ 2005 Express Edition - VisualStudio('8.0Exp', - vc_version='8.0Exp', - sdk_version='6.0A', - hkeys=[r'Microsoft\VCExpress\8.0\Setup\VS\ProductDir'], - common_tools_var='VS80COMNTOOLS', - executable_path=r'Common7\IDE\VCExpress.exe', - batch_file_path=r'Common7\Tools\vsvars32.bat', - default_dirname='Microsoft Visual Studio 8', - supported_arch=['x86'], - ), - - # Visual Studio .NET 2003 - VisualStudio('7.1', - sdk_version='6.0', - hkeys=[r'Microsoft\VisualStudio\7.1\Setup\VS\ProductDir'], - common_tools_var='VS71COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - default_dirname='Microsoft Visual Studio .NET 2003', - supported_arch=['x86'], - ), - - # Visual Studio .NET - VisualStudio('7.0', - sdk_version='2003R2', - hkeys=[r'Microsoft\VisualStudio\7.0\Setup\VS\ProductDir'], - common_tools_var='VS70COMNTOOLS', - executable_path=r'Common7\IDE\devenv.com', - batch_file_path=r'Common7\Tools\vsvars32.bat', - default_dirname='Microsoft Visual Studio .NET', - supported_arch=['x86'], - ), - - # Visual Studio 6.0 - VisualStudio('6.0', - sdk_version='2003R1', - hkeys=[r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Studio\ProductDir', - 'use_dir'], - common_tools_var='VS60COMNTOOLS', - executable_path=r'Common\MSDev98\Bin\MSDEV.COM', - batch_file_path=r'Common7\Tools\vsvars32.bat', - default_dirname='Microsoft Visual Studio', - supported_arch=['x86'], - ), -] - -SupportedVSMap = {} -for vs in SupportedVSList: - SupportedVSMap[vs.version] = vs - - -# Finding installed versions of Visual Studio isn't cheap, because it -# goes not only to the registry but also to the disk to sanity-check -# that there is, in fact, a Visual Studio directory there and that the -# registry entry isn't just stale. Find this information once, when -# requested, and cache it. - -InstalledVSList = None -InstalledVSMap = None - -def get_installed_visual_studios(env=None): - global InstalledVSList - global InstalledVSMap - if InstalledVSList is None: - InstalledVSList = [] - InstalledVSMap = {} - for vs in SupportedVSList: - debug('trying to find VS %s' % vs.version) - if vs.get_executable(env): - debug('found VS %s' % vs.version) - InstalledVSList.append(vs) - InstalledVSMap[vs.version] = vs - return InstalledVSList - -def reset_installed_visual_studios(): - global InstalledVSList - global InstalledVSMap - InstalledVSList = None - InstalledVSMap = None - for vs in SupportedVSList: - vs.reset() - - # Need to clear installed VC's as well as they are used in finding - # installed VS's - SCons.Tool.MSCommon.vc.reset_installed_vcs() - - -# We may be asked to update multiple construction environments with -# SDK information. When doing this, we check on-disk for whether -# the SDK has 'mfc' and 'atl' subdirectories. Since going to disk -# is expensive, cache results by directory. - -#SDKEnvironmentUpdates = {} -# -#def set_sdk_by_directory(env, sdk_dir): -# global SDKEnvironmentUpdates -# try: -# env_tuple_list = SDKEnvironmentUpdates[sdk_dir] -# except KeyError: -# env_tuple_list = [] -# SDKEnvironmentUpdates[sdk_dir] = env_tuple_list -# -# include_path = os.path.join(sdk_dir, 'include') -# mfc_path = os.path.join(include_path, 'mfc') -# atl_path = os.path.join(include_path, 'atl') -# -# if os.path.exists(mfc_path): -# env_tuple_list.append(('INCLUDE', mfc_path)) -# if os.path.exists(atl_path): -# env_tuple_list.append(('INCLUDE', atl_path)) -# env_tuple_list.append(('INCLUDE', include_path)) -# -# env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib'))) -# env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib'))) -# env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin'))) -# -# for variable, directory in env_tuple_list: -# env.PrependENVPath(variable, directory) - -def msvs_exists(env=None): - return (len(get_installed_visual_studios(env)) > 0) - -def get_vs_by_version(msvs): - global InstalledVSMap - global SupportedVSMap - - debug('called') - if msvs not in SupportedVSMap: - msg = "Visual Studio version %s is not supported" % repr(msvs) - raise SCons.Errors.UserError(msg) - get_installed_visual_studios() - vs = InstalledVSMap.get(msvs) - debug('InstalledVSMap:%s' % InstalledVSMap) - debug('found vs:%s' % vs) - # Some check like this would let us provide a useful error message - # if they try to set a Visual Studio version that's not installed. - # However, we also want to be able to run tests (like the unit - # tests) on systems that don't, or won't ever, have it installed. - # It might be worth resurrecting this, with some configurable - # setting that the tests can use to bypass the check. - #if not vs: - # msg = "Visual Studio version %s is not installed" % repr(msvs) - # raise SCons.Errors.UserError, msg - return vs - -def get_default_version(env): - """Returns the default version string to use for MSVS. - - If no version was requested by the user through the MSVS environment - variable, query all the available visual studios through - get_installed_visual_studios, and take the highest one. - - Return - ------ - version: str - the default version. - """ - if 'MSVS' not in env or not SCons.Util.is_Dict(env['MSVS']): - # get all versions, and remember them for speed later - versions = [vs.version for vs in get_installed_visual_studios()] - env['MSVS'] = {'VERSIONS' : versions} - else: - versions = env['MSVS'].get('VERSIONS', []) - - if 'MSVS_VERSION' not in env: - if versions: - env['MSVS_VERSION'] = versions[0] #use highest version by default - else: - debug('WARNING: no installed versions found, ' - 'using first in SupportedVSList (%s)' % SupportedVSList[0].version) - env['MSVS_VERSION'] = SupportedVSList[0].version - - env['MSVS']['VERSION'] = env['MSVS_VERSION'] - - return env['MSVS_VERSION'] - -def get_default_arch(env): - """Return the default arch to use for MSVS - - if no version was requested by the user through the MSVS_ARCH environment - variable, select x86 - - Return - ------ - arch: str - """ - arch = env.get('MSVS_ARCH', 'x86') - - msvs = InstalledVSMap.get(env['MSVS_VERSION']) - - if not msvs: - arch = 'x86' - elif arch not in msvs.get_supported_arch(): - fmt = "Visual Studio version %s does not support architecture %s" - raise SCons.Errors.UserError(fmt % (env['MSVS_VERSION'], arch)) - - return arch - -def merge_default_version(env): - version = get_default_version(env) - arch = get_default_arch(env) - -def msvs_setup_env(env): - batfilename = msvs.get_batch_file() - msvs = get_vs_by_version(version) - if msvs is None: - return - - # XXX: I think this is broken. This will silently set a bogus tool instead - # of failing, but there is no other way with the current scons tool - # framework - if batfilename is not None: - - vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE') - - msvs_list = get_installed_visual_studios() - vscommonvarnames = [vs.common_tools_var for vs in msvs_list] - save_ENV = env['ENV'] - nenv = normalize_env(env['ENV'], - ['COMSPEC'] + vscommonvarnames, - force=True) - try: - output = get_output(batfilename, arch, env=nenv) - finally: - env['ENV'] = save_ENV - vars = parse_output(output, vars) - - for k, v in vars.items(): - env.PrependENVPath(k, v, delete_existing=1) - -def query_versions(): - """Query the system to get available versions of VS. A version is - considered when a batfile is found.""" - msvs_list = get_installed_visual_studios() - versions = [msvs.version for msvs in msvs_list] - return versions - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/PharLapCommon.py b/scons/scons-local-4.1.0/SCons/Tool/PharLapCommon.py deleted file mode 100644 index 9ffafa9e5..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/PharLapCommon.py +++ /dev/null @@ -1,116 +0,0 @@ -"""SCons.Tool.PharLapCommon - -This module contains common code used by all Tools for the -Phar Lap ETS tool chain. Right now, this is linkloc and -386asm. - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import os.path -import SCons.Errors -import SCons.Util -import re - -def getPharLapPath(): - """Reads the registry to find the installed path of the Phar Lap ETS - development kit. - - Raises UserError if no installed version of Phar Lap can - be found.""" - - if not SCons.Util.can_read_reg: - raise SCons.Errors.InternalError("No Windows registry module was found") - try: - k=SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, - 'SOFTWARE\\Pharlap\\ETS') - val, type = SCons.Util.RegQueryValueEx(k, 'BaseDir') - - # The following is a hack...there is (not surprisingly) - # an odd issue in the Phar Lap plug in that inserts - # a bunch of junk data after the phar lap path in the - # registry. We must trim it. - idx=val.find('\0') - if idx >= 0: - val = val[:idx] - - return os.path.normpath(val) - except SCons.Util.RegError: - raise SCons.Errors.UserError("Cannot find Phar Lap ETS path in the registry. Is it installed properly?") - -REGEX_ETS_VER = re.compile(r'#define\s+ETS_VER\s+([0-9]+)') - -def getPharLapVersion(): - """Returns the version of the installed ETS Tool Suite as a - decimal number. This version comes from the ETS_VER #define in - the embkern.h header. For example, '#define ETS_VER 1010' (which - is what Phar Lap 10.1 defines) would cause this method to return - 1010. Phar Lap 9.1 does not have such a #define, but this method - will return 910 as a default. - - Raises UserError if no installed version of Phar Lap can - be found.""" - - include_path = os.path.join(getPharLapPath(), os.path.normpath("include/embkern.h")) - if not os.path.exists(include_path): - raise SCons.Errors.UserError("Cannot find embkern.h in ETS include directory.\nIs Phar Lap ETS installed properly?") - with open(include_path, 'r') as f: - mo = REGEX_ETS_VER.search(f.read()) - if mo: - return int(mo.group(1)) - # Default return for Phar Lap 9.1 - return 910 - -def addPharLapPaths(env): - """This function adds the path to the Phar Lap binaries, includes, - and libraries, if they are not already there.""" - ph_path = getPharLapPath() - - try: - env_dict = env['ENV'] - except KeyError: - env_dict = {} - env['ENV'] = env_dict - SCons.Util.AddPathIfNotExists(env_dict, 'PATH', - os.path.join(ph_path, 'bin')) - SCons.Util.AddPathIfNotExists(env_dict, 'INCLUDE', - os.path.join(ph_path, 'include')) - SCons.Util.AddPathIfNotExists(env_dict, 'LIB', - os.path.join(ph_path, 'lib')) - SCons.Util.AddPathIfNotExists(env_dict, 'LIB', - os.path.join(ph_path, os.path.normpath('lib/vclib'))) - - env['PHARLAP_PATH'] = getPharLapPath() - env['PHARLAP_VERSION'] = str(getPharLapVersion()) - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/__init__.py b/scons/scons-local-4.1.0/SCons/Tool/__init__.py deleted file mode 100644 index 63f6a5958..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/__init__.py +++ /dev/null @@ -1,868 +0,0 @@ -# MIT License -# -# Copyright 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.Tool - -SCons tool selection. - -This looks for modules that define a callable object that can modify -a construction environment as appropriate for a given tool (or tool -chain). - -Note that because this subsystem just *selects* a callable that can -modify a construction environment, it's possible for people to define -their own "tool specification" in an arbitrary callable function. No -one needs to use or tie in to this subsystem in order to roll their own -tool specifications. -""" - - - -import sys -import os -import importlib.util - -import SCons.Builder -import SCons.Errors -import SCons.Node.FS -import SCons.Scanner -import SCons.Scanner.C -import SCons.Scanner.D -import SCons.Scanner.LaTeX -import SCons.Scanner.Prog -import SCons.Scanner.SWIG -from SCons.Tool.linkCommon import LibSymlinksActionFunction, LibSymlinksStrFun - -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') -SWIGScanner = SCons.Scanner.SWIG.SWIGScanner() - -CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", - ".h", ".H", ".hxx", ".hpp", ".hh", - ".F", ".fpp", ".FPP", - ".m", ".mm", - ".S", ".spp", ".SPP", ".sx"] - -DSuffixes = ['.d'] - -IDLSuffixes = [".idl", ".IDL"] - -LaTeXSuffixes = [".tex", ".ltx", ".latex"] - -SWIGSuffixes = ['.i'] - -for suffix in CSuffixes: - SourceFileScanner.add_scanner(suffix, CScanner) - -for suffix in DSuffixes: - SourceFileScanner.add_scanner(suffix, DScanner) - -for suffix in SWIGSuffixes: - SourceFileScanner.add_scanner(suffix, SWIGScanner) - -# 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, PDFLaTeXScanner) - -# Tool aliases are needed for those tools whose module names also -# occur in the python standard library (This causes module shadowing and -# can break using python library functions under python3) or if the current tool/file names -# are not legal module names (violate python's identifier rules or are -# python language keywords). -TOOL_ALIASES = { - 'gettext': 'gettext_tool', - 'clang++': 'clangxx', - 'as': 'asm', -} - - -class Tool: - def __init__(self, name, toolpath=None, **kw): - if toolpath is None: - toolpath = [] - - # Rename if there's a TOOL_ALIAS for this tool - self.name = TOOL_ALIASES.get(name, name) - self.toolpath = toolpath + DefaultToolpath - # remember these so we can merge them into the call - self.init_kw = kw - - module = self._tool_module() - self.generate = module.generate - self.exists = module.exists - if hasattr(module, 'options'): - self.options = module.options - - def _load_dotted_module_py2(self, short_name, full_name, searchpaths=None): - import imp - - splitname = short_name.split('.') - index = 0 - srchpths = searchpaths - for item in splitname: - file, path, desc = imp.find_module(item, srchpths) - mod = imp.load_module(full_name, file, path, desc) - srchpths = [path] - return mod, file - - def _tool_module(self): - oldpythonpath = sys.path - sys.path = self.toolpath + sys.path - # sys.stderr.write("Tool:%s\nPATH:%s\n"%(self.name,sys.path)) - - # From: http://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path/67692#67692 - # import importlib.util - # spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py") - # foo = importlib.util.module_from_spec(spec) - # spec.loader.exec_module(foo) - # foo.MyClass() - # Py 3 code - - - # sys.stderr.write("toolpath:%s\n" % self.toolpath) - # sys.stderr.write("SCONS.TOOL path:%s\n" % sys.modules['SCons.Tool'].__path__) - debug = False - spec = None - found_name = self.name - add_to_scons_tools_namespace = False - for path in self.toolpath: - sepname = self.name.replace('.', os.path.sep) - file_path = os.path.join(path, "%s.py" % sepname) - file_package = os.path.join(path, sepname) - - if debug: sys.stderr.write("Trying:%s %s\n" % (file_path, file_package)) - - if os.path.isfile(file_path): - spec = importlib.util.spec_from_file_location(self.name, file_path) - if debug: print("file_Path:%s FOUND" % file_path) - break - elif os.path.isdir(file_package): - file_package = os.path.join(file_package, '__init__.py') - spec = importlib.util.spec_from_file_location(self.name, file_package) - if debug: print("PACKAGE:%s Found" % file_package) - break - - else: - continue - - if spec is None: - if debug: sys.stderr.write("NO SPEC :%s\n" % self.name) - spec = importlib.util.find_spec("." + self.name, package='SCons.Tool') - if spec: - found_name = 'SCons.Tool.' + self.name - add_to_scons_tools_namespace = True - if debug: sys.stderr.write("Spec Found? .%s :%s\n" % (self.name, spec)) - - if spec is None: - sconstools = os.path.normpath(sys.modules['SCons.Tool'].__path__[0]) - if self.toolpath: - sconstools = ", ".join(self.toolpath) + ", " + sconstools - error_string = "No tool module '%s' found in %s" % (self.name, sconstools) - raise SCons.Errors.UserError(error_string) - - module = importlib.util.module_from_spec(spec) - if module is None: - if debug: print("MODULE IS NONE:%s" % self.name) - error_string = "Tool module '%s' failed import" % self.name - raise SCons.Errors.SConsEnvironmentError(error_string) - - # Don't reload a tool we already loaded. - sys_modules_value = sys.modules.get(found_name, False) - - found_module = None - if sys_modules_value and sys_modules_value.__file__ == spec.origin: - found_module = sys.modules[found_name] - else: - # Not sure what to do in the case that there already - # exists sys.modules[self.name] but the source file is - # different.. ? - module = spec.loader.load_module(spec.name) - - sys.modules[found_name] = module - if add_to_scons_tools_namespace: - # If we found it in SCons.Tool, then add it to the module - setattr(SCons.Tool, self.name, module) - - found_module = module - - if found_module is not None: - sys.path = oldpythonpath - return found_module - - sys.path = oldpythonpath - - full_name = 'SCons.Tool.' + self.name - try: - return sys.modules[full_name] - except KeyError: - try: - smpath = sys.modules['SCons.Tool'].__path__ - try: - module, file = self._load_dotted_module_py2(self.name, full_name, smpath) - setattr(SCons.Tool, self.name, module) - if file: - file.close() - return module - except ImportError as e: - if str(e) != "No module named %s" % self.name: - raise SCons.Errors.SConsEnvironmentError(e) - try: - import zipimport - importer = zipimport.zipimporter(sys.modules['SCons.Tool'].__path__[0]) - module = importer.load_module(full_name) - setattr(SCons.Tool, self.name, module) - return module - except ImportError as e: - m = "No tool named '%s': %s" % (self.name, e) - raise SCons.Errors.SConsEnvironmentError(m) - except ImportError as e: - m = "No tool named '%s': %s" % (self.name, e) - raise SCons.Errors.SConsEnvironmentError(m) - - def __call__(self, env, *args, **kw): - if self.init_kw is not None: - # Merge call kws into init kws; - # but don't bash self.init_kw. - if kw is not None: - call_kw = kw - kw = self.init_kw.copy() - kw.update(call_kw) - else: - kw = self.init_kw - env.Append(TOOLS=[self.name]) - if hasattr(self, 'options'): - import SCons.Variables - if 'options' not in env: - from SCons.Script import ARGUMENTS - env['options'] = SCons.Variables.Variables(args=ARGUMENTS) - opts = env['options'] - - self.options(opts) - opts.Update(env) - - self.generate(env, *args, **kw) - - def __str__(self): - return self.name - - -LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun) - - -########################################################################## -# Create common executable program / library / object builders - -def createProgBuilder(env): - """This is a utility function that creates the Program - Builder in an Environment if it is not there already. - - If it is already there, we return the existing one. - """ - - try: - program = env['BUILDERS']['Program'] - except KeyError: - import SCons.Defaults - program = SCons.Builder.Builder(action=SCons.Defaults.LinkAction, - emitter='$PROGEMITTER', - prefix='$PROGPREFIX', - suffix='$PROGSUFFIX', - src_suffix='$OBJSUFFIX', - src_builder='Object', - target_scanner=ProgramScanner) - env['BUILDERS']['Program'] = program - - return program - - -def createStaticLibBuilder(env): - """This is a utility function that creates the StaticLibrary - Builder in an Environment if it is not there already. - - If it is already there, we return the existing one. - """ - - try: - static_lib = env['BUILDERS']['StaticLibrary'] - except KeyError: - action_list = [SCons.Action.Action("$ARCOM", "$ARCOMSTR")] - if env.get('RANLIB', False) or env.Detect('ranlib'): - ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") - action_list.append(ranlib_action) - - static_lib = SCons.Builder.Builder(action=action_list, - emitter='$LIBEMITTER', - prefix='$LIBPREFIX', - suffix='$LIBSUFFIX', - src_suffix='$OBJSUFFIX', - src_builder='StaticObject') - env['BUILDERS']['StaticLibrary'] = static_lib - env['BUILDERS']['Library'] = static_lib - - return static_lib - - -def createSharedLibBuilder(env, shlib_suffix='$_SHLIBSUFFIX'): - """This is a utility function that creates the SharedLibrary - Builder in an Environment if it is not there already. - - If it is already there, we return the existing one. - - Args: - shlib_suffix: The suffix specified for the shared library builder - - """ - - try: - shared_lib = env['BUILDERS']['SharedLibrary'] - except KeyError: - import SCons.Defaults - action_list = [SCons.Defaults.SharedCheck, - SCons.Defaults.ShLinkAction, - LibSymlinksAction] - shared_lib = SCons.Builder.Builder(action=action_list, - emitter="$SHLIBEMITTER", - prefix="$SHLIBPREFIX", - suffix=shlib_suffix, - target_scanner=ProgramScanner, - src_suffix='$SHOBJSUFFIX', - src_builder='SharedObject') - env['BUILDERS']['SharedLibrary'] = shared_lib - - return shared_lib - - -def createLoadableModuleBuilder(env, loadable_module_suffix='$_LDMODULESUFFIX'): - """This is a utility function that creates the LoadableModule - Builder in an Environment if it is not there already. - - If it is already there, we return the existing one. - - Args: - loadable_module_suffix: The suffix specified for the loadable module builder - - """ - - try: - ld_module = env['BUILDERS']['LoadableModule'] - except KeyError: - import SCons.Defaults - action_list = [SCons.Defaults.SharedCheck, - SCons.Defaults.LdModuleLinkAction, - LibSymlinksAction] - ld_module = SCons.Builder.Builder(action=action_list, - emitter="$LDMODULEEMITTER", - prefix="$LDMODULEPREFIX", - suffix=loadable_module_suffix, - target_scanner=ProgramScanner, - src_suffix='$SHOBJSUFFIX', - src_builder='SharedObject') - env['BUILDERS']['LoadableModule'] = ld_module - - return ld_module - - -def createObjBuilders(env): - """This is a utility function that creates the StaticObject - and SharedObject Builders in an Environment if they - are not there already. - - If they are there already, we return the existing ones. - - This is a separate function because soooo many Tools - use this functionality. - - The return is a 2-tuple of (StaticObject, SharedObject) - """ - - try: - static_obj = env['BUILDERS']['StaticObject'] - except KeyError: - static_obj = SCons.Builder.Builder(action={}, - emitter={}, - prefix='$OBJPREFIX', - suffix='$OBJSUFFIX', - src_builder=['CFile', 'CXXFile'], - source_scanner=SourceFileScanner, - single_source=1) - env['BUILDERS']['StaticObject'] = static_obj - env['BUILDERS']['Object'] = static_obj - - try: - shared_obj = env['BUILDERS']['SharedObject'] - except KeyError: - shared_obj = SCons.Builder.Builder(action={}, - emitter={}, - prefix='$SHOBJPREFIX', - suffix='$SHOBJSUFFIX', - src_builder=['CFile', 'CXXFile'], - source_scanner=SourceFileScanner, - single_source=1) - env['BUILDERS']['SharedObject'] = shared_obj - - return (static_obj, shared_obj) - - -def createCFileBuilders(env): - """This is a utility function that creates the CFile/CXXFile - Builders in an Environment if they - are not there already. - - If they are there already, we return the existing ones. - - This is a separate function because soooo many Tools - use this functionality. - - The return is a 2-tuple of (CFile, CXXFile) - """ - - try: - c_file = env['BUILDERS']['CFile'] - except KeyError: - c_file = SCons.Builder.Builder(action={}, - emitter={}, - suffix={None: '$CFILESUFFIX'}) - env['BUILDERS']['CFile'] = c_file - - env.SetDefault(CFILESUFFIX='.c') - - try: - cxx_file = env['BUILDERS']['CXXFile'] - except KeyError: - cxx_file = SCons.Builder.Builder(action={}, - emitter={}, - suffix={None: '$CXXFILESUFFIX'}) - env['BUILDERS']['CXXFile'] = cxx_file - env.SetDefault(CXXFILESUFFIX='.cc') - - return (c_file, cxx_file) - - -########################################################################## -# Create common Java builders - -def CreateJarBuilder(env): - """The Jar builder expects a list of class files - which it can package into a jar file. - - The jar tool provides an interface for passing other types - of java files such as .java, directories or swig interfaces - and will build them to class files in which it can package - into the jar. - """ - try: - java_jar = env['BUILDERS']['JarFile'] - except KeyError: - fs = SCons.Node.FS.get_default_fs() - jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR') - java_jar = SCons.Builder.Builder(action=jar_com, - suffix='$JARSUFFIX', - src_suffix='$JAVACLASSSUFFIX', - src_builder='JavaClassFile', - source_factory=fs.Entry) - env['BUILDERS']['JarFile'] = java_jar - return java_jar - - -def CreateJavaHBuilder(env): - try: - java_javah = env['BUILDERS']['JavaH'] - except KeyError: - fs = SCons.Node.FS.get_default_fs() - java_javah_com = SCons.Action.Action('$JAVAHCOM', '$JAVAHCOMSTR') - java_javah = SCons.Builder.Builder(action=java_javah_com, - src_suffix='$JAVACLASSSUFFIX', - target_factory=fs.Entry, - source_factory=fs.File, - src_builder='JavaClassFile') - env['BUILDERS']['JavaH'] = java_javah - return java_javah - - -def CreateJavaClassFileBuilder(env): - try: - java_class_file = env['BUILDERS']['JavaClassFile'] - except KeyError: - fs = SCons.Node.FS.get_default_fs() - javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') - java_class_file = SCons.Builder.Builder(action=javac_com, - emitter={}, - # suffix = '$JAVACLASSSUFFIX', - src_suffix='$JAVASUFFIX', - src_builder=['JavaFile'], - target_factory=fs.Entry, - source_factory=fs.File) - env['BUILDERS']['JavaClassFile'] = java_class_file - return java_class_file - - -def CreateJavaClassDirBuilder(env): - try: - java_class_dir = env['BUILDERS']['JavaClassDir'] - except KeyError: - fs = SCons.Node.FS.get_default_fs() - javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') - java_class_dir = SCons.Builder.Builder(action=javac_com, - emitter={}, - target_factory=fs.Dir, - source_factory=fs.Dir) - env['BUILDERS']['JavaClassDir'] = java_class_dir - return java_class_dir - - -def CreateJavaFileBuilder(env): - try: - java_file = env['BUILDERS']['JavaFile'] - except KeyError: - java_file = SCons.Builder.Builder(action={}, - emitter={}, - suffix={None: '$JAVASUFFIX'}) - env['BUILDERS']['JavaFile'] = java_file - env['JAVASUFFIX'] = '.java' - return java_file - - -class ToolInitializerMethod: - """ - 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, 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 - 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: - # There was no Builder added, which means no valid Tool - # 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). - return None - - self.initializer.remove_methods(env) - - return builder - - def __call__(self, env, *args, **kw): - """ - """ - builder = self.get_builder(env) - if builder is None: - return [], [] - return 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): - ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs', '_InternalInstallVersionedLib']) - - def Install(self, *args, **kw): - return self._InternalInstall(*args, **kw) - - def InstallAs(self, *args, **kw): - return self._InternalInstallAs(*args, **kw) - - def InstallVersionedLib(self, *args, **kw): - return self._InternalInstallVersionedLib(*args, **kw) - - env.AddMethod(Install) - env.AddMethod(InstallAs) - env.AddMethod(InstallVersionedLib) - - -def FindTool(tools, env): - for tool in tools: - t = Tool(tool) - if t.exists(env): - return tool - return None - - -def FindAllTools(tools, env): - def ToolExists(tool, env=env): - return Tool(tool).exists(env) - - return list(filter(ToolExists, tools)) - - -def tool_list(platform, env): - other_plat_tools = [] - # XXX this logic about what tool to prefer on which platform - # should be moved into either the platform files or - # the tool files themselves. - # The search orders here are described in the man page. If you - # change these search orders, update the man page as well. - if str(platform) == 'win32': - "prefer Microsoft tools on Windows" - linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32'] - c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32'] - cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'cxx', 'bcc32'] - assemblers = ['masm', 'nasm', 'gas', '386asm'] - fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran'] - ars = ['mslib', 'ar', 'tlib'] - other_plat_tools = ['msvs', 'midl', 'wix'] - elif str(platform) == 'os2': - "prefer IBM tools on OS/2" - linkers = ['ilink', 'gnulink', ] # 'mslink'] - c_compilers = ['icc', 'gcc', ] # 'msvc', 'cc'] - cxx_compilers = ['icc', 'g++', ] # 'msvc', 'cxx'] - assemblers = ['nasm', ] # 'masm', 'gas'] - fortran_compilers = ['ifl', 'g77'] - ars = ['ar', ] # 'mslib'] - elif str(platform) == 'irix': - "prefer MIPSPro on IRIX" - linkers = ['sgilink', 'gnulink'] - c_compilers = ['sgicc', 'gcc', 'cc'] - cxx_compilers = ['sgicxx', 'g++', 'cxx'] - assemblers = ['as', 'gas'] - fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran'] - ars = ['sgiar'] - elif str(platform) == 'sunos': - "prefer Forte tools on SunOS" - linkers = ['sunlink', 'gnulink'] - c_compilers = ['suncc', 'gcc', 'cc'] - cxx_compilers = ['suncxx', 'g++', 'cxx'] - assemblers = ['as', 'gas'] - fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77', - 'gfortran', 'g77', 'fortran'] - ars = ['sunar'] - elif str(platform) == 'hpux': - "prefer aCC tools on HP-UX" - linkers = ['hplink', 'gnulink'] - c_compilers = ['hpcc', 'gcc', 'cc'] - cxx_compilers = ['hpcxx', 'g++', 'cxx'] - assemblers = ['as', 'gas'] - fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran'] - ars = ['ar'] - elif str(platform) == 'aix': - "prefer AIX Visual Age tools on AIX" - linkers = ['aixlink', 'gnulink'] - c_compilers = ['aixcc', 'gcc', 'cc'] - cxx_compilers = ['aixcxx', 'g++', 'cxx'] - assemblers = ['as', 'gas'] - fortran_compilers = ['f95', 'f90', 'aixf77', 'g77', 'fortran'] - ars = ['ar'] - elif str(platform) == 'darwin': - "prefer GNU tools on Mac OS X, except for some linkers and IBM tools" - linkers = ['applelink', 'gnulink'] - c_compilers = ['gcc', 'cc'] - cxx_compilers = ['g++', 'cxx'] - assemblers = ['as'] - fortran_compilers = ['gfortran', 'f95', 'f90', 'g77'] - ars = ['ar'] - elif str(platform) == 'cygwin': - "prefer GNU tools on Cygwin, except for a platform-specific linker" - linkers = ['cyglink', 'mslink', 'ilink'] - c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc'] - cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'cxx'] - assemblers = ['gas', 'nasm', 'masm'] - fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77'] - ars = ['ar', 'mslib'] - else: - "prefer GNU tools on all other platforms" - linkers = ['gnulink', 'ilink'] - c_compilers = ['gcc', 'intelc', 'icc', 'cc'] - cxx_compilers = ['g++', 'intelc', 'icc', 'cxx'] - assemblers = ['gas', 'nasm', 'masm'] - fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77'] - ars = ['ar', ] - - if not str(platform) == 'win32': - other_plat_tools += ['m4', 'rpm'] - - c_compiler = FindTool(c_compilers, env) or c_compilers[0] - - # XXX this logic about what tool provides what should somehow be - # moved into the tool files themselves. - if c_compiler and c_compiler == 'mingw': - # MinGW contains a linker, C compiler, C++ compiler, - # Fortran compiler, archiver and assembler: - cxx_compiler = None - linker = None - assembler = None - fortran_compiler = None - ar = None - else: - # Don't use g++ if the C compiler has built-in C++ support: - if c_compiler in ('msvc', 'intelc', 'icc'): - cxx_compiler = None - else: - cxx_compiler = FindTool(cxx_compilers, env) or cxx_compilers[0] - linker = FindTool(linkers, env) or linkers[0] - assembler = FindTool(assemblers, env) or assemblers[0] - fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0] - ar = FindTool(ars, env) or ars[0] - - d_compilers = ['dmd', 'ldc', 'gdc'] - d_compiler = FindTool(d_compilers, env) or d_compilers[0] - - other_tools = FindAllTools(other_plat_tools + [ - # TODO: merge 'install' into 'filesystem' and - # make 'filesystem' the default - 'filesystem', - # Parser generators - 'lex', 'yacc', - # Foreign function interface - 'rpcgen', 'swig', - # Java - 'jar', 'javac', 'javah', 'rmic', - # TeX - 'dvipdf', 'dvips', 'gs', - 'tex', 'latex', 'pdflatex', 'pdftex', - # Archivers - 'tar', 'zip', - # File builders (text) - 'textfile', - ], env) - - tools = [ - linker, - c_compiler, - cxx_compiler, - fortran_compiler, - assembler, - ar, - d_compiler, - ] + other_tools - - return [x for x in tools if x] - - -def find_program_path(env, key_program, default_paths=None): - """ - Find the location of a tool using various means. - - Mainly for windows where tools aren't all installed in /usr/bin, etc. - - :param env: Current Construction Environment. - :param key_program: Tool to locate. - :param default_paths: List of additional paths this tool might be found in. - """ - # First search in the SCons path - path = env.WhereIs(key_program) - if path: - return path - - # Then in the OS path - path = SCons.Util.WhereIs(key_program) - if path: - return path - - # Finally, add the defaults and check again. Do not change - # ['ENV']['PATH'] permananetly, the caller can do that if needed. - if default_paths is None: - return path - save_path = env['ENV']['PATH'] - for p in default_paths: - env.AppendENVPath('PATH', p) - path = env.WhereIs(key_program) - env['ENV']['PATH'] = save_path - return path - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/aixc++.py b/scons/scons-local-4.1.0/SCons/Tool/aixc++.py deleted file mode 100644 index c3efaea44..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/aixc++.py +++ /dev/null @@ -1,43 +0,0 @@ -"""SCons.Tool.aixc++ - -Tool-specific initialization for IBM xlC / Visual Age C++ 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -#forward proxy to the preffered cxx version -from SCons.Tool.aixcxx import * - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/aixcc.py b/scons/scons-local-4.1.0/SCons/Tool/aixcc.py deleted file mode 100644 index 09365b1df..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/aixcc.py +++ /dev/null @@ -1,74 +0,0 @@ -"""SCons.Tool.aixcc - -Tool-specific initialization for IBM xlc / Visual Age C 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path - -import SCons.Platform.aix - -from . import cc - -packages = ['vac.C', 'ibmcxx.cmp'] - -def get_xlc(env): - xlc = env.get('CC', 'xlc') - return SCons.Platform.aix.get_xlc(env, xlc, packages) - -def generate(env): - """Add Builders and construction variables for xlc / Visual Age - suite to an Environment.""" - path, _cc, version = get_xlc(env) - if path and _cc: - _cc = os.path.join(path, _cc) - - if 'CC' not in env: - env['CC'] = _cc - - cc.generate(env) - - if version: - env['CCVERSION'] = version - -def exists(env): - path, _cc, version = get_xlc(env) - if path and _cc: - xlc = os.path.join(path, _cc) - if os.path.exists(xlc): - return xlc - return None - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/aixcxx.py b/scons/scons-local-4.1.0/SCons/Tool/aixcxx.py deleted file mode 100644 index 58d9ecca9..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/aixcxx.py +++ /dev/null @@ -1,77 +0,0 @@ -"""SCons.Tool.aixc++ - -Tool-specific initialization for IBM xlC / Visual Age C++ 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path - -import SCons.Platform.aix - -import SCons.Tool.cxx -cplusplus = SCons.Tool.cxx -#cplusplus = __import__('cxx', globals(), locals(), []) - -packages = ['vacpp.cmp.core', 'vacpp.cmp.batch', 'vacpp.cmp.C', 'ibmcxx.cmp'] - -def get_xlc(env): - xlc = env.get('CXX', 'xlC') - return SCons.Platform.aix.get_xlc(env, xlc, packages) - -def generate(env): - """Add Builders and construction variables for xlC / Visual Age - suite to an Environment.""" - path, _cxx, version = get_xlc(env) - if path and _cxx: - _cxx = os.path.join(path, _cxx) - - if 'CXX' not in env: - env['CXX'] = _cxx - - cplusplus.generate(env) - - if version: - env['CXXVERSION'] = version - -def exists(env): - path, _cxx, version = get_xlc(env) - if path and _cxx: - xlc = os.path.join(path, _cxx) - if os.path.exists(xlc): - return xlc - return None - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/aixf77.py b/scons/scons-local-4.1.0/SCons/Tool/aixf77.py deleted file mode 100644 index 4cef908fa..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/aixf77.py +++ /dev/null @@ -1,80 +0,0 @@ -"""SCons.Tool.aixf77 - -Tool-specific initialization for IBM Visual Age 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path - -#import SCons.Platform.aix - -from . import f77 - -# It would be good to look for the AIX F77 package the same way we're now -# looking for the C and C++ packages. This should be as easy as supplying -# the correct package names in the following list and uncommenting the -# SCons.Platform.aix_get_xlc() call in the function below. -packages = [] - -def get_xlf77(env): - xlf77 = env.get('F77', 'xlf77') - xlf77_r = env.get('SHF77', 'xlf77_r') - #return SCons.Platform.aix.get_xlc(env, xlf77, xlf77_r, packages) - return (None, xlf77, xlf77_r, None) - -def generate(env): - """ - Add Builders and construction variables for the Visual Age FORTRAN - compiler to an Environment. - """ - path, _f77, _shf77, version = get_xlf77(env) - if path: - _f77 = os.path.join(path, _f77) - _shf77 = os.path.join(path, _shf77) - - f77.generate(env) - - env['F77'] = _f77 - env['SHF77'] = _shf77 - -def exists(env): - path, _f77, _shf77, version = get_xlf77(env) - if path and _f77: - xlf77 = os.path.join(path, _f77) - if os.path.exists(xlf77): - return xlf77 - return None - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/aixlink.py b/scons/scons-local-4.1.0/SCons/Tool/aixlink.py deleted file mode 100644 index dc0de2a3d..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/aixlink.py +++ /dev/null @@ -1,78 +0,0 @@ -"""SCons.Tool.aixlink - -Tool-specific initialization for the IBM Visual Age linker. - -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. -""" - -# -# 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. -# - -import os -import os.path - -import SCons.Util - -from . import aixcc -from . import link - -import SCons.Tool.cxx -cplusplus = SCons.Tool.cxx - - -def smart_linkflags(source, target, env, for_signature): - if cplusplus.iscplusplus(source): - build_dir = env.subst('$BUILDDIR', target=target, source=source) - if build_dir: - return '-qtempinc=' + os.path.join(build_dir, 'tempinc') - return '' - - -def generate(env): - """ - Add Builders and construction variables for Visual Age linker to - an Environment. - """ - link.generate(env) - - env['SMARTLINKFLAGS'] = smart_linkflags - env['LINKFLAGS'] = SCons.Util.CLVar('$SMARTLINKFLAGS') - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -qmkshrobj -qsuppress=1501-218') - env['SHLIBSUFFIX'] = '.a' - - -def exists(env): - # TODO: sync with link.smart_link() to choose a linker - linkers = { 'CXX': ['aixc++'], 'CC': ['aixcc'] } - alltools = [] - for langvar, linktools in linkers.items(): - if langvar in env: # use CC over CXX when user specified CC but not CXX - return SCons.Tool.FindTool(linktools, env) - alltools.extend(linktools) - return SCons.Tool.FindTool(alltools, env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/applelink.py b/scons/scons-local-4.1.0/SCons/Tool/applelink.py deleted file mode 100644 index 2cdbd50b2..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/applelink.py +++ /dev/null @@ -1,189 +0,0 @@ -"""SCons.Tool.applelink - -Tool-specific initialization for Apple's gnu-like linker. - -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. - -""" - -# -# MIT License -# -# Copyright 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. -# - -# 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". -from SCons.Util import CLVar - -from . import link - -# User programmatically describes how SHLIBVERSION maps to values for compat/current. -_APPLELIB_MAX_VERSION_VALUES = (65535, 255, 255) - - -class AppleLinkInvalidCurrentVersionException(Exception): - pass - - -class AppleLinkInvalidCompatibilityVersionException(Exception): - pass - - -def _applelib_check_valid_version(version_string): - """ - Check that the version # is valid. - X[.Y[.Z]] - where X 0-65535 - where Y either not specified or 0-255 - where Z either not specified or 0-255 - :param version_string: - :return: - """ - parts = version_string.split('.') - if len(parts) > 3: - return False, "Version string has too many periods [%s]" % version_string - if len(parts) <= 0: - return False, "Version string unspecified [%s]" % version_string - - for (i, p) in enumerate(parts): - try: - p_i = int(p) - except ValueError: - return False, "Version component %s (from %s) is not a number" % (p, version_string) - if p_i < 0 or p_i > _APPLELIB_MAX_VERSION_VALUES[i]: - return False, "Version component %s (from %s) is not valid value should be between 0 and %d" % ( - p, version_string, _APPLELIB_MAX_VERSION_VALUES[i]) - - return True, "" - - -def _applelib_currentVersionFromSoVersion(source, target, env, for_signature): - """ - A generator function to create the -Wl,-current_version flag if needed. - If env['APPLELINK_NO_CURRENT_VERSION'] contains a true value no flag will be generated - Otherwise if APPLELINK_CURRENT_VERSION is not specified, env['SHLIBVERSION'] - will be used. - - :param source: - :param target: - :param env: - :param for_signature: - :return: A string providing the flag to specify the current_version of the shared library - """ - if env.get('APPLELINK_NO_CURRENT_VERSION', False): - return "" - elif env.get('APPLELINK_CURRENT_VERSION', False): - version_string = env['APPLELINK_CURRENT_VERSION'] - elif env.get('SHLIBVERSION', False): - version_string = env['SHLIBVERSION'] - else: - return "" - - version_string = ".".join(version_string.split('.')[:3]) - - valid, reason = _applelib_check_valid_version(version_string) - if not valid: - raise AppleLinkInvalidCurrentVersionException(reason) - - return "-Wl,-current_version,%s" % version_string - - -def _applelib_compatVersionFromSoVersion(source, target, env, for_signature): - """ - A generator function to create the -Wl,-compatibility_version flag if needed. - If env['APPLELINK_NO_COMPATIBILITY_VERSION'] contains a true value no flag will be generated - Otherwise if APPLELINK_COMPATIBILITY_VERSION is not specified - the first two parts of env['SHLIBVERSION'] will be used with a .0 appended. - - :param source: - :param target: - :param env: - :param for_signature: - :return: A string providing the flag to specify the compatibility_version of the shared library - """ - if env.get('APPLELINK_NO_COMPATIBILITY_VERSION', False): - return "" - elif env.get('APPLELINK_COMPATIBILITY_VERSION', False): - version_string = env['APPLELINK_COMPATIBILITY_VERSION'] - elif env.get('SHLIBVERSION', False): - version_string = ".".join(env['SHLIBVERSION'].split('.')[:2] + ['0']) - else: - return "" - - if version_string is None: - return "" - - valid, reason = _applelib_check_valid_version(version_string) - if not valid: - raise AppleLinkInvalidCompatibilityVersionException(reason) - - return "-Wl,-compatibility_version,%s" % version_string - - -def generate(env): - """Add Builders and construction variables for applelink to an - Environment.""" - link.generate(env) - - env['FRAMEWORKPATHPREFIX'] = '-F' - env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__, RDirs)}' - - env['_FRAMEWORKS'] = '${_concat("-framework ", FRAMEWORKS, "", __env__)}' - env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' - env['SHLINKFLAGS'] = CLVar('$LINKFLAGS -dynamiclib') - env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' - - env['_APPLELINK_CURRENT_VERSION'] = _applelib_currentVersionFromSoVersion - env['_APPLELINK_COMPATIBILITY_VERSION'] = _applelib_compatVersionFromSoVersion - env['_SHLIBVERSIONFLAGS'] = '$_APPLELINK_CURRENT_VERSION $_APPLELINK_COMPATIBILITY_VERSION ' - env['_LDMODULEVERSIONFLAGS'] = '$_APPLELINK_CURRENT_VERSION $_APPLELINK_COMPATIBILITY_VERSION ' - - # override the default for loadable modules, which are different - # on OS X than dynamic shared libs. echoing what XCode does for - # pre/suffixes: - env['LDMODULEPREFIX'] = '' - env['LDMODULESUFFIX'] = '' - env['LDMODULEFLAGS'] = CLVar('$LINKFLAGS -bundle') - env['LDMODULECOM'] = '$LDMODULE -o ${TARGET} $LDMODULEFLAGS' \ - ' $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' - - # New stuff - # - env['_SHLIBSUFFIX'] = '${_SHLIBVERSION}${SHLIBSUFFIX}' - - env['__SHLIBVERSIONFLAGS'] = '${__lib_either_version_flag(__env__,' \ - '"SHLIBVERSION","_APPLELINK_CURRENT_VERSION", "_SHLIBVERSIONFLAGS")}' - env['__LDMODULEVERSIONFLAGS'] = '${__lib_either_version_flag(__env__,' \ - '"LDMODULEVERSION","_APPLELINK_CURRENT_VERSION", "_LDMODULEVERSIONFLAGS")}' - - -def exists(env): - return env['PLATFORM'] == 'darwin' - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/ar.py b/scons/scons-local-4.1.0/SCons/Tool/ar.py deleted file mode 100644 index 2cd15c844..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/ar.py +++ /dev/null @@ -1,63 +0,0 @@ -"""SCons.Tool.ar - -Tool-specific initialization for ar (library archive). - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util - - -def generate(env): - """Add Builders and construction variables for ar to an Environment.""" - SCons.Tool.createStaticLibBuilder(env) - - env['AR'] = 'ar' - env['ARFLAGS'] = SCons.Util.CLVar('rc') - env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES' - env['LIBPREFIX'] = 'lib' - env['LIBSUFFIX'] = '.a' - - if env.get('RANLIB',env.Detect('ranlib')) : - env['RANLIB'] = env.get('RANLIB','ranlib') - env['RANLIBFLAGS'] = SCons.Util.CLVar('') - env['RANLIBCOM'] = '$RANLIB $RANLIBFLAGS $TARGET' - -def exists(env): - return env.Detect('ar') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/as.py b/scons/scons-local-4.1.0/SCons/Tool/as.py deleted file mode 100644 index d21cc8eea..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/as.py +++ /dev/null @@ -1,49 +0,0 @@ -"""SCons.Tool.as - -Tool-specific initialization for generic assembler. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -# -# forward proxy to the preferred asm version -# -import SCons.Tool.asm - -# Resolve FLAKE8 F401 (make sider happy) -generate = SCons.Tool.asm.generate -exists = SCons.Tool.asm.exists - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/asm.py b/scons/scons-local-4.1.0/SCons/Tool/asm.py deleted file mode 100644 index c7482513b..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/asm.py +++ /dev/null @@ -1,78 +0,0 @@ -"""SCons.Tool.as - -Tool-specific initialization for as, the generic Posix assembler. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util - -assemblers = ['as'] - -ASSuffixes = ['.s', '.asm', '.ASM'] -ASPPSuffixes = ['.spp', '.SPP', '.sx'] -if SCons.Util.case_sensitive_suffixes('.s', '.S'): - ASPPSuffixes.extend(['.S']) -else: - ASSuffixes.extend(['.S']) - -def generate(env): - """Add Builders and construction variables for as to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in ASSuffixes: - static_obj.add_action(suffix, SCons.Defaults.ASAction) - shared_obj.add_action(suffix, SCons.Defaults.ASAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) - - for suffix in ASPPSuffixes: - static_obj.add_action(suffix, SCons.Defaults.ASPPAction) - shared_obj.add_action(suffix, SCons.Defaults.ASPPAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) - - env['AS'] = env.Detect(assemblers) or 'as' - env['ASFLAGS'] = SCons.Util.CLVar('') - env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES' - env['ASPPFLAGS'] = '$ASFLAGS' - env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' - -def exists(env): - return env.Detect(assemblers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/bcc32.py b/scons/scons-local-4.1.0/SCons/Tool/bcc32.py deleted file mode 100644 index 55f871b75..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/bcc32.py +++ /dev/null @@ -1,81 +0,0 @@ -"""SCons.Tool.bcc32 - -XXX - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import os.path - -import SCons.Defaults -import SCons.Tool -import SCons.Util - -def findIt(program, env): - # First search in the SCons path and then the OS path: - borwin = env.WhereIs(program) or SCons.Util.WhereIs(program) - if borwin: - dir = os.path.dirname(borwin) - env.PrependENVPath('PATH', dir) - return borwin - -def generate(env): - findIt('bcc32', env) - """Add Builders and construction variables for bcc to an - Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - for suffix in ['.c', '.cpp']: - static_obj.add_action(suffix, SCons.Defaults.CAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) - - env['CC'] = 'bcc32' - env['CCFLAGS'] = SCons.Util.CLVar('') - env['CFLAGS'] = SCons.Util.CLVar('') - env['CCCOM'] = '$CC -q $CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES' - env['SHCC'] = '$CC' - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') - env['SHCCCOM'] = '$SHCC -WD $SHCFLAGS $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES' - env['CPPDEFPREFIX'] = '-D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '-I' - env['INCSUFFIX'] = '' - env['SHOBJSUFFIX'] = '.dll' - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0 - env['CFILESUFFIX'] = '.cpp' - -def exists(env): - return findIt('bcc32', env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/c++.py b/scons/scons-local-4.1.0/SCons/Tool/c++.py deleted file mode 100644 index 6b772fa70..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/c++.py +++ /dev/null @@ -1,44 +0,0 @@ -"""SCons.Tool.c++ - -Tool-specific initialization for generic Posix C++ compilers. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -#forward proxy to the preffered cxx version -from SCons.Tool.cxx import * - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/cc.py b/scons/scons-local-4.1.0/SCons/Tool/cc.py deleted file mode 100644 index 590ec5fd3..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/cc.py +++ /dev/null @@ -1,105 +0,0 @@ -"""SCons.Tool.cc - -Tool-specific initialization for generic Posix C compilers. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Tool -import SCons.Defaults -import SCons.Util - -CSuffixes = ['.c', '.m'] -if not SCons.Util.case_sensitive_suffixes('.c', '.C'): - CSuffixes.append('.C') - -def add_common_cc_variables(env): - """ - Add underlying common "C compiler" variables that - are used by multiple tools (specifically, c++). - """ - if '_CCCOMCOM' not in env: - env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS' - # It's a hack to test for darwin here, but the alternative - # of creating an applecc.py to contain this seems overkill. - # Maybe someday the Apple platform will require more setup and - # this logic will be moved. - env['FRAMEWORKS'] = SCons.Util.CLVar('') - env['FRAMEWORKPATH'] = SCons.Util.CLVar('') - if env['PLATFORM'] == 'darwin': - env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH' - - if 'CCFLAGS' not in env: - env['CCFLAGS'] = SCons.Util.CLVar('') - - if 'SHCCFLAGS' not in env: - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - -compilers = ['cc'] - -def generate(env): - """ - Add Builders and construction variables for C compilers to an Environment. - """ - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in CSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) - - add_common_cc_variables(env) - - if 'CC' not in env: - env['CC'] = env.Detect(compilers) or compilers[0] - env['CFLAGS'] = SCons.Util.CLVar('') - env['CCCOM'] = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' - env['SHCC'] = '$CC' - env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') - env['SHCCCOM'] = '$SHCC -o $TARGET -c $SHCFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES' - - env['CPPDEFPREFIX'] = '-D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '-I' - env['INCSUFFIX'] = '' - env['SHOBJSUFFIX'] = '.os' - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0 - - env['CFILESUFFIX'] = '.c' - -def exists(env): - return env.Detect(env.get('CC', compilers)) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/clang.py b/scons/scons-local-4.1.0/SCons/Tool/clang.py deleted file mode 100644 index e033cfa95..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/clang.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8; -*- -# -# MIT License -# -# Copyright 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.Tool.clang - -Tool-specific initialization for clang. - -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. - -""" - - -# Based on SCons/Tool/gcc.py by Paweł Tomulik 2014 as a separate tool. -# Brought into the SCons mainline by Russel Winder 2017. - -import os -import re -import subprocess -import sys - -import SCons.Util -import SCons.Tool.cc -from SCons.Tool.clangCommon import get_clang_install_dirs -from SCons.Tool.MSCommon import msvc_setup_env_once - - -compilers = ['clang'] - -def generate(env): - """Add Builders and construction variables for clang to an Environment.""" - SCons.Tool.cc.generate(env) - - if env['PLATFORM'] == 'win32': - # Ensure that we have a proper path for clang - clang = SCons.Tool.find_program_path(env, compilers[0], - default_paths=get_clang_install_dirs(env['PLATFORM'])) - if clang: - clang_bin_dir = os.path.dirname(clang) - env.AppendENVPath('PATH', clang_bin_dir) - - # Set-up ms tools paths - msvc_setup_env_once(env) - - - env['CC'] = env.Detect(compilers) or 'clang' - if env['PLATFORM'] in ['cygwin', 'win32']: - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - else: - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC') - - # determine compiler version - if env['CC']: - #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 - # clang -dumpversion is of no use - with pipe.stdout: - line = pipe.stdout.readline() - line = line.decode() - match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line) - if match: - env['CCVERSION'] = match.group(1) - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/clangCommon/__init__.py b/scons/scons-local-4.1.0/SCons/Tool/clangCommon/__init__.py deleted file mode 100644 index 55014579f..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/clangCommon/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -Common routines and data for clang tools -""" - -clang_win32_dirs = [ - r'C:\Program Files\LLVM\bin', - r'C:\cygwin64\bin', - r'C:\msys64', - r'C:\msys64\mingw64\bin', - r'C:\cygwin\bin', - r'C:\msys', -] - -def get_clang_install_dirs(platform): - if platform == 'win32': - return clang_win32_dirs - else: - return [] \ No newline at end of file diff --git a/scons/scons-local-4.1.0/SCons/Tool/clangxx.py b/scons/scons-local-4.1.0/SCons/Tool/clangxx.py deleted file mode 100644 index 736d45506..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/clangxx.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8; -*- - -"""SCons.Tool.clang++ - -Tool-specific initialization for clang++. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -# Based on SCons/Tool/g++.py by Paweł Tomulik 2014 as a separate tool. -# Brought into the SCons mainline by Russel Winder 2017. - -import os.path -import re -import subprocess -import sys - -import SCons.Tool -import SCons.Util -import SCons.Tool.cxx -from SCons.Tool.clangCommon import get_clang_install_dirs -from SCons.Tool.MSCommon import msvc_setup_env_once - - -compilers = ['clang++'] - -def generate(env): - """Add Builders and construction variables for clang++ to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - SCons.Tool.cxx.generate(env) - - env['CXX'] = env.Detect(compilers) or 'clang++' - - # platform specific settings - 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': - env['SHOBJSUFFIX'] = '.pic.o' - elif env['PLATFORM'] == 'sunos': - env['SHOBJSUFFIX'] = '.pic.o' - elif env['PLATFORM'] == 'win32': - # Ensure that we have a proper path for clang++ - clangxx = SCons.Tool.find_program_path(env, compilers[0], default_paths=get_clang_install_dirs(env['PLATFORM'])) - if clangxx: - clangxx_bin_dir = os.path.dirname(clangxx) - env.AppendENVPath('PATH', clangxx_bin_dir) - - # Set-up ms tools paths - msvc_setup_env_once(env) - - - # determine compiler version - if env['CXX']: - pipe = SCons.Action._subproc(env, [env['CXX'], '--version'], - stdin='devnull', - stderr='devnull', - stdout=subprocess.PIPE) - if pipe.wait() != 0: - return - - # clang -dumpversion is of no use - with pipe.stdout: - line = pipe.stdout.readline() - line = line.decode() - match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line) - if match: - env['CXXVERSION'] = match.group(1) - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/compilation_db.py b/scons/scons-local-4.1.0/SCons/Tool/compilation_db.py deleted file mode 100644 index d20d171f5..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/compilation_db.py +++ /dev/null @@ -1,255 +0,0 @@ -""" -Implements the ability for SCons to emit a compilation database for the MongoDB project. See -http://clang.llvm.org/docs/JSONCompilationDatabase.html for details on what a compilation -database is, and why you might want one. The only user visible entry point here is -'env.CompilationDatabase'. This method takes an optional 'target' to name the file that -should hold the compilation database, otherwise, the file defaults to compile_commands.json, -which is the name that most clang tools search for by default. -""" - -# Copyright 2020 MongoDB Inc. -# -# 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. -# - -import json -import itertools -import fnmatch -import SCons - -from .cxx import CXXSuffixes -from .cc import CSuffixes -from .asm import ASSuffixes, ASPPSuffixes - -# TODO: Is there a better way to do this than this global? Right now this exists so that the -# emitter we add can record all of the things it emits, so that the scanner for the top level -# compilation database can access the complete list, and also so that the writer has easy -# access to write all of the files. But it seems clunky. How can the emitter and the scanner -# communicate more gracefully? -__COMPILATION_DB_ENTRIES = [] - - -# We make no effort to avoid rebuilding the entries. Someday, perhaps we could and even -# integrate with the cache, but there doesn't seem to be much call for it. -class __CompilationDbNode(SCons.Node.Python.Value): - def __init__(self, value): - SCons.Node.Python.Value.__init__(self, value) - self.Decider(changed_since_last_build_node) - -def changed_since_last_build_node(child, target, prev_ni, node): - """ Dummy decider to force always building""" - return True - - -def make_emit_compilation_DB_entry(comstr): - """ - Effectively this creates a lambda function to capture: - * command line - * source - * target - :param comstr: unevaluated command line - :return: an emitter which has captured the above - """ - user_action = SCons.Action.Action(comstr) - - def emit_compilation_db_entry(target, source, env): - """ - This emitter will be added to each c/c++ object build to capture the info needed - for clang tools - :param target: target node(s) - :param source: source node(s) - :param env: Environment for use building this node - :return: target(s), source(s) - """ - - dbtarget = __CompilationDbNode(source) - - entry = env.__COMPILATIONDB_Entry( - target=dbtarget, - source=[], - __COMPILATIONDB_UOUTPUT=target, - __COMPILATIONDB_USOURCE=source, - __COMPILATIONDB_UACTION=user_action, - __COMPILATIONDB_ENV=env, - ) - - # TODO: Technically, these next two lines should not be required: it should be fine to - # cache the entries. However, they don't seem to update properly. Since they are quick - # to re-generate disable caching and sidestep this problem. - env.AlwaysBuild(entry) - env.NoCache(entry) - - __COMPILATION_DB_ENTRIES.append(dbtarget) - - return target, source - - return emit_compilation_db_entry - - -def compilation_db_entry_action(target, source, env, **kw): - """ - Create a dictionary with evaluated command line, target, source - and store that info as an attribute on the target - (Which has been stored in __COMPILATION_DB_ENTRIES array - :param target: target node(s) - :param source: source node(s) - :param env: Environment for use building this node - :param kw: - :return: None - """ - - command = env["__COMPILATIONDB_UACTION"].strfunction( - target=env["__COMPILATIONDB_UOUTPUT"], - source=env["__COMPILATIONDB_USOURCE"], - env=env["__COMPILATIONDB_ENV"], - ) - - entry = { - "directory": env.Dir("#").abspath, - "command": command, - "file": env["__COMPILATIONDB_USOURCE"][0], - "output": env['__COMPILATIONDB_UOUTPUT'][0] - } - - target[0].write(entry) - - -def write_compilation_db(target, source, env): - entries = [] - - use_abspath = env['COMPILATIONDB_USE_ABSPATH'] in [True, 1, 'True', 'true'] - use_path_filter = env.subst('$COMPILATIONDB_PATH_FILTER') - - for s in __COMPILATION_DB_ENTRIES: - entry = s.read() - source_file = entry['file'] - output_file = entry['output'] - - if use_abspath: - source_file = source_file.srcnode().abspath - output_file = output_file.abspath - else: - source_file = source_file.srcnode().path - output_file = output_file.path - - if use_path_filter and not fnmatch.fnmatch(output_file, use_path_filter): - continue - - path_entry = {'directory': entry['directory'], - 'command': entry['command'], - 'file': source_file, - 'output': output_file} - - entries.append(path_entry) - - with open(target[0].path, "w") as output_file: - json.dump( - entries, output_file, sort_keys=True, indent=4, separators=(",", ": ") - ) - - -def scan_compilation_db(node, env, path): - return __COMPILATION_DB_ENTRIES - - -def compilation_db_emitter(target, source, env): - """ fix up the source/targets """ - - # Someone called env.CompilationDatabase('my_targetname.json') - if not target and len(source) == 1: - target = source - - # Default target name is compilation_db.json - if not target: - target = ['compile_commands.json', ] - - # No source should have been passed. Drop it. - if source: - source = [] - - return target, source - - -def generate(env, **kwargs): - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - env["COMPILATIONDB_COMSTR"] = kwargs.get( - "COMPILATIONDB_COMSTR", "Building compilation database $TARGET" - ) - - components_by_suffix = itertools.chain( - itertools.product( - CSuffixes, - [ - (static_obj, SCons.Defaults.StaticObjectEmitter, "$CCCOM"), - (shared_obj, SCons.Defaults.SharedObjectEmitter, "$SHCCCOM"), - ], - ), - itertools.product( - CXXSuffixes, - [ - (static_obj, SCons.Defaults.StaticObjectEmitter, "$CXXCOM"), - (shared_obj, SCons.Defaults.SharedObjectEmitter, "$SHCXXCOM"), - ], - ), - itertools.product( - ASSuffixes, - [(static_obj, SCons.Defaults.StaticObjectEmitter, "$ASCOM")], - [(shared_obj, SCons.Defaults.SharedObjectEmitter, "$ASCOM")], - ), - itertools.product( - ASPPSuffixes, - [(static_obj, SCons.Defaults.StaticObjectEmitter, "$ASPPCOM")], - [(shared_obj, SCons.Defaults.SharedObjectEmitter, "$ASPPCOM")], - ), - ) - - for entry in components_by_suffix: - suffix = entry[0] - builder, base_emitter, command = entry[1] - - # Assumes a dictionary emitter - emitter = builder.emitter.get(suffix, False) - if emitter: - # We may not have tools installed which initialize all or any of - # cxx, cc, or assembly. If not skip resetting the respective emitter. - builder.emitter[suffix] = SCons.Builder.ListEmitter( - [emitter, make_emit_compilation_DB_entry(command), ] - ) - - env["BUILDERS"]["__COMPILATIONDB_Entry"] = SCons.Builder.Builder( - action=SCons.Action.Action(compilation_db_entry_action, None), - ) - - env["BUILDERS"]["CompilationDatabase"] = SCons.Builder.Builder( - action=SCons.Action.Action(write_compilation_db, "$COMPILATIONDB_COMSTR"), - target_scanner=SCons.Scanner.Scanner( - function=scan_compilation_db, node_class=None - ), - emitter=compilation_db_emitter, - suffix='json', - ) - - env['COMPILATIONDB_USE_ABSPATH'] = False - env['COMPILATIONDB_PATH_FILTER'] = '' - - -def exists(env): - return True diff --git a/scons/scons-local-4.1.0/SCons/Tool/cvf.py b/scons/scons-local-4.1.0/SCons/Tool/cvf.py deleted file mode 100644 index 47e733ebd..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/cvf.py +++ /dev/null @@ -1,58 +0,0 @@ -"""SCons.Tool.cvf - -Tool-specific initialization for the Compaq Visual Fortran compiler. - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from . import fortran - -compilers = ['f90'] - -def generate(env): - """Add Builders and construction variables for compaq visual fortran to an Environment.""" - - fortran.generate(env) - - env['FORTRAN'] = 'f90' - env['FORTRANCOM'] = '$FORTRAN $FORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' - env['FORTRANPPCOM'] = '$FORTRAN $FORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' - env['SHFORTRANCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' - env['SHFORTRANPPCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' - env['OBJSUFFIX'] = '.obj' - env['FORTRANMODDIR'] = '${TARGET.dir}' - env['FORTRANMODDIRPREFIX'] = '/module:' - env['FORTRANMODDIRSUFFIX'] = '' - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/cxx.py b/scons/scons-local-4.1.0/SCons/Tool/cxx.py deleted file mode 100644 index 128cdc4f6..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/cxx.py +++ /dev/null @@ -1,95 +0,0 @@ -"""SCons.Tool.c++ - -Tool-specific initialization for generic Posix C++ compilers. - -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. -""" - -# -# 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. -# - -import os.path - -import SCons.Defaults -import SCons.Util - -compilers = ['CC', 'c++'] - -CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++', '.mm'] -if SCons.Util.case_sensitive_suffixes('.c', '.C'): - CXXSuffixes.append('.C') - -def iscplusplus(source): - 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 CXXSuffixes: - return 1 - return 0 - -def generate(env): - """ - Add Builders and construction variables for Visual Age C++ compilers - to an Environment. - """ - import SCons.Tool - import SCons.Tool.cc - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in CXXSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CXXAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) - - SCons.Tool.cc.add_common_cc_variables(env) - - if 'CXX' not in env: - env['CXX'] = env.Detect(compilers) or compilers[0] - 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 $SHCCFLAGS $_CCCOMCOM $SOURCES' - - env['CPPDEFPREFIX'] = '-D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '-I' - env['INCSUFFIX'] = '' - env['SHOBJSUFFIX'] = '.os' - env['OBJSUFFIX'] = '.o' - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0 - - env['CXXFILESUFFIX'] = '.cc' - -def exists(env): - return env.Detect(env.get('CXX', compilers)) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/cyglink.py b/scons/scons-local-4.1.0/SCons/Tool/cyglink.py deleted file mode 100644 index bb5cd1035..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/cyglink.py +++ /dev/null @@ -1,212 +0,0 @@ -"""SCons.Tool.cyglink - -Customization of gnulink for Cygwin (http://www.cygwin.com/) - -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. - -""" - -from SCons.Tool.linkCommon import StringizeLibSymlinks, EmitLibSymlinks -from SCons.Util import CLVar, is_String -from . import gnulink - - -def cyglink_lib_emitter(target, source, env, **kw): - verbose = True - - if 'variable_prefix' in kw: - var_prefix = kw['variable_prefix'] - else: - var_prefix = 'SHLIB' - - no_import_lib = env.get('no_import_lib', False) - - if verbose: - print("cyglink_lib_emitter: target[0]={!r}".format(target[0].get_path())) - - if not no_import_lib: - # Specify import lib and add to targets - - import_lib = env.subst('$%s_IMPLIBNAME' % var_prefix, target=target, source=source) - import_lib_target = env.fs.File(import_lib) - import_lib_target.attributes.shared = 1 - target.append(import_lib_target) - - if verbose: - print("cyglink_lib_emitter: import_lib={}".format(import_lib)) - print("cyglink_lib_emitter: target=%s" % target) - - for tgt in target: - if is_String(tgt): - tgt = env.File(tgt) - tgt.attributes.shared = 1 - - return target, source - - -def cyglink_ldmodule_emitter(target, source, env, **kw): - return cyglink_lib_emitter(target, source, env, variable_prefix='LDMODULE') - - -def cyglink_shlib_symlink_emitter(target, source, env, **kw): - """ - On cygwin, we only create a symlink from the non-versioned implib to the versioned implib. - We don't version the shared library itself. - :param target: - :param source: - :param env: - :param kw: - :return: - """ - verbose = True - - if 'variable_prefix' in kw: - var_prefix = kw['variable_prefix'] - else: - var_prefix = 'SHLIB' - - no_import_lib = env.get('no_import_lib', False) - if no_import_lib in ['1', 'True', 'true', True]: - if verbose: - print("cyglink_shlib_symlink_emitter: no_import_lib=%s" % no_import_lib) - return target, source - - no_symlinks = env.subst('$%sNOVERSIONSYMLINKS' % var_prefix) - if no_symlinks in ['1', 'True', 'true', True]: - return target, source - - shlibversion = env.subst('$%sVERSION' % var_prefix) - if shlibversion: - if verbose: - print("cyglink_shlib_symlink_emitter: %sVERSION=%s" % (var_prefix, shlibversion)) - - # The implib (added by the cyglink_lib_emitter) - imp_lib_node = target[1] - shlib_noversion_symlink = env.subst('$%s_NOVERSION_SYMLINK' % var_prefix, target=target[0], source=source) - - if verbose: - print("cyglink_shlib_symlink_emitter: shlib_noversion_symlink :%s" % shlib_noversion_symlink) - print("cyglink_shlib_symlink_emitter: imp_lib_node :%s" % imp_lib_node) - - symlinks = [(env.File(shlib_noversion_symlink), imp_lib_node)] - - if verbose: - print("cyglink_shlib_symlink_emitter: symlinks={!r}".format( - ', '.join(["%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks)]) - )) - - if symlinks: - # This does the actual symlinking - EmitLibSymlinks(env, symlinks, target[0]) - - # This saves the information so if the versioned shared library is installed - # it can faithfully reproduce the correct symlinks - target[0].attributes.shliblinks = symlinks - - return target, source - - -def cyglink_ldmod_symlink_emitter(target, source, env, **kw): - return cyglink_shlib_symlink_emitter(target, source, env, variable_prefix='LDMODULE') - - -def cyglink_shlibversion(target, source, env, for_signature): - var_prefix = 'SHLIB' - var = '%sVERSION' % var_prefix - if var not in env: - return '' - - version = env.subst("$%s" % var, target=target, source=source) - version = version.replace('.', '-') - return "." + version - - -def cyglink_ldmodule_version(target, source, env, for_signature): - var_prefix = 'LDMODULE' - var = '%sVERSION' % var_prefix - if var not in env: - return '' - - version = env.subst("$%s" % var, target=target, source=source) - version = version.replace('.', '-') - return "." + version - - -def _implib_pre_flags(target, source, env, for_signature): - no_import_lib = env.get('no_import_lib', False) - if no_import_lib in ['1', 'True', 'true', True]: - return '' - else: - return '-Wl,--out-implib=${TARGETS[1]} -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' - - -def _implib_post_flags(target, source, env, for_signature): - no_import_lib = env.get('no_import_lib', False) - if no_import_lib in ['1', 'True', 'true', True]: - return '' - else: - return '-Wl,--no-whole-archive' - - -def generate(env): - """Add Builders and construction variables for cyglink to an Environment.""" - gnulink.generate(env) - - env['LINKFLAGS'] = CLVar('-Wl,-no-undefined') - - env['SHLIBPREFIX'] = 'cyg' - env['SHLIBSUFFIX'] = '.dll' - - env['IMPLIBPREFIX'] = 'lib' - env['IMPLIBSUFFIX'] = '.dll.a' - - # Variables used by versioned shared libraries - # SHLIBVERSIONFLAGS and LDMODULEVERSIONFLAGS are same as in gnulink... - env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' - env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS' - - env['_IMPLIB_PRE_SOURCES'] = _implib_pre_flags - env['_IMPLIB_POST_SOURCES'] = _implib_post_flags - env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $__SHLIBVERSIONFLAGS $__RPATH ' \ - '$_IMPLIB_PRE_SOURCES $SOURCES $_IMPLIB_POST_SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - env['LDMODULECOM'] = '$LDMODULE -o $TARGET $SHLINKFLAGS $__LDMODULEVERSIONFLAGS $__RPATH ' \ - '$_IMPLIB_PRE_SOURCES $SOURCES $_IMPLIB_POST_SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - - # Overwrite emitters. Cyglink does things differently when creating symlinks - env['SHLIBEMITTER'] = [cyglink_lib_emitter, cyglink_shlib_symlink_emitter] - env['LDMODULEEMITTER'] = [cyglink_ldmodule_emitter, cyglink_ldmod_symlink_emitter] - - # This is the non versioned shlib filename - # If SHLIBVERSION is defined then this will symlink to $SHLIBNAME - env['SHLIB_NOVERSION_SYMLINK'] = '${IMPLIBPREFIX}$_get_shlib_stem${IMPLIBSUFFIX}' - env['LDMODULE_NOVERSION_SYMLINK'] = '${IMPLIBPREFIX}$_get_ldmodule_stem${IMPLIBSUFFIX}' - - env['SHLIB_IMPLIBNAME'] = '${IMPLIBPREFIX}$_get_shlib_stem${_SHLIB_IMPLIBSUFFIX}' - env['LDMODULE_IMPLIBNAME'] = '${IMPLIBPREFIX}$_get_ldmodule_stem${_LDMODULE_IMPLIBSUFFIX}' - - env['_cyglink_shlibversion'] = cyglink_shlibversion - env['_SHLIB_IMPLIBSUFFIX'] = '${_cyglink_shlibversion}${IMPLIBSUFFIX}' - env['_SHLIBSUFFIX'] = '${_cyglink_shlibversion}${SHLIBSUFFIX}' - - env['_cyglink_ldmodule_version'] = cyglink_ldmodule_version - - env['_LDMODULESUFFIX'] = '${_cyglink_ldmodule_version}${LDMODULESUFFIX}' - env['_LDMODULE_IMPLIBSUFFIX'] = '${_cyglink_ldmodule_version}${IMPLIBSUFFIX}' - - # Remove variables set by default initialization which aren't needed/used by cyglink - # these variables were set by gnulink but are not used in cyglink - for rv in ['_SHLIBSONAME', '_LDMODULESONAME']: - if rv in env: - del env[rv] - - -def exists(env): - return gnulink.exists(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/default.py b/scons/scons-local-4.1.0/SCons/Tool/default.py deleted file mode 100644 index a36e9ec1c..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/default.py +++ /dev/null @@ -1,50 +0,0 @@ -"""SCons.Tool.default - -Initialization with a default tool list. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Tool - -def generate(env): - """Add default tools.""" - for t in SCons.Tool.tool_list(env['PLATFORM'], env): - SCons.Tool.Tool(t)(env) - -def exists(env): - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/dmd.py b/scons/scons-local-4.1.0/SCons/Tool/dmd.py deleted file mode 100644 index 67ed43eda..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/dmd.py +++ /dev/null @@ -1,169 +0,0 @@ -# MIT License -# -# Copyright 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.Tool.dmd - -Tool-specific initialization for the Digital Mars D compiler. -(http://digitalmars.com/d) - -Originally coded by Andy Friesen (andy@ikagames.com) -15 November 2003 - -Evolved by Russel Winder (russel@winder.org.uk) -2010-02-07 onwards - -Compiler variables: - -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 or gdmd, whichever is found. - -DLINKFLAGS - List of linker flags. - -Lib tool variables: - -DLIB - Name of the lib tool to use. Defaults to lib. - -DLIBFLAGS - List of flags to pass to the lib tool. - -LIBS - Same as for the linker. (libraries to pull into the .lib) - -""" - - -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Scanner.D -import SCons.Tool - -import SCons.Tool.DCommon as DCommon - - -def generate(env): - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - static_obj.add_action('.d', SCons.Defaults.DAction) - shared_obj.add_action('.d', SCons.Defaults.ShDAction) - static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) - - env['DC'] = env.Detect(['dmd', 'ldmd2', 'gdmd']) or 'dmd' - 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__)}' - env['_DDEBUGFLAGS'] = '${_concat(DDEBUGPREFIX, DDEBUG, DDEBUGSUFFIX, __env__)}' - env['_DFLAGS'] = '${_concat(DFLAGPREFIX, DFLAGS, DFLAGSUFFIX, __env__)}' - - env['SHDC'] = '$DC' - env['SHDCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -fPIC -of$TARGET $SOURCES' - - env['DPATH'] = ['#/'] - env['DFLAGS'] = [] - env['DVERSIONS'] = [] - env['DDEBUG'] = [] - - if env['DC']: - DCommon.addDPATHToEnv(env, env['DC']) - - env['DINCPREFIX'] = '-I' - env['DINCSUFFIX'] = '' - env['DVERPREFIX'] = '-version=' - env['DVERSUFFIX'] = '' - env['DDEBUGPREFIX'] = '-debug=' - env['DDEBUGSUFFIX'] = '' - env['DFLAGPREFIX'] = '-' - env['DFLAGSUFFIX'] = '' - env['DFILESUFFIX'] = '.d' - - env['DLINK'] = '$DC' - env['DLINKFLAGS'] = SCons.Util.CLVar('') - env['DLINKCOM'] = '$DLINK -of$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' - - env['SHDLINK'] = '$DC' - env['SHDLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=libphobos2.so') - env[ - 'SHDLINKCOM'] = '$DLINK -of$TARGET $SHDLINKFLAGS $__SHDLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' - - env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' - env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else '' - env['_DLIBFLAGS'] = '${_stripixes(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}' - - env['DLIBDIRPREFIX'] = '-L-L' - env['DLIBDIRSUFFIX'] = '' - env['_DLIBDIRFLAGS'] = '${_concat(DLIBDIRPREFIX, LIBPATH, DLIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)}' - - env['DLIB'] = 'lib' if env['PLATFORM'] == 'win32' else 'ar cr' - env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLIBFLAGS'.format( - '-c ' if env['PLATFORM'] == 'win32' else '') - - # env['_DLIBFLAGS'] = '${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)}' - - env['DLIBFLAGPREFIX'] = '-' - env['DLIBFLAGSUFFIX'] = '' - - # __RPATH is set to $_RPATH in the platform specification if that - # platform supports it. - env['DRPATHPREFIX'] = '-L-rpath,' if env['PLATFORM'] == 'darwin' else '-L-rpath=' - env['DRPATHSUFFIX'] = '' - env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' - - # Support for versioned libraries - env['_SHDLIBVERSIONFLAGS'] = '$SHDLIBVERSIONFLAGS -L-soname=$_SHLIBSONAME' - - env['BUILDERS']['ProgramAllAtOnce'] = SCons.Builder.Builder( - action='$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -of$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS', - emitter=DCommon.allAtOnceEmitter, - ) - - -def exists(env): - return env.Detect(['dmd', 'ldmd2', 'gdmd']) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/dvi.py b/scons/scons-local-4.1.0/SCons/Tool/dvi.py deleted file mode 100644 index 4067b2a1e..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/dvi.py +++ /dev/null @@ -1,64 +0,0 @@ -"""SCons.Tool.dvi - -Common DVI Builder definition for various other Tool modules that use it. - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Builder -import SCons.Tool - -DVIBuilder = None - -def generate(env): - try: - env['BUILDERS']['DVI'] - except KeyError: - global DVIBuilder - - if DVIBuilder is None: - # The suffix is hard-coded to '.dvi', not configurable via a - # construction variable like $DVISUFFIX, because the output - # file name is hard-coded within TeX. - DVIBuilder = SCons.Builder.Builder(action = {}, - source_scanner = SCons.Tool.LaTeXScanner, - suffix = '.dvi', - emitter = {}, - source_ext_match = None) - - env['BUILDERS']['DVI'] = DVIBuilder - -def exists(env): - # This only puts a skeleton Builder in place, so if someone - # references this Tool directly, it's always "available." - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/dvipdf.py b/scons/scons-local-4.1.0/SCons/Tool/dvipdf.py deleted file mode 100644 index f1e951313..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/dvipdf.py +++ /dev/null @@ -1,125 +0,0 @@ -"""SCons.Tool.dvipdf - -Tool-specific initialization for dvipdf. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -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. - These are created by the TeX Builder that in all likelihood was - used to generate the .dvi file we're using as input, and we only - care about the .dvi file. - """ - def strip_suffixes(n): - return not SCons.Util.splitext(str(n))[1] in ['.aux', '.log'] - source = [src for src in source if strip_suffixes(src)] - return (target, source) - -def generate(env): - """Add Builders and construction variables for dvipdf to an Environment.""" - global PDFAction - if PDFAction is None: - PDFAction = SCons.Action.Action('$DVIPDFCOM', '$DVIPDFCOMSTR') - - global DVIPDFAction - if DVIPDFAction is None: - DVIPDFAction = SCons.Action.Action(DviPdfFunction, strfunction = DviPdfStrFunction) - - from . import pdf - pdf.generate(env) - - bld = env['BUILDERS']['PDF'] - bld.add_action('.dvi', DVIPDFAction) - bld.add_emitter('.dvi', PDFEmitter) - - env['DVIPDF'] = 'dvipdf' - env['DVIPDFFLAGS'] = SCons.Util.CLVar('') - env['DVIPDFCOM'] = 'cd ${TARGET.dir} && $DVIPDF $DVIPDFFLAGS ${SOURCE.file} ${TARGET.file}' - - # Deprecated synonym. - env['PDFCOM'] = ['$DVIPDFCOM'] - -def exists(env): - SCons.Tool.tex.generate_darwin(env) - return env.Detect('dvipdf') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/dvips.py b/scons/scons-local-4.1.0/SCons/Tool/dvips.py deleted file mode 100644 index 198bda038..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/dvips.py +++ /dev/null @@ -1,95 +0,0 @@ -"""SCons.Tool.dvips - -Tool-specific initialization for dvips. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -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): - """Add Builders and construction variables for dvips to an Environment.""" - global PSAction - 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', - 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 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'] = '' - env['PSSUFFIX'] = '.ps' - -def exists(env): - SCons.Tool.tex.generate_darwin(env) - return env.Detect('dvips') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/f03.py b/scons/scons-local-4.1.0/SCons/Tool/f03.py deleted file mode 100644 index 41d9c43d4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/f03.py +++ /dev/null @@ -1,67 +0,0 @@ -"""SCons.Tool.f03 - -Tool-specific initialization for the generic Posix f03 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran -from SCons.Tool.FortranCommon import add_all_to_env, add_f03_to_env - -compilers = ['f03'] - -def generate(env): - add_all_to_env(env) - add_f03_to_env(env) - - fcomp = env.Detect(compilers) or 'f03' - if 'F03' not in env: - env['F03'] = fcomp - if 'SHF03' not in env: - env['SHF03'] = '$F03' - - if 'FORTRAN' not in env: - env['FORTRAN'] = fcomp - if 'SHFORTRAN' not in env: - env['SHFORTRAN'] = '$FORTRAN' - - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/f08.py b/scons/scons-local-4.1.0/SCons/Tool/f08.py deleted file mode 100644 index 3d1bce22d..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/f08.py +++ /dev/null @@ -1,67 +0,0 @@ -"""SCons.Tool.f08 - -Tool-specific initialization for the generic Posix f08 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran -from SCons.Tool.FortranCommon import add_all_to_env, add_f08_to_env - -compilers = ['f08'] - -def generate(env): - add_all_to_env(env) - add_f08_to_env(env) - - fcomp = env.Detect(compilers) or 'f08' - if 'F08' not in env: - env['F08'] = fcomp - if 'SHF08' not in env: - env['SHF08'] = '$F08' - - if 'FORTRAN' not in env: - env['FORTRAN'] = fcomp - if 'SHFORTRAN' not in env: - env['SHFORTRAN'] = '$FORTRAN' - - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/f77.py b/scons/scons-local-4.1.0/SCons/Tool/f77.py deleted file mode 100644 index b936acd60..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/f77.py +++ /dev/null @@ -1,66 +0,0 @@ -"""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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -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' - if 'F77' not in env: - env['F77'] = fcomp - if 'SHF77' not in env: - env['SHF77'] = '$F77' - - if 'FORTRAN' not in env: - env['FORTRAN'] = fcomp - if 'SHFORTRAN' not in env: - env['SHFORTRAN'] = '$FORTRAN' - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/f90.py b/scons/scons-local-4.1.0/SCons/Tool/f90.py deleted file mode 100644 index ef7d93dfa..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/f90.py +++ /dev/null @@ -1,66 +0,0 @@ -"""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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -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 = ['f90'] - -def generate(env): - add_all_to_env(env) - add_f90_to_env(env) - - fc = env.Detect(compilers) or 'f90' - if 'F90' not in env: - env['F90'] = fc - if 'SHF90' not in env: - env['SHF90'] = '$F90' - - if 'FORTRAN' not in env: - env['FORTRAN'] = fc - if 'SHFORTRAN' not in env: - env['SHFORTRAN'] = '$FORTRAN' - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/f95.py b/scons/scons-local-4.1.0/SCons/Tool/f95.py deleted file mode 100644 index 7b56d4e95..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/f95.py +++ /dev/null @@ -1,67 +0,0 @@ -"""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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . 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' - if 'F95' not in env: - env['F95'] = fcomp - if 'SHF95' not in env: - env['SHF95'] = '$F95' - - if 'FORTRAN' not in env: - env['FORTRAN'] = fcomp - if 'SHFORTRAN' not in env: - env['SHFORTRAN'] = '$FORTRAN' - - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/filesystem.py b/scons/scons-local-4.1.0/SCons/Tool/filesystem.py deleted file mode 100644 index 3b8ee4c8f..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/filesystem.py +++ /dev/null @@ -1,98 +0,0 @@ -"""SCons.Tool.filesystem - -Tool-specific initialization for the filesystem tools. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons -from SCons.Tool.install import copyFunc - -copyToBuilder, copyAsBuilder = None, None - -def copyto_emitter(target, source, env): - """ changes the path of the source to be under the target (which - are assumed to be directories. - """ - n_target = [] - - for t in target: - n_target = n_target + [t.File( str( s ) ) for s in source] - - return (n_target, source) - -def copy_action_func(target, source, env): - assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(list(map(str, target)),list(map(str, source))) - - for t, s in zip(target, source): - if copyFunc(t.get_path(), s.get_path(), env): - return 1 - - return 0 - -def copy_action_str(target, source, env): - return env.subst_target_source(env['COPYSTR'], 0, target, source) - -copy_action = SCons.Action.Action( copy_action_func, copy_action_str ) - -def generate(env): - try: - env['BUILDERS']['CopyTo'] - env['BUILDERS']['CopyAs'] - except KeyError as e: - global copyToBuilder - if copyToBuilder is None: - copyToBuilder = SCons.Builder.Builder( - action = copy_action, - target_factory = env.fs.Dir, - source_factory = env.fs.Entry, - multi = 1, - emitter = [ copyto_emitter, ] ) - - global copyAsBuilder - if copyAsBuilder is None: - copyAsBuilder = SCons.Builder.Builder( - action = copy_action, - target_factory = env.fs.Entry, - source_factory = env.fs.Entry ) - - env['BUILDERS']['CopyTo'] = copyToBuilder - env['BUILDERS']['CopyAs'] = copyAsBuilder - - env['COPYSTR'] = 'Copy file(s): "$SOURCES" to "$TARGETS"' - -def exists(env): - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/fortran.py b/scons/scons-local-4.1.0/SCons/Tool/fortran.py deleted file mode 100644 index 0a68df642..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/fortran.py +++ /dev/null @@ -1,62 +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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -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) - - if 'FORTRAN' not in env: - env['FORTRAN'] = env.Detect(compilers) or 'f77' - if 'SHFORTRAN' not in env: - env['SHFORTRAN'] = '$FORTRAN' - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/g++.py b/scons/scons-local-4.1.0/SCons/Tool/g++.py deleted file mode 100644 index 88d88ca84..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/g++.py +++ /dev/null @@ -1,45 +0,0 @@ -"""SCons.Tool.g++ - -Tool-specific initialization for g++. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -#forward proxy to the preffered cxx version -from SCons.Tool.gxx import * - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/g77.py b/scons/scons-local-4.1.0/SCons/Tool/g77.py deleted file mode 100644 index 764235e0b..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/g77.py +++ /dev/null @@ -1,73 +0,0 @@ -"""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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -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) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/gas.py b/scons/scons-local-4.1.0/SCons/Tool/gas.py deleted file mode 100644 index d01bd60cc..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gas.py +++ /dev/null @@ -1,56 +0,0 @@ -"""SCons.Tool.gas - -Tool-specific initialization for as, the Gnu assembler. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -try: - as_module = __import__('as', globals(), locals(), []) -except: - as_module = __import__(__package__+'.as', globals(), locals(), ['*']) - -assemblers = ['as', 'gas'] - -def generate(env): - """Add Builders and construction variables for as to an Environment.""" - as_module.generate(env) - - env['AS'] = env.Detect(assemblers) or 'as' - -def exists(env): - return env.Detect(assemblers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/gcc.py b/scons/scons-local-4.1.0/SCons/Tool/gcc.py deleted file mode 100644 index 6470002f1..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gcc.py +++ /dev/null @@ -1,109 +0,0 @@ -# MIT License -# -# Copyright 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.Tool.gcc - -Tool-specific initialization for gcc. - -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. - -""" - -from . import cc -import re -import subprocess - -import SCons.Util - -compilers = ['gcc', 'cc'] - - -def generate(env): - """Add Builders and construction variables for gcc to an Environment.""" - - if 'CC' not in env: - env['CC'] = env.Detect(compilers) or compilers[0] - - cc.generate(env) - - if env['PLATFORM'] in ['cygwin', 'win32']: - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - else: - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC') - # determine compiler version - version = detect_version(env, env['CC']) - if version: - env['CCVERSION'] = version - - -def exists(env): - # is executable, and is a GNU compiler (or accepts '--version' at least) - return detect_version(env, env.Detect(env.get('CC', compilers))) - - -def detect_version(env, cc): - """Return the version of the GNU compiler, or None if it is not a GNU compiler.""" - version = None - cc = env.subst(cc) - if not cc: - return version - - # -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. - # pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['-dumpversion'], - pipe=SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['--version'], - stdin='devnull', - stderr='devnull', - stdout=subprocess.PIPE) - if pipe.wait() != 0: - return version - - with pipe.stdout: - # -dumpversion variant: - # line = pipe.stdout.read().strip() - # --version variant: - line = SCons.Util.to_str(pipe.stdout.readline()) - # Non-GNU compiler's output (like AIX xlc's) may exceed the stdout buffer: - # So continue with reading to let the child process actually terminate. - while SCons.Util.to_str(pipe.stdout.readline()): - pass - - - # -dumpversion variant: - # if line: - # version = line - # --version variant: - match = re.search(r'[0-9]+(\.[0-9]+)+', line) - if match: - version = match.group(0) - - return version - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/gdc.py b/scons/scons-local-4.1.0/SCons/Tool/gdc.py deleted file mode 100644 index 0728c6fec..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gdc.py +++ /dev/null @@ -1,134 +0,0 @@ -# MIT License -# -# Copyright 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.Tool.gdc - -Tool-specific initialization for the GDC compiler. -(https://github.com/D-Programming-GDC/GDC) - -Developed by Russel Winder (russel@winder.org.uk) -2012-05-09 onwards - -Compiler variables: - DC - The name of the D compiler to use. Defaults to gdc. - 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 gdc. - DLINKFLAGS - List of linker flags. - -Lib tool variables: - DLIB - Name of the lib tool to use. Defaults to lib. - DLIBFLAGS - List of flags to pass to the lib tool. - LIBS - Same as for the linker. (libraries to pull into the .lib) -""" - -import SCons.Action -import SCons.Defaults -import SCons.Tool - -import SCons.Tool.DCommon as DCommon -import SCons.Tool.linkCommon - - -def generate(env): - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - static_obj.add_action('.d', SCons.Defaults.DAction) - shared_obj.add_action('.d', SCons.Defaults.ShDAction) - static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) - - env['DC'] = env.Detect('gdc') or 'gdc' - env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -o $TARGET $SOURCES' - env['_DINCFLAGS'] = '${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}' - env['_DVERFLAGS'] = '${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)}' - env['_DDEBUGFLAGS'] = '${_concat(DDEBUGPREFIX, DDEBUG, DDEBUGSUFFIX, __env__)}' - env['_DFLAGS'] = '${_concat(DFLAGPREFIX, DFLAGS, DFLAGSUFFIX, __env__)}' - - env['SHDC'] = '$DC' - env['SHDCOM'] = '$SHDC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -fPIC -c -o $TARGET $SOURCES' - - env['DPATH'] = ['#/'] - env['DFLAGS'] = [] - env['DVERSIONS'] = [] - env['DDEBUG'] = [] - - if env['DC']: - DCommon.addDPATHToEnv(env, env['DC']) - - env['DINCPREFIX'] = '-I' - env['DINCSUFFIX'] = '' - env['DVERPREFIX'] = '-version=' - env['DVERSUFFIX'] = '' - env['DDEBUGPREFIX'] = '-debug=' - env['DDEBUGSUFFIX'] = '' - env['DFLAGPREFIX'] = '-' - env['DFLAGSUFFIX'] = '' - env['DFILESUFFIX'] = '.d' - - env['DLINK'] = '$DC' - env['DLINKFLAGS'] = SCons.Util.CLVar('') - env['DLINKCOM'] = '$DLINK -o $TARGET $DLINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - - env['SHDLINK'] = '$DC' - env['SHDLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -shared-libphobos') - env['SHDLINKCOM'] = '$DLINK -o $TARGET $SHDLINKFLAGS $__SHDLIBVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - - env['DLIB'] = 'lib' if env['PLATFORM'] == 'win32' else 'ar cr' - env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLINKLIBFLAGS'.format('-c ' if env['PLATFORM'] == 'win32' else '') - - env['_DLIBFLAGS'] = '${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)}' - - env['DLIBFLAGPREFIX'] = '-' - env['DLIBFLAGSUFFIX'] = '' - env['DLINKFLAGPREFIX'] = '-' - env['DLINKFLAGSUFFIX'] = '' - - # __RPATH is set to $_RPATH in the platform specification if that - # platform supports it. - env['RPATHPREFIX'] = '-Wl,-rpath=' - env['RPATHSUFFIX'] = '' - env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' - - # Support for versioned libraries - env['_SHDLIBVERSIONFLAGS'] = '$SHDLIBVERSIONFLAGS -Wl,-soname=$_SHLIBSONAME' - - env['BUILDERS']['ProgramAllAtOnce'] = SCons.Builder.Builder( - action='$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -o $TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS', - emitter=DCommon.allAtOnceEmitter, - ) - - -def exists(env): - return env.Detect('gdc') - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/gettext_tool.py b/scons/scons-local-4.1.0/SCons/Tool/gettext_tool.py deleted file mode 100644 index 43ca494c2..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gettext_tool.py +++ /dev/null @@ -1,60 +0,0 @@ -"""gettext tool -""" - - -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -############################################################################# -def generate(env,**kw): - import sys - import os - import SCons.Tool - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - from SCons.Tool.GettextCommon \ - import _translate, tool_list - for t in tool_list(env['PLATFORM'], env): - if sys.platform == 'win32': - tool = SCons.Tool.find_program_path(env, t, default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if tool: - tool_bin_dir = os.path.dirname(tool) - env.AppendENVPath('PATH', tool_bin_dir) - else: - SCons.Warnings.SConsWarning(t + ' tool requested, but binary not found in ENV PATH') - env.Tool(t) - env.AddMethod(_translate, 'Translate') -############################################################################# - -############################################################################# -def exists(env): - from SCons.Tool.GettextCommon \ - import _xgettext_exists, _msginit_exists, \ - _msgmerge_exists, _msgfmt_exists - try: - return _xgettext_exists(env) and _msginit_exists(env) \ - and _msgmerge_exists(env) and _msgfmt_exists(env) - except: - return False -############################################################################# diff --git a/scons/scons-local-4.1.0/SCons/Tool/gfortran.py b/scons/scons-local-4.1.0/SCons/Tool/gfortran.py deleted file mode 100644 index 45750d6f4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gfortran.py +++ /dev/null @@ -1,66 +0,0 @@ -"""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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Util - -from . 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', 'F03', 'F08']: - 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] = "" - - env['FORTRANMODDIRPREFIX'] = "-J" - -def exists(env): - return env.Detect('gfortran') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/gnulink.py b/scons/scons-local-4.1.0/SCons/Tool/gnulink.py deleted file mode 100644 index e8b668fa3..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gnulink.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# MIT License -# -# Copyright 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.Tool.gnulink - -Tool-specific initialization for the gnu linker. - -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. - -""" - -import SCons.Tool.linkCommon -import SCons.Util -import SCons.Tool - -from . import link - - -def generate(env): - """Add Builders and construction variables for gnulink to an Environment.""" - link.generate(env) - - if env['PLATFORM'] == 'hpux': - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared -fPIC') - - # __RPATH is set to $_RPATH in the platform specification if that - # platform supports it. - env['RPATHPREFIX'] = '-Wl,-rpath=' - env['RPATHSUFFIX'] = '' - env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' - - -def exists(env): - # TODO: sync with link.smart_link() to choose a linker - linkers = {'CXX': ['g++'], 'CC': ['gcc']} - alltools = [] - for langvar, linktools in linkers.items(): - if langvar in env: # use CC over CXX when user specified CC but not CXX - return SCons.Tool.FindTool(linktools, env) - alltools.extend(linktools) - return SCons.Tool.FindTool(alltools, env) # find CXX or CC - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/gs.py b/scons/scons-local-4.1.0/SCons/Tool/gs.py deleted file mode 100644 index 25359a858..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gs.py +++ /dev/null @@ -1,91 +0,0 @@ -"""SCons.Tool.gs - -Tool-specific initialization for Ghostscript. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Action -import SCons.Builder -import SCons.Platform -import SCons.Util - -# Ghostscript goes by different names on different platforms... -platform = SCons.Platform.platform_default() - -if platform == 'os2': - gs = 'gsos2' -elif platform == 'win32': - gs = 'gswin32c' -else: - gs = 'gs' - -GhostscriptAction = None - -def generate(env): - """Add Builders and construction variables for Ghostscript to an - Environment.""" - global GhostscriptAction - # The following try-except block enables us to use the Tool - # in standalone mode (without the accompanying pdf.py), - # whenever we need an explicit call of gs via the Gs() - # Builder ... - try: - if GhostscriptAction is None: - GhostscriptAction = SCons.Action.Action('$GSCOM', '$GSCOMSTR') - - from SCons.Tool import pdf - pdf.generate(env) - - bld = env['BUILDERS']['PDF'] - bld.add_action('.ps', GhostscriptAction) - except ImportError as e: - pass - - gsbuilder = SCons.Builder.Builder(action = SCons.Action.Action('$GSCOM', '$GSCOMSTR')) - env['BUILDERS']['Gs'] = gsbuilder - - env['GS'] = gs - env['GSFLAGS'] = SCons.Util.CLVar('-dNOPAUSE -dBATCH -sDEVICE=pdfwrite') - env['GSCOM'] = '$GS $GSFLAGS -sOutputFile=$TARGET $SOURCES' - - -def exists(env): - if 'PS2PDF' in env: - return env.Detect(env['PS2PDF']) - else: - return env.Detect(gs) or SCons.Util.WhereIs(gs) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/gxx.py b/scons/scons-local-4.1.0/SCons/Tool/gxx.py deleted file mode 100644 index 88186cbc2..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/gxx.py +++ /dev/null @@ -1,78 +0,0 @@ -"""SCons.Tool.g++ - -Tool-specific initialization for g++. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -import SCons.Tool -import SCons.Util - -from . import gcc -from . import cxx - -compilers = ['g++'] - - -def generate(env): - """Add Builders and construction variables for g++ to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - if 'CXX' not in env: - env['CXX'] = env.Detect(compilers) or compilers[0] - - cxx.generate(env) - - # platform specific settings - 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': - env['SHOBJSUFFIX'] = '.pic.o' - elif env['PLATFORM'] == 'sunos': - env['SHOBJSUFFIX'] = '.pic.o' - # determine compiler version - version = gcc.detect_version(env, env['CXX']) - if version: - env['CXXVERSION'] = version - - -def exists(env): - # is executable, and is a GNU compiler (or accepts '--version' at least) - return gcc.detect_version(env, env.Detect(env.get('CXX', compilers))) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/hpc++.py b/scons/scons-local-4.1.0/SCons/Tool/hpc++.py deleted file mode 100644 index 9631277b4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/hpc++.py +++ /dev/null @@ -1,45 +0,0 @@ -"""SCons.Tool.hpc++ - -Tool-specific initialization for c++ on HP/UX. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -#forward proxy to the preffered cxx version -from SCons.Tool.hpcxx import * - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/hpcc.py b/scons/scons-local-4.1.0/SCons/Tool/hpcc.py deleted file mode 100644 index 51d2e3802..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/hpcc.py +++ /dev/null @@ -1,53 +0,0 @@ -"""SCons.Tool.hpcc - -Tool-specific initialization for HP aCC and cc. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Util - -from . import cc - -def generate(env): - """Add Builders and construction variables for aCC & cc to an Environment.""" - cc.generate(env) - - env['CXX'] = 'aCC' - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS +Z') - -def exists(env): - return env.Detect('aCC') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/hpcxx.py b/scons/scons-local-4.1.0/SCons/Tool/hpcxx.py deleted file mode 100644 index 7113fa222..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/hpcxx.py +++ /dev/null @@ -1,88 +0,0 @@ -"""SCons.Tool.hpc++ - -Tool-specific initialization for c++ on HP/UX. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path - -import SCons.Util - -import SCons.Tool.cxx -cplusplus = SCons.Tool.cxx -#cplusplus = __import__('cxx', globals(), locals(), []) - - -acc = None - -# search for the acc compiler and linker front end - -try: - dirs = os.listdir('/opt') -except (IOError, OSError): - # Not being able to read the directory because it doesn't exist - # (IOError) or isn't readable (OSError) is okay. - dirs = [] - -for dir in dirs: - cc = '/opt/' + dir + '/bin/aCC' - if os.path.exists(cc): - acc = cc - break - - -def generate(env): - """Add Builders and construction variables for g++ to an Environment.""" - cplusplus.generate(env) - - if acc: - env['CXX'] = acc or 'aCC' - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS +Z') - # determine version of aCC - with os.popen(acc + ' -V 2>&1') as p: - line = p.readline().rstrip() - if line.find('aCC: HP ANSI C++') == 0: - env['CXXVERSION'] = line.split()[-1] - - if env['PLATFORM'] == 'cygwin': - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - else: - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS +Z') - -def exists(env): - return acc - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/hplink.py b/scons/scons-local-4.1.0/SCons/Tool/hplink.py deleted file mode 100644 index ba182f1d3..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/hplink.py +++ /dev/null @@ -1,72 +0,0 @@ -"""SCons.Tool.hplink - -Tool-specific initialization for the HP linker. - -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. -""" - -# -# 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. -# - -import os.path - -import SCons.Util - -from . import link - -ccLinker = None - -# search for the acc compiler and linker front end - -try: - dirs = os.listdir('/opt') -except (IOError, OSError): - # Not being able to read the directory because it doesn't exist - # (IOError) or isn't readable (OSError) is okay. - dirs = [] - -for dir in dirs: - linker = '/opt/' + dir + '/bin/aCC' - if os.path.exists(linker): - ccLinker = linker - break - -def generate(env): - """ - Add Builders and construction variables for Visual Age linker to - an Environment. - """ - link.generate(env) - - env['LINKFLAGS'] = SCons.Util.CLVar('-Wl,+s -Wl,+vnocompatwarnings') - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -b') - env['SHLIBSUFFIX'] = '.sl' - -def exists(env): - return ccLinker - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/icc.py b/scons/scons-local-4.1.0/SCons/Tool/icc.py deleted file mode 100644 index adf24e9ab..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/icc.py +++ /dev/null @@ -1,59 +0,0 @@ -"""SCons.Tool.icc - -Tool-specific initialization for the OS/2 icc 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from . import cc - -def generate(env): - """Add Builders and construction variables for the OS/2 to an Environment.""" - cc.generate(env) - - env['CC'] = 'icc' - env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' - env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' - env['CPPDEFPREFIX'] = '/D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '/I' - env['INCSUFFIX'] = '' - env['CFILESUFFIX'] = '.c' - env['CXXFILESUFFIX'] = '.cc' - -def exists(env): - return env.Detect('icc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/icl.py b/scons/scons-local-4.1.0/SCons/Tool/icl.py deleted file mode 100644 index 421a388aa..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/icl.py +++ /dev/null @@ -1,52 +0,0 @@ -"""SCons.Tool.icl - -Tool-specific initialization for the Intel C/C++ 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Tool.intelc - -# This has been completely superseded by intelc.py, which can -# handle both Windows and Linux versions. - -def generate(*args, **kw): - """Add Builders and construction variables for icl to an Environment.""" - return SCons.Tool.intelc.generate(*args, **kw) - -def exists(*args, **kw): - return SCons.Tool.intelc.exists(*args, **kw) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/ifl.py b/scons/scons-local-4.1.0/SCons/Tool/ifl.py deleted file mode 100644 index 865d2baa8..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/ifl.py +++ /dev/null @@ -1,72 +0,0 @@ -"""SCons.Tool.ifl - -Tool-specific initialization for the Intel 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -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.""" - fscan = FortranScan("FORTRANPATH") - SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) - SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan) - - if 'FORTRANFILESUFFIXES' not in env: - env['FORTRANFILESUFFIXES'] = ['.i'] - else: - env['FORTRANFILESUFFIXES'].append('.i') - - if 'F90FILESUFFIXES' not in env: - 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' - env['SHFORTRANPPCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' - -def exists(env): - return env.Detect('ifl') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/ifort.py b/scons/scons-local-4.1.0/SCons/Tool/ifort.py deleted file mode 100644 index 638bd12de..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/ifort.py +++ /dev/null @@ -1,88 +0,0 @@ -"""SCons.Tool.ifort - -Tool-specific initialization for newer versions of the Intel Fortran Compiler -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() -selection method. - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -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. - fscan = FortranScan("FORTRANPATH") - SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) - SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan) - - if 'FORTRANFILESUFFIXES' not in env: - env['FORTRANFILESUFFIXES'] = ['.i'] - else: - env['FORTRANFILESUFFIXES'].append('.i') - - if 'F90FILESUFFIXES' not in env: - env['F90FILESUFFIXES'] = ['.i90'] - else: - env['F90FILESUFFIXES'].append('.i90') - - add_all_to_env(env) - - fc = 'ifort' - - for dialect in ['F77', 'F90', 'FORTRAN', 'F95']: - env['%s' % dialect] = fc - env['SH%s' % dialect] = '$%s' % dialect - if env['PLATFORM'] == 'posix': - 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 dialect in ['F77', 'F90', 'FORTRAN', 'F95']: - for var in ['%sCOM' % dialect, '%sPPCOM' % dialect, - 'SH%sCOM' % dialect, 'SH%sPPCOM' % dialect]: - env[var] = env[var].replace('-o $TARGET', '-object:$TARGET') - env['FORTRANMODDIRPREFIX'] = "/module:" - else: - env['FORTRANMODDIRPREFIX'] = "-module " - -def exists(env): - return env.Detect('ifort') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/ilink.py b/scons/scons-local-4.1.0/SCons/Tool/ilink.py deleted file mode 100644 index 4112825b8..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/ilink.py +++ /dev/null @@ -1,55 +0,0 @@ -"""SCons.Tool.ilink - -Tool-specific initialization for the OS/2 ilink linker. - -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. - -""" - -# -# 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. -# - -import SCons.Defaults -import SCons.Tool -import SCons.Util - -def generate(env): - """Add Builders and construction variables for ilink to an Environment.""" - SCons.Tool.createProgBuilder(env) - - env['LINK'] = 'ilink' - env['LINKFLAGS'] = SCons.Util.CLVar('') - env['LINKCOM'] = '$LINK $LINKFLAGS /O:$TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - env['LIBDIRPREFIX']='/LIBPATH:' - env['LIBDIRSUFFIX']='' - env['LIBLINKPREFIX']='' - env['LIBLINKSUFFIX']='$LIBSUFFIX' - -def exists(env): - return env.Detect('ilink') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/ilink32.py b/scons/scons-local-4.1.0/SCons/Tool/ilink32.py deleted file mode 100644 index 1452fd555..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/ilink32.py +++ /dev/null @@ -1,60 +0,0 @@ -"""SCons.Tool.ilink32 - -XXX - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Tool -import SCons.Tool.bcc32 -import SCons.Util - -def generate(env): - """Add Builders and construction variables for Borland ilink to an - Environment.""" - SCons.Tool.createSharedLibBuilder(env) - SCons.Tool.createProgBuilder(env) - - env['LINK'] = '$CC' - env['LINKFLAGS'] = SCons.Util.CLVar('') - env['LINKCOM'] = '$LINK -q $LINKFLAGS -e$TARGET $SOURCES $LIBS' - env['LIBDIRPREFIX']='' - env['LIBDIRSUFFIX']='' - 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 - return SCons.Tool.bcc32.findIt('bcc32', env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/install.py b/scons/scons-local-4.1.0/SCons/Tool/install.py deleted file mode 100644 index e79203e66..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/install.py +++ /dev/null @@ -1,473 +0,0 @@ -"""SCons.Tool.install - -Tool-specific initialization for the install tool. - -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__ -# -# 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. -# - -import os -from shutil import copy2, copymode, copystat - -import SCons.Action -import SCons.Tool -from SCons.Tool.linkCommon import StringizeLibSymlinks, CreateLibSymlinks, EmitLibSymlinks -import SCons.Util - -# -# We keep track of *all* installed files. -_INSTALLED_FILES = [] -_UNIQUE_INSTALLED_FILES = None - -class CopytreeError(OSError): - pass - - -def scons_copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, - ignore_dangling_symlinks=False, dirs_exist_ok=False): - """Recursively copy a directory tree, SCons version. - - This is a modified copy of the Python 3.7 shutil.copytree function. - SCons update: dirs_exist_ok dictates whether to raise an - exception in case dst or any missing parent directory already - exists. Implementation depends on os.makedirs having a similar - flag, which it has since Python 3.2. This version also raises an - SCons-defined exception rather than the one defined locally to shtuil. - This version uses a change from Python 3.8. - TODO: we can remove this forked copy once the minimum Py version is 3.8. - - If exception(s) occur, an Error is raised with a list of reasons. - - If the optional symlinks flag is true, symbolic links in the - source tree result in symbolic links in the destination tree; if - it is false, the contents of the files pointed to by symbolic - links are copied. If the file pointed by the symlink doesn't - exist, an exception will be added in the list of errors raised in - an Error exception at the end of the copy process. - - You can set the optional ignore_dangling_symlinks flag to true if you - want to silence this exception. Notice that this has no effect on - platforms that don't support os.symlink. - - The optional ignore argument is a callable. If given, it - is called with the `src` parameter, which is the directory - being visited by copytree(), and `names` which is the list of - `src` contents, as returned by os.listdir(): - - callable(src, names) -> ignored_names - - Since copytree() is called recursively, the callable will be - called once for each directory that is copied. It returns a - list of names relative to the `src` directory that should - not be copied. - - The optional copy_function argument is a callable that will be used - to copy each file. It will be called with the source path and the - destination path as arguments. By default, copy2() is used, but any - function that supports the same signature (like copy()) can be used. - - """ - names = os.listdir(src) - if ignore is not None: - ignored_names = ignore(src, names) - else: - ignored_names = set() - - os.makedirs(dst, exist_ok=dirs_exist_ok) - errors = [] - for name in names: - if name in ignored_names: - continue - srcname = os.path.join(src, name) - dstname = os.path.join(dst, name) - try: - if os.path.islink(srcname): - linkto = os.readlink(srcname) - if symlinks: - # We can't just leave it to `copy_function` because legacy - # code with a custom `copy_function` may rely on copytree - # doing the right thing. - os.symlink(linkto, dstname) - copystat(srcname, dstname, follow_symlinks=not symlinks) - else: - # ignore dangling symlink if the flag is on - if not os.path.exists(linkto) and ignore_dangling_symlinks: - continue - # otherwise let the copy occurs. copy2 will raise an error - if os.path.isdir(srcname): - scons_copytree(srcname, dstname, symlinks, ignore, - copy_function, dirs_exist_ok) - else: - copy_function(srcname, dstname) - elif os.path.isdir(srcname): - scons_copytree(srcname, dstname, symlinks, ignore, copy_function, dirs_exist_ok) - else: - # Will raise a SpecialFileError for unsupported file types - copy_function(srcname, dstname) - # catch the Error from the recursive copytree so that we can - # continue with other files - except CopytreeError as err: # SCons change - errors.extend(err.args[0]) - except OSError as why: - errors.append((srcname, dstname, str(why))) - try: - copystat(src, dst) - except OSError as why: - # Copying file access times may fail on Windows - if getattr(why, 'winerror', None) is None: - errors.append((src, dst, str(why))) - if errors: - raise CopytreeError(errors) # SCons change - return dst - -# -# Functions doing the actual work of the Install Builder. -# -def copyFunc(dest, source, env): - """Install a source file or directory into a destination by copying, - - Mode/permissions bits will be copied as well. - - """ - if os.path.isdir(source): - if os.path.exists(dest): - if not os.path.isdir(dest): - raise SCons.Errors.UserError("cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))) - else: - parent = os.path.split(dest)[0] - if not os.path.exists(parent): - os.makedirs(parent) - scons_copytree(source, dest, dirs_exist_ok=True) - else: - copy2(source, dest) - copymode(source, dest) - - return 0 - -# -# Functions doing the actual work of the InstallVersionedLib Builder. -# -def copyFuncVersionedLib(dest, source, env): - """Install a versioned library into a destination by copying, - - Mode/permissions bits will be copied as well. - Any required symbolic links for other library names are created. - - """ - if os.path.isdir(source): - raise SCons.Errors.UserError("cannot install directory `%s' as a version library" % str(source) ) - else: - # remove the link if it is already there - try: - os.remove(dest) - except: - pass - copy2(source, dest) - copymode(source, dest) - installShlibLinks(dest, source, env) - - return 0 - -def listShlibLinksToInstall(dest, source, env): - install_links = [] - source = env.arg2nodes(source) - dest = env.fs.File(dest) - install_dir = dest.get_dir() - for src in source: - symlinks = getattr(getattr(src, 'attributes', None), 'shliblinks', None) - if symlinks: - for link, linktgt in symlinks: - link_base = os.path.basename(link.get_path()) - linktgt_base = os.path.basename(linktgt.get_path()) - install_link = env.fs.File(link_base, install_dir) - install_linktgt = env.fs.File(linktgt_base, install_dir) - install_links.append((install_link, install_linktgt)) - return install_links - -def installShlibLinks(dest, source, env): - """If we are installing a versioned shared library create the required links.""" - Verbose = False - symlinks = listShlibLinksToInstall(dest, source, env) - if Verbose: - print('installShlibLinks: symlinks={!r}'.format(StringizeLibSymlinks(symlinks))) - if symlinks: - CreateLibSymlinks(env, symlinks) - return - -def installFunc(target, source, env): - """Install a source file into a target using the function specified - as the INSTALL construction variable.""" - try: - install = env['INSTALL'] - except KeyError: - raise SCons.Errors.UserError('Missing INSTALL construction variable.') - - assert len(target)==len(source), \ - "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target))) - for t,s in zip(target,source): - if install(t.get_path(),s.get_path(),env): - return 1 - - return 0 - -def installFuncVersionedLib(target, source, env): - """Install a versioned library into a target using the function specified - as the INSTALLVERSIONEDLIB construction variable.""" - try: - install = env['INSTALLVERSIONEDLIB'] - except KeyError: - raise SCons.Errors.UserError('Missing INSTALLVERSIONEDLIB construction variable.') - - assert len(target)==len(source), \ - "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target))) - for t,s in zip(target,source): - if hasattr(t.attributes, 'shlibname'): - tpath = os.path.join(t.get_dir(), t.attributes.shlibname) - else: - tpath = t.get_path() - if install(tpath,s.get_path(),env): - return 1 - - return 0 - -def stringFunc(target, source, env): - installstr = env.get('INSTALLSTR') - if installstr: - return env.subst_target_source(installstr, 0, target, source) - target = str(target[0]) - source = str(source[0]) - if os.path.isdir(source): - type = 'directory' - else: - type = 'file' - return 'Install %s: "%s" as "%s"' % (type, source, target) - -# -# Emitter functions -# -def add_targets_to_INSTALLED_FILES(target, source, env): - """ An emitter that adds all target files to the list stored in the - _INSTALLED_FILES global variable. This way all installed files of one - scons call will be collected. - """ - global _INSTALLED_FILES, _UNIQUE_INSTALLED_FILES - _INSTALLED_FILES.extend(target) - - _UNIQUE_INSTALLED_FILES = None - return (target, source) - -def add_versioned_targets_to_INSTALLED_FILES(target, source, env): - """ An emitter that adds all target files to the list stored in the - _INSTALLED_FILES global variable. This way all installed files of one - scons call will be collected. - """ - global _INSTALLED_FILES, _UNIQUE_INSTALLED_FILES - Verbose = False - _INSTALLED_FILES.extend(target) - if Verbose: - print("add_versioned_targets_to_INSTALLED_FILES: target={!r}".format(list(map(str, target)))) - symlinks = listShlibLinksToInstall(target[0], source, env) - if symlinks: - EmitLibSymlinks(env, symlinks, target[0]) - _UNIQUE_INSTALLED_FILES = None - return (target, source) - -class DESTDIR_factory: - """ A node factory, where all files will be relative to the dir supplied - in the constructor. - """ - def __init__(self, env, dir): - self.env = env - self.dir = env.arg2nodes( dir, env.fs.Dir )[0] - - def Entry(self, name): - name = SCons.Util.make_path_relative(name) - return self.dir.Entry(name) - - def Dir(self, name): - name = SCons.Util.make_path_relative(name) - return self.dir.Dir(name) - -# -# The Builder Definition -# -install_action = SCons.Action.Action(installFunc, stringFunc) -installas_action = SCons.Action.Action(installFunc, stringFunc) -installVerLib_action = SCons.Action.Action(installFuncVersionedLib, stringFunc) - -BaseInstallBuilder = 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 - - import SCons.Script - install_sandbox = SCons.Script.GetOption('install_sandbox') - if install_sandbox: - target_factory = DESTDIR_factory(env, install_sandbox) - else: - target_factory = env.fs - - try: - dnodes = env.arg2nodes(dir, target_factory.Dir) - except TypeError: - raise SCons.Errors.UserError("Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir)) - sources = env.arg2nodes(source, env.fs.Entry) - tgt = [] - for dnode in dnodes: - for src in sources: - # Prepend './' so the lookup doesn't interpret an initial - # '#' 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, **kw)) - return tgt - - -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, **kw)) - return result - -BaseVersionedInstallBuilder = None - - -def InstallVersionedBuilderWrapper(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 - - import SCons.Script - install_sandbox = SCons.Script.GetOption('install_sandbox') - if install_sandbox: - target_factory = DESTDIR_factory(env, install_sandbox) - else: - target_factory = env.fs - - try: - dnodes = env.arg2nodes(dir, target_factory.Dir) - except TypeError: - raise SCons.Errors.UserError("Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir)) - sources = env.arg2nodes(source, env.fs.Entry) - tgt = [] - for dnode in dnodes: - for src in sources: - # Prepend './' so the lookup doesn't interpret an initial - # '#' 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(BaseVersionedInstallBuilder(env, target, src, **kw)) - return tgt - -added = None - - -def generate(env): - - from SCons.Script import AddOption, GetOption - global added - if not added: - added = 1 - AddOption('--install-sandbox', - dest='install_sandbox', - type="string", - action="store", - help='A directory under which all installed files will be placed.') - - global BaseInstallBuilder - if BaseInstallBuilder is None: - install_sandbox = GetOption('install_sandbox') - if install_sandbox: - target_factory = DESTDIR_factory(env, install_sandbox) - else: - target_factory = env.fs - - BaseInstallBuilder = SCons.Builder.Builder( - action = install_action, - target_factory = target_factory.Entry, - source_factory = env.fs.Entry, - multi = 1, - emitter = [ add_targets_to_INSTALLED_FILES, ], - source_scanner = SCons.Scanner.Base( {}, name = 'Install', recursive = False ), - name = 'InstallBuilder') - - global BaseVersionedInstallBuilder - if BaseVersionedInstallBuilder is None: - install_sandbox = GetOption('install_sandbox') - if install_sandbox: - target_factory = DESTDIR_factory(env, install_sandbox) - else: - target_factory = env.fs - - BaseVersionedInstallBuilder = SCons.Builder.Builder( - action = installVerLib_action, - target_factory = target_factory.Entry, - source_factory = env.fs.Entry, - multi = 1, - emitter = [ add_versioned_targets_to_INSTALLED_FILES, ], - name = 'InstallVersionedBuilder') - - env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper - env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper - env['BUILDERS']['_InternalInstallVersionedLib'] = InstallVersionedBuilderWrapper - - # We'd like to initialize this doing something like the following, - # but there isn't yet support for a ${SOURCE.type} expansion that - # will print "file" or "directory" depending on what's being - # installed. For now we punt by not initializing it, and letting - # the stringFunc() that we put in the action fall back to the - # hand-crafted default string if it's not set. - # - #try: - # env['INSTALLSTR'] - #except KeyError: - # env['INSTALLSTR'] = 'Install ${SOURCE.type}: "$SOURCES" as "$TARGETS"' - - try: - env['INSTALL'] - except KeyError: - env['INSTALL'] = copyFunc - - try: - env['INSTALLVERSIONEDLIB'] - except KeyError: - env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib - -def exists(env): - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/intelc.py b/scons/scons-local-4.1.0/SCons/Tool/intelc.py deleted file mode 100644 index 502571950..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/intelc.py +++ /dev/null @@ -1,612 +0,0 @@ -"""SCons.Tool.icl - -Tool-specific initialization for the Intel C/C++ compiler. -Supports Linux and Windows compilers, v7 and up. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import glob -import math -import os.path -import re -import sys - -is_windows = sys.platform == 'win32' -is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or - ('PROCESSOR_ARCHITEW6432' in os.environ and - os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64')) -is_linux = sys.platform.startswith('linux') -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 - -# Exceptions for this tool -class IntelCError(SCons.Errors.InternalError): - pass -class MissingRegistryError(IntelCError): # missing registry entry - pass -class MissingDirError(IntelCError): # dir not found - pass -class NoRegistryModuleError(IntelCError): # can't read registry at all - pass - -def linux_ver_normalize(vstr): - """Normalize a Linux compiler version number. - Intel changed from "80" to "9.0" in 2005, so we assume if the number - is greater than 60 it's an old-style number and otherwise new-style. - Always returns an old-style float like 80 or 90 for compatibility with Windows. - Shades of Y2K!""" - # Check for version number like 9.1.026: return 91.026 - # XXX needs to be updated for 2011+ versions (like 2011.11.344 which is compiler v12.1.5) - m = re.match(r'([0-9]+)\.([0-9]+)\.([0-9]+)', vstr) - if m: - vmaj,vmin,build = m.groups() - return float(vmaj) * 10. + float(vmin) + float(build) / 1000. - else: - f = float(vstr) - if is_windows: - return f - else: - if f < 60: return f * 10.0 - else: return f - -def check_abi(abi): - """Check for valid ABI (application binary interface) name, - and map into canonical one""" - if not abi: - return None - abi = abi.lower() - # valid_abis maps input name to canonical name - if is_windows: - valid_abis = {'ia32' : 'ia32', - 'x86' : 'ia32', - 'ia64' : 'ia64', - '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: - raise SCons.Errors.UserError("Intel compiler: Invalid ABI %s, valid values are %s"% \ - (abi, list(valid_abis.keys()))) - return abi - -def get_version_from_list(v, vlist): - """See if we can match v (string) in vlist (list of strings) - Linux has to match in a fuzzy way.""" - if is_windows: - # Simple case, just find it in the list - if v in vlist: return v - else: return None - else: - # Fuzzy match: normalize version number first, but still return - # original non-normalized form. - fuzz = 0.001 - for vi in vlist: - if math.fabs(linux_ver_normalize(vi) - linux_ver_normalize(v)) < fuzz: - return vi - # Not found - return None - -def get_intel_registry_value(valuename, version=None, abi=None): - """ - Return a value from the Intel compiler registry tree. (Windows only) - """ - # Open the key: - if is_win64: - K = 'Software\\Wow6432Node\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper() - else: - K = 'Software\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper() - try: - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) - except SCons.Util.RegError: - # For version 13 and later, check UUID subkeys for valuename - if is_win64: - K = 'Software\\Wow6432Node\\Intel\\Suites\\' + version + "\\Defaults\\C++\\" + abi.upper() - else: - K = 'Software\\Intel\\Suites\\' + version + "\\Defaults\\C++\\" + abi.upper() - try: - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) - uuid = SCons.Util.RegQueryValueEx(k, 'SubKey')[0] - - if is_win64: - K = 'Software\\Wow6432Node\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++" - else: - K = 'Software\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++" - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) - - try: - v = SCons.Util.RegQueryValueEx(k, valuename)[0] - return v # or v.encode('iso-8859-1', 'replace') to remove unicode? - except SCons.Util.RegError: - if abi.upper() == 'EM64T': - abi = 'em64t_native' - if is_win64: - K = 'Software\\Wow6432Node\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++\\" + abi.upper() - else: - K = 'Software\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++\\" + abi.upper() - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) - - try: - v = SCons.Util.RegQueryValueEx(k, valuename)[0] - return v # or v.encode('iso-8859-1', 'replace') to remove unicode? - except SCons.Util.RegError: - raise MissingRegistryError("%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi)) - - except SCons.Util.RegError: - raise MissingRegistryError("%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi)) - except SCons.Util.WinError: - raise MissingRegistryError("%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi)) - - # Get the value: - try: - v = SCons.Util.RegQueryValueEx(k, valuename)[0] - return v # or v.encode('iso-8859-1', 'replace') to remove unicode? - except SCons.Util.RegError: - raise MissingRegistryError("%s\\%s was not found in the registry."%(K, valuename)) - - -def get_all_compiler_versions(): - """Returns a sorted list of strings, like "70" or "80" or "9.0" - with most recent compiler version first. - """ - versions=[] - if is_windows: - if is_win64: - keyname = 'Software\\WoW6432Node\\Intel\\Compilers\\C++' - else: - keyname = 'Software\\Intel\\Compilers\\C++' - try: - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, - keyname) - except SCons.Util.WinError: - # For version 13 or later, check for default instance UUID - if is_win64: - keyname = 'Software\\WoW6432Node\\Intel\\Suites' - else: - keyname = 'Software\\Intel\\Suites' - try: - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, - keyname) - except SCons.Util.WinError: - return [] - i = 0 - versions = [] - try: - while i < 100: - subkey = SCons.Util.RegEnumKey(k, i) # raises SConsEnvironmentError - # Check that this refers to an existing dir. - # This is not 100% perfect but should catch common - # installation issues like when the compiler was installed - # and then the install directory deleted or moved (rather - # than uninstalling properly), so the registry values - # are still there. - if subkey == 'Defaults': # Ignore default instances - i = i + 1 - continue - ok = False - for try_abi in ('IA32', 'IA32e', 'IA64', 'EM64T'): - try: - d = get_intel_registry_value('ProductDir', subkey, try_abi) - except MissingRegistryError: - continue # not found in reg, keep going - if os.path.exists(d): ok = True - if ok: - versions.append(subkey) - else: - try: - # Registry points to nonexistent dir. Ignore this - # version. - value = get_intel_registry_value('ProductDir', subkey, 'IA32') - except MissingRegistryError as 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 - pass - elif is_linux or is_mac: - for d in glob.glob('/opt/intel_cc_*'): - # Typical dir here is /opt/intel_cc_80. - 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) - m = re.search(r'([0-9][0-9.]*)$', d) - if m: - versions.append(m.group(1)) - for d in glob.glob('/opt/intel/Compiler/*'): - # Typical dir here is /opt/intel/Compiler/11.1 - m = re.search(r'([0-9][0-9.]*)$', d) - if m: - versions.append(m.group(1)) - for d in glob.glob('/opt/intel/composerxe-*'): - # Typical dir here is /opt/intel/composerxe-2011.4.184 - m = re.search(r'([0-9][0-9.]*)$', d) - if m: - versions.append(m.group(1)) - for d in glob.glob('/opt/intel/composer_xe_*'): - # Typical dir here is /opt/intel/composer_xe_2011_sp1.11.344 - # The _sp1 is useless, the installers are named 2011.9.x, 2011.10.x, 2011.11.x - m = re.search(r'([0-9]{0,4})(?:_sp\d*)?\.([0-9][0-9.]*)$', d) - if m: - versions.append("%s.%s"%(m.group(1), m.group(2))) - for d in glob.glob('/opt/intel/compilers_and_libraries_*'): - # JPA: For the new version of Intel compiler 2016.1. - m = re.search(r'([0-9]{0,4})(?:_sp\d*)?\.([0-9][0-9.]*)$', d) - if m: - versions.append("%s.%s"%(m.group(1), m.group(2))) - - def keyfunc(str): - """Given a dot-separated version string, return a tuple of ints representing it.""" - return [int(x) for x in str.split('.')] - # split into ints, sort, then remove dups - return sorted(SCons.Util.unique(versions), key=keyfunc, reverse=True) - -def get_intel_compiler_top(version, abi): - """ - Return the main path to the top-level dir of the Intel compiler, - using the given version. - The compiler will be in /bin/icl.exe (icc on linux), - the include dir is /include, etc. - """ - - if is_windows: - if not SCons.Util.can_read_reg: - raise NoRegistryModuleError("No Windows registry module was found") - top = get_intel_registry_value('ProductDir', version, abi) - archdir={'x86_64': 'intel64', - 'amd64' : 'intel64', - 'em64t' : 'intel64', - 'x86' : 'ia32', - 'i386' : 'ia32', - 'ia32' : 'ia32' - }[abi] # for v11 and greater - # pre-11, icl was in Bin. 11 and later, it's in Bin/ apparently. - if not os.path.exists(os.path.join(top, "Bin", "icl.exe")) \ - and not os.path.exists(os.path.join(top, "Bin", abi, "icl.exe")) \ - and not os.path.exists(os.path.join(top, "Bin", archdir, "icl.exe")): - raise MissingDirError("Can't find Intel compiler in %s" % top) - elif is_mac or is_linux: - def find_in_2008style_dir(version): - # 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': - dirs=('/opt/intel/cce/%s',) # 'e' stands for 'em64t', aka x86_64 aka amd64 - top=None - for d in dirs: - if os.path.exists(os.path.join(d%version, "bin", "icc")): - top = d%version - break - return top - def find_in_2010style_dir(version): - dirs=('/opt/intel/Compiler/%s/*'%version) - # typically /opt/intel/Compiler/11.1/064 (then bin/intel64/icc) - dirs=glob.glob(dirs) - # find highest sub-version number by reverse sorting and picking first existing one. - dirs.sort() - dirs.reverse() - top=None - for d in dirs: - if (os.path.exists(os.path.join(d, "bin", "ia32", "icc")) or - os.path.exists(os.path.join(d, "bin", "intel64", "icc"))): - top = d - break - return top - def find_in_2011style_dir(version): - # The 2011 (compiler v12) dirs are inconsistent, so just redo the search from - # get_all_compiler_versions and look for a match (search the newest form first) - top=None - for d in glob.glob('/opt/intel/composer_xe_*'): - # Typical dir here is /opt/intel/composer_xe_2011_sp1.11.344 - # The _sp1 is useless, the installers are named 2011.9.x, 2011.10.x, 2011.11.x - m = re.search(r'([0-9]{0,4})(?:_sp\d*)?\.([0-9][0-9.]*)$', d) - if m: - cur_ver = "%s.%s"%(m.group(1), m.group(2)) - if cur_ver == version and \ - (os.path.exists(os.path.join(d, "bin", "ia32", "icc")) or - os.path.exists(os.path.join(d, "bin", "intel64", "icc"))): - top = d - break - if not top: - for d in glob.glob('/opt/intel/composerxe-*'): - # Typical dir here is /opt/intel/composerxe-2011.4.184 - m = re.search(r'([0-9][0-9.]*)$', d) - if m and m.group(1) == version and \ - (os.path.exists(os.path.join(d, "bin", "ia32", "icc")) or - os.path.exists(os.path.join(d, "bin", "intel64", "icc"))): - top = d - break - return top - def find_in_2016style_dir(version): - # The 2016 (compiler v16) dirs are inconsistent from previous. - top = None - for d in glob.glob('/opt/intel/compilers_and_libraries_%s/linux'%version): - if os.path.exists(os.path.join(d, "bin", "ia32", "icc")) or os.path.exists(os.path.join(d, "bin", "intel64", "icc")): - top = d - break - return top - - top = find_in_2016style_dir(version) or find_in_2011style_dir(version) or find_in_2010style_dir(version) or find_in_2008style_dir(version) - # print "INTELC: top=",top - if not top: - raise MissingDirError("Can't find version %s Intel compiler in %s (abi='%s')"%(version,top, abi)) - return top - - -def generate(env, version=None, abi=None, topdir=None, verbose=0): - r"""Add Builders and construction variables for Intel C/C++ compiler - to an Environment. - - Args: - version (str): compiler version to use, like "80" - abi (str): 'win32' or whatever Itanium version wants - topdir (str): directory containing compiler tree, e.g. - "c:\\Program Files\\Intel\\Compiler70". - If `topdir` is used, `version` and `abi` are ignored. - verbose: if >0, prints compiler version used. - - """ - if not (is_mac or is_linux or is_windows): - # can't handle this platform - return - - if is_windows: - 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() - if not version: - if vlist: - version = vlist[0] - else: - # User may have specified '90' but we need to get actual dirname '9.0'. - # get_version_from_list does that mapping. - v = get_version_from_list(version, vlist) - if not v: - raise SCons.Errors.UserError("Invalid Intel compiler version %s: "%version + \ - "installed versions are %s"%(', '.join(vlist))) - version = v - - # if abi is unspecified, use ia32 - # 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_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': - abi = 'x86_64' - else: - abi = 'ia32' - else: - if is_win64: - abi = 'em64t' - else: - abi = 'ia32' - - if version and not topdir: - try: - topdir = get_intel_compiler_top(version, abi) - except (SCons.Util.RegError, IntelCError): - topdir = None - - if not topdir: - # Normally this is an error, but it might not be if the compiler is - # on $PATH and the user is importing their env. - class ICLTopDirWarning(SCons.Warnings.SConsWarning): - pass - if (is_mac or is_linux) and not env.Detect('icc') or \ - is_windows and not env.Detect('icl'): - - SCons.Warnings.enableWarningClass(ICLTopDirWarning) - SCons.Warnings.warn(ICLTopDirWarning, - "Failed to find Intel compiler for version='%s', abi='%s'"% - (str(version), str(abi))) - else: - # should be cleaned up to say what this other version is - # since in this case we have some other Intel compiler installed - SCons.Warnings.enableWarningClass(ICLTopDirWarning) - SCons.Warnings.warn(ICLTopDirWarning, - "Can't find Intel compiler top dir for version='%s', abi='%s'"% - (str(version), str(abi))) - - if topdir: - archdir={'x86_64': 'intel64', - 'amd64' : 'intel64', - 'em64t' : 'intel64', - 'x86' : 'ia32', - 'i386' : 'ia32', - 'ia32' : 'ia32' - }[abi] # for v11 and greater - if os.path.exists(os.path.join(topdir, 'bin', archdir)): - bindir="bin/%s"%archdir - libdir="lib/%s"%archdir - else: - bindir="bin" - libdir="lib" - if verbose: - print("Intel C compiler: using version %s (%g), abi %s, in '%s/%s'"%\ - (repr(version), linux_ver_normalize(version),abi,topdir,bindir)) - if is_linux: - # Show the actual compiler version by running the compiler. - os.system('%s/%s/icc --version'%(topdir,bindir)) - if is_mac: - # Show the actual compiler version by running the compiler. - os.system('%s/%s/icc --version'%(topdir,bindir)) - - env['INTEL_C_COMPILER_TOP'] = topdir - if is_linux: - paths={'INCLUDE' : 'include', - 'LIB' : libdir, - 'PATH' : bindir, - 'LD_LIBRARY_PATH' : libdir} - for p, v in paths.items(): - env.PrependENVPath(p, os.path.join(topdir, v)) - if is_mac: - paths={'INCLUDE' : 'include', - 'LIB' : libdir, - 'PATH' : bindir, - 'LD_LIBRARY_PATH' : libdir} - for p, v in paths.items(): - env.PrependENVPath(p, os.path.join(topdir, v)) - 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: - path=get_intel_registry_value(p[1], version, abi) - # These paths may have $(ICInstallDir) - # which needs to be substituted with the topdir. - path=path.replace('$(ICInstallDir)', topdir + os.sep) - except IntelCError: - # Couldn't get it from registry: use default subdir of topdir - env.PrependENVPath(p[0], os.path.join(topdir, p[2])) - else: - env.PrependENVPath(p[0], path.split(os.pathsep)) - # print "ICL %s: %s, final=%s"%(p[0], path, str(env['ENV'][p[0]])) - - if is_windows: - env['CC'] = 'icl' - env['CXX'] = 'icl' - env['LINK'] = 'xilink' - else: - env['CC'] = 'icc' - env['CXX'] = 'icpc' - # Don't reset LINK here; - # use smart_link which should already be here from link.py. - #env['LINK'] = '$CC' - env['AR'] = 'xiar' - env['LD'] = 'xild' # not used by default - - # This is not the exact (detailed) compiler version, - # just the major version as determined above or specified - # by the user. It is a float like 80 or 90, in normalized form for Linux - # (i.e. even for Linux 9.0 compiler, still returns 90 rather than 9.0) - if version: - env['INTEL_C_COMPILER_VERSION']=linux_ver_normalize(version) - - if is_windows: - # Look for license file dir - # in system environment, registry, and default location. - envlicdir = os.environ.get("INTEL_LICENSE_FILE", '') - K = r'SOFTWARE\Intel\Licenses' - try: - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) - reglicdir = SCons.Util.RegQueryValueEx(k, "w_cpp")[0] - except (AttributeError, SCons.Util.RegError): - reglicdir = "" - defaultlicdir = r'C:\Program Files\Common Files\Intel\Licenses' - - licdir = None - for ld in [envlicdir, reglicdir]: - # If the string contains an '@', then assume it's a network - # license (port@system) and good by definition. - if ld and (ld.find('@') != -1 or os.path.exists(ld)): - licdir = ld - break - if not licdir: - licdir = defaultlicdir - if not os.path.exists(licdir): - class ICLLicenseDirWarning(SCons.Warnings.SConsWarning): - pass - SCons.Warnings.enableWarningClass(ICLLicenseDirWarning) - SCons.Warnings.warn(ICLLicenseDirWarning, - "Intel license dir was not found." - " Tried using the INTEL_LICENSE_FILE environment variable (%s), the registry (%s) and the default path (%s)." - " Using the default path as a last resort." - % (envlicdir, reglicdir, defaultlicdir)) - env['ENV']['INTEL_LICENSE_FILE'] = licdir - -def exists(env): - if not (is_mac or is_linux or is_windows): - # can't handle this platform - return 0 - - try: - versions = get_all_compiler_versions() - except (SCons.Util.RegError, IntelCError): - versions = None - detected = versions is not None and len(versions) > 0 - if not detected: - # try env.Detect, maybe that will work - if is_windows: - return env.Detect('icl') - elif is_linux: - return env.Detect('icc') - elif is_mac: - return env.Detect('icc') - return detected - -# end of file - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/ipkg.py b/scons/scons-local-4.1.0/SCons/Tool/ipkg.py deleted file mode 100644 index 8e01dd26d..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/ipkg.py +++ /dev/null @@ -1,75 +0,0 @@ -"""SCons.Tool.ipkg - -Tool-specific initialization for ipkg. - -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. - -The ipkg tool calls the ipkg-build. Its only argument should be the -packages fake_root. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os - -import SCons.Builder - -def generate(env): - """Add Builders and construction variables for ipkg to an Environment.""" - try: - bld = env['BUILDERS']['Ipkg'] - except KeyError: - bld = SCons.Builder.Builder(action='$IPKGCOM', - suffix='$IPKGSUFFIX', - source_scanner=None, - target_scanner=None) - env['BUILDERS']['Ipkg'] = bld - - - env['IPKG'] = 'ipkg-build' - env['IPKGCOM'] = '$IPKG $IPKGFLAGS ${SOURCE}' - - if env.WhereIs('id'): - with os.popen('id -un') as p: - env['IPKGUSER'] = p.read().strip() - with os.popen('id -gn') as p: - env['IPKGGROUP'] = p.read().strip() - env['IPKGFLAGS'] = SCons.Util.CLVar('-o $IPKGUSER -g $IPKGGROUP') - env['IPKGSUFFIX'] = '.ipk' - -def exists(env): - """ - Can we find the tool - """ - return env.Detect('ipkg-build') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/jar.py b/scons/scons-local-4.1.0/SCons/Tool/jar.py deleted file mode 100644 index fa29987cf..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/jar.py +++ /dev/null @@ -1,241 +0,0 @@ -"""SCons.Tool.jar - -Tool-specific initialization for jar. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import os - -import SCons.Subst -import SCons.Util -from SCons.Node.FS import _my_normcase -from SCons.Tool.JavaCommon import get_java_install_dirs - - -def jarSources(target, source, env, for_signature): - """Only include sources that are not a manifest file.""" - 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_text_contents() - if not contents.startswith("Manifest-Version"): - 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(_chdir)) - result.append('-C') - result.append(_chdir) - result.append(src) - return result - -def jarManifest(target, source, env, for_signature): - """Look in sources for a manifest file, if any.""" - for src in source: - contents = src.get_text_contents() - if contents.startswith("Manifest-Version"): - return src - return '' - -def jarFlags(target, source, env, for_signature): - """If we have a manifest, make sure that the 'm' - flag is specified.""" - jarflags = env.subst('$JARFLAGS', target=target, source=source) - for src in source: - contents = src.get_text_contents() - if contents.startswith("Manifest-Version"): - if 'm' not in jarflags: - return jarflags + 'm' - break - return jarflags - -def Jar(env, target = None, source = [], *args, **kw): - """ - A pseudo-Builder wrapper around the separate Jar sources{File,Dir} - Builders. - """ - - # jar target should not be a list so assume they passed - # no target and want implicit target to be made and the arg - # was actaully the list of sources - if SCons.Util.is_List(target) and source == []: - SCons.Warnings.SConsWarning("Making implicit target jar file, " + - "and treating the list as sources") - source = target - target = None - - # mutiple targets pass so build each target the same from the - # same source - #TODO Maybe this should only be done once, and the result copied - # for each target since it should result in the same? - if SCons.Util.is_List(target) and SCons.Util.is_List(source): - jars = [] - for single_target in target: - jars += env.Jar( target = single_target, source = source, *args, **kw) - return jars - - # they passed no target so make a target implicitly - if target is None: - try: - # make target from the first source file - target = os.path.splitext(str(source[0]))[0] + env.subst('$JARSUFFIX') - except: - # something strange is happening but attempt anyways - SCons.Warnings.SConsWarning("Could not make implicit target from sources, using directory") - target = os.path.basename(str(env.Dir('.'))) + env.subst('$JARSUFFIX') - - # make lists out of our target and sources - if not SCons.Util.is_List(target): - target = [target] - if not SCons.Util.is_List(source): - source = [source] - - # setup for checking through all the sources and handle accordingly - java_class_suffix = env.subst('$JAVACLASSSUFFIX') - java_suffix = env.subst('$JAVASUFFIX') - target_nodes = [] - - # function for determining what to do with a file and not a directory - # if its already a class file then it can be used as a - # source for jar, otherwise turn it into a class file then - # return the source - def file_to_class(s): - if _my_normcase(str(s)).endswith(java_suffix): - return env.JavaClassFile(source = s, *args, **kw) - else: - return [env.fs.File(s)] - - # function for calling the JavaClassDir builder if a directory is - # passed as a source to Jar builder. The JavaClassDir builder will - # return an empty list if there were not target classes built from - # the directory, in this case assume the user wanted the directory - # copied into the jar as is (it contains other files such as - # resources or class files compiled from proir commands) - # TODO: investigate the expexcted behavior for directories that - # have mixed content, such as Java files along side other files - # files. - def dir_to_class(s): - dir_targets = env.JavaClassDir(source = s, *args, **kw) - if dir_targets == []: - # no classes files could be built from the source dir - # so pass the dir as is. - return [env.fs.Dir(s)] - else: - return dir_targets - - # loop through the sources and handle each accordingly - # the goal here is to get all the source files into a class - # file or a directory that contains class files - for s in SCons.Util.flatten(source): - s = env.subst(s) - if isinstance(s, SCons.Node.FS.Base): - if isinstance(s, SCons.Node.FS.File): - # found a file so make sure its a class file - target_nodes.extend(file_to_class(s)) - else: - # found a dir so get the class files out of it - target_nodes.extend(dir_to_class(s)) - else: - try: - # source is string try to convert it to file - target_nodes.extend(file_to_class(env.fs.File(s))) - continue - except: - pass - - try: - # source is string try to covnert it to dir - target_nodes.extend(dir_to_class(env.fs.Dir(s))) - continue - except: - pass - - SCons.Warnings.SConsWarning("File: " + str(s) + " could not be identified as File or Directory, skipping.") - - # at this point all our sources have been converted to classes or directories of class - # so pass it to the Jar builder - return env.JarFile(target = target, source = target_nodes, *args, **kw) - -def generate(env): - """Add Builders and construction variables for jar to an Environment.""" - SCons.Tool.CreateJarBuilder(env) - - SCons.Tool.CreateJavaFileBuilder(env) - SCons.Tool.CreateJavaClassFileBuilder(env) - SCons.Tool.CreateJavaClassDirBuilder(env) - - env.AddMethod(Jar) - - if env['PLATFORM'] == 'win32': - # Ensure that we have a proper path for jar - paths = get_java_install_dirs('win32') - jar = SCons.Tool.find_program_path(env, 'jar', default_paths=paths) - if jar: - jar_bin_dir = os.path.dirname(jar) - env.AppendENVPath('PATH', jar_bin_dir) - - env['JAR'] = 'jar' - env['JARFLAGS'] = SCons.Util.CLVar('cf') - env['_JARFLAGS'] = jarFlags - env['_JARMANIFEST'] = jarManifest - env['_JARSOURCES'] = jarSources - env['_JARCOM'] = '$JAR $_JARFLAGS $TARGET $_JARMANIFEST $_JARSOURCES' - env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}" - env['JARSUFFIX'] = '.jar' - -def exists(env): - # As reported by Jan Nijtmans in issue #2730, the simple - # return env.Detect('jar') - # doesn't always work during initialization. For now, we - # stop trying to detect an executable (analogous to the - # javac Builder). - # TODO: Come up with a proper detect() routine...and enable it. - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/javac.py b/scons/scons-local-4.1.0/SCons/Tool/javac.py deleted file mode 100644 index fd007eb51..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/javac.py +++ /dev/null @@ -1,248 +0,0 @@ -"""SCons.Tool.javac - -Tool-specific initialization for javac. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import os.path -from collections import OrderedDict - -import SCons.Action -import SCons.Builder -from SCons.Node.FS import _my_normcase -from SCons.Tool.JavaCommon import parse_java_file, get_java_install_dirs, get_java_include_paths -import SCons.Util - -def classname(path): - """Turn a string (path name) into a Java class name.""" - return os.path.normpath(path).replace(os.sep, '.') - -def emit_java_classes(target, source, env): - """Create and return lists of source java files - and their corresponding target class files. - """ - java_suffix = env.get('JAVASUFFIX', '.java') - class_suffix = env.get('JAVACLASSSUFFIX', '.class') - - target[0].must_be_same(SCons.Node.FS.Dir) - classdir = target[0] - - s = source[0].rentry().disambiguate() - if isinstance(s, SCons.Node.FS.File): - sourcedir = s.dir.rdir() - elif isinstance(s, SCons.Node.FS.Dir): - sourcedir = s.rdir() - else: - raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % s.__class__) - - slist = [] - js = _my_normcase(java_suffix) - for entry in source: - entry = entry.rentry().disambiguate() - if isinstance(entry, SCons.Node.FS.File): - slist.append(entry) - elif isinstance(entry, SCons.Node.FS.Dir): - result = OrderedDict() - dirnode = entry.rdir() - def find_java_files(arg, dirpath, filenames): - java_files = sorted([n for n in filenames - if _my_normcase(n).endswith(js)]) - mydir = dirnode.Dir(dirpath) - java_paths = [mydir.File(f) for f in java_files] - for jp in java_paths: - arg[jp] = True - for dirpath, dirnames, filenames in os.walk(dirnode.get_abspath()): - find_java_files(result, dirpath, filenames) - entry.walk(find_java_files, result) - - slist.extend(list(result.keys())) - else: - raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % entry.__class__) - - version = env.get('JAVAVERSION', '1.4') - full_tlist = [] - for f in slist: - tlist = [] - source_file_based = True - pkg_dir = None - if not f.is_derived(): - pkg_dir, classes = parse_java_file(f.rfile().get_abspath(), version) - if classes: - source_file_based = False - if pkg_dir: - d = target[0].Dir(pkg_dir) - p = pkg_dir + os.sep - else: - d = target[0] - p = '' - for c in classes: - t = d.File(c + class_suffix) - t.attributes.java_classdir = classdir - t.attributes.java_sourcedir = sourcedir - t.attributes.java_classname = classname(p + c) - tlist.append(t) - - if source_file_based: - base = f.name[:-len(java_suffix)] - if pkg_dir: - t = target[0].Dir(pkg_dir).File(base + class_suffix) - else: - t = target[0].File(base + class_suffix) - t.attributes.java_classdir = classdir - t.attributes.java_sourcedir = f.dir - t.attributes.java_classname = classname(base) - tlist.append(t) - - for t in tlist: - t.set_specific_source([f]) - - full_tlist.extend(tlist) - - return full_tlist, slist - -JavaAction = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') - -JavaBuilder = SCons.Builder.Builder(action = JavaAction, - emitter = emit_java_classes, - target_factory = SCons.Node.FS.Entry, - source_factory = SCons.Node.FS.Entry) - -class pathopt: - """ - Callable object for generating javac-style path options from - a construction variable (e.g. -classpath, -sourcepath). - """ - def __init__(self, opt, var, default=None): - self.opt = opt - self.var = var - self.default = default - - def __call__(self, target, source, env, for_signature): - path = env[self.var] - if path and not SCons.Util.is_List(path): - path = [path] - if self.default: - default = env[self.default] - if default: - if not SCons.Util.is_List(default): - default = [default] - path = path + default - if path: - return [self.opt, os.pathsep.join(map(str, path))] - else: - return [] - -def Java(env, target, source, *args, **kw): - """ - A pseudo-Builder wrapper around the separate JavaClass{File,Dir} - Builders. - """ - if not SCons.Util.is_List(target): - target = [target] - if not SCons.Util.is_List(source): - source = [source] - - # Pad the target list with repetitions of the last element in the - # list so we have a target for every source element. - target = target + ([target[-1]] * (len(source) - len(target))) - - java_suffix = env.subst('$JAVASUFFIX') - result = [] - - for t, s in zip(target, source): - if isinstance(s, SCons.Node.FS.Base): - if isinstance(s, SCons.Node.FS.File): - b = env.JavaClassFile - else: - b = env.JavaClassDir - else: - if os.path.isfile(s): - b = env.JavaClassFile - elif os.path.isdir(s): - b = env.JavaClassDir - elif s[-len(java_suffix):] == java_suffix: - b = env.JavaClassFile - else: - b = env.JavaClassDir - result.extend(b(t, s, *args, **kw)) - - return result - -def generate(env): - """Add Builders and construction variables for javac to an Environment.""" - java_file = SCons.Tool.CreateJavaFileBuilder(env) - java_class = SCons.Tool.CreateJavaClassFileBuilder(env) - java_class_dir = SCons.Tool.CreateJavaClassDirBuilder(env) - java_class.add_emitter(None, emit_java_classes) - java_class.add_emitter(env.subst('$JAVASUFFIX'), emit_java_classes) - java_class_dir.emitter = emit_java_classes - - env.AddMethod(Java) - - version = env.get('JAVAVERSION', None) - - if env['PLATFORM'] == 'win32': - # Ensure that we have a proper path for javac - paths = get_java_install_dirs('win32', version=version) - javac = SCons.Tool.find_program_path(env, 'javac', default_paths=paths) - if javac: - javac_bin_dir = os.path.dirname(javac) - env.AppendENVPath('PATH', javac_bin_dir) - else: - javac = SCons.Tool.find_program_path(env, 'javac') - - env['JAVAINCLUDES'] = get_java_include_paths(env, javac, version) - - - env['JAVAC'] = 'javac' - env['JAVACFLAGS'] = SCons.Util.CLVar('') - env['JAVABOOTCLASSPATH'] = [] - env['JAVACLASSPATH'] = [] - env['JAVASOURCEPATH'] = [] - env['_javapathopt'] = pathopt - env['_JAVABOOTCLASSPATH'] = '${_javapathopt("-bootclasspath", "JAVABOOTCLASSPATH")} ' - env['_JAVACLASSPATH'] = '${_javapathopt("-classpath", "JAVACLASSPATH")} ' - env['_JAVASOURCEPATH'] = '${_javapathopt("-sourcepath", "JAVASOURCEPATH", "_JAVASOURCEPATHDEFAULT")} ' - env['_JAVASOURCEPATHDEFAULT'] = '${TARGET.attributes.java_sourcedir}' - env['_JAVACCOM'] = '$JAVAC $JAVACFLAGS $_JAVABOOTCLASSPATH $_JAVACLASSPATH -d ${TARGET.attributes.java_classdir} $_JAVASOURCEPATH $SOURCES' - env['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM','$JAVACCOMSTR')}" - env['JAVACLASSSUFFIX'] = '.class' - env['JAVASUFFIX'] = '.java' - -def exists(env): - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/javah.py b/scons/scons-local-4.1.0/SCons/Tool/javah.py deleted file mode 100644 index fbfcbe249..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/javah.py +++ /dev/null @@ -1,147 +0,0 @@ -"""SCons.Tool.javah - -Tool-specific initialization for javah. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path - -import SCons.Action -import SCons.Builder -import SCons.Node.FS -import SCons.Tool.javac -import SCons.Util -from SCons.Tool.JavaCommon import get_java_install_dirs - - -def emit_java_headers(target, source, env): - """Create and return lists of Java stub header files that will - be created from a set of class files. - """ - class_suffix = env.get('JAVACLASSSUFFIX', '.class') - classdir = env.get('JAVACLASSDIR') - - if not classdir: - try: - s = source[0] - except IndexError: - classdir = '.' - else: - try: - classdir = s.attributes.java_classdir - except AttributeError: - classdir = '.' - classdir = env.Dir(classdir).rdir() - - if str(classdir) == '.': - c_ = None - else: - c_ = str(classdir) + os.sep - - slist = [] - for src in source: - try: - classname = src.attributes.java_classname - except AttributeError: - classname = str(src) - if c_ and classname[:len(c_)] == c_: - classname = classname[len(c_):] - if class_suffix and classname[-len(class_suffix):] == class_suffix: - classname = classname[:-len(class_suffix)] - classname = SCons.Tool.javac.classname(classname) - s = src.rfile() - s.attributes.java_classname = classname - slist.append(s) - - s = source[0].rfile() - if not hasattr(s.attributes, 'java_classdir'): - s.attributes.java_classdir = classdir - - if target[0].__class__ is SCons.Node.FS.File: - tlist = target - else: - if not isinstance(target[0], SCons.Node.FS.Dir): - target[0].__class__ = SCons.Node.FS.Dir - target[0]._morph() - tlist = [] - for s in source: - fname = s.attributes.java_classname.replace('.', '_') + '.h' - t = target[0].File(fname) - t.attributes.java_lookupdir = target[0] - tlist.append(t) - - return tlist, source - -def JavaHOutFlagGenerator(target, source, env, for_signature): - try: - t = target[0] - except (AttributeError, IndexError, TypeError): - t = target - try: - return '-d ' + str(t.attributes.java_lookupdir) - except AttributeError: - return '-o ' + str(t) - -def getJavaHClassPath(env,target, source, for_signature): - path = "${SOURCE.attributes.java_classdir}" - if 'JAVACLASSPATH' in env and env['JAVACLASSPATH']: - path = SCons.Util.AppendPath(path, env['JAVACLASSPATH']) - return "-classpath %s" % path - -def generate(env): - """Add Builders and construction variables for javah to an Environment.""" - java_javah = SCons.Tool.CreateJavaHBuilder(env) - java_javah.emitter = emit_java_headers - - if env['PLATFORM'] == 'win32': - # Ensure that we have a proper path for javah - paths = get_java_install_dirs('win32') - javah = SCons.Tool.find_program_path(env, 'javah', default_paths=paths) - if javah: - javah_bin_dir = os.path.dirname(javah) - env.AppendENVPath('PATH', javah_bin_dir) - - env['_JAVAHOUTFLAG'] = JavaHOutFlagGenerator - env['JAVAH'] = 'javah' - env['JAVAHFLAGS'] = SCons.Util.CLVar('') - env['_JAVAHCLASSPATH'] = getJavaHClassPath - env['JAVAHCOM'] = '$JAVAH $JAVAHFLAGS $_JAVAHOUTFLAG $_JAVAHCLASSPATH ${SOURCES.attributes.java_classname}' - env['JAVACLASSSUFFIX'] = '.class' - -def exists(env): - return env.Detect('javah') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/latex.py b/scons/scons-local-4.1.0/SCons/Tool/latex.py deleted file mode 100644 index f30356b23..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/latex.py +++ /dev/null @@ -1,80 +0,0 @@ -"""SCons.Tool.latex - -Tool-specific initialization for LaTeX. -Generates .dvi files from .latex or .ltx files - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Action -import SCons.Defaults -import SCons.Scanner.LaTeX -import SCons.Util -import SCons.Tool -import SCons.Tool.tex - -def LaTeXAuxFunction(target = None, source= None, env=None): - result = SCons.Tool.tex.InternalLaTeXAuxAction( SCons.Tool.tex.LaTeXAction, target, source, env ) - if result != 0: - SCons.Tool.tex.check_file_error_message(env['LATEX']) - return result - -LaTeXAuxAction = SCons.Action.Action(LaTeXAuxFunction, - strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) - -def generate(env): - """Add Builders and construction variables for LaTeX to an Environment.""" - - env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) - - from . import dvi - dvi.generate(env) - - from . 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_eps_emitter) - bld.add_emitter('.latex', SCons.Tool.tex.tex_eps_emitter) - - SCons.Tool.tex.generate_common(env) - -def exists(env): - SCons.Tool.tex.generate_darwin(env) - return env.Detect('latex') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/ldc.py b/scons/scons-local-4.1.0/SCons/Tool/ldc.py deleted file mode 100644 index fa02bf873..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/ldc.py +++ /dev/null @@ -1,147 +0,0 @@ -# MIT License -# -# Copyright 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.Tool.ldc - -Tool-specific initialization for the LDC compiler. -(https://github.com/ldc-developers/ldc) - -Developed by Russel Winder (russel@winder.org.uk) -2012-05-09 onwards - -Compiler variables: - DC - The name of the D compiler to use. Defaults to ldc2. - 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 ldc2. - DLINKFLAGS - List of linker flags. - -Lib tool variables: - DLIB - Name of the lib tool to use. Defaults to lib. - DLIBFLAGS - List of flags to pass to the lib tool. - LIBS - Same as for the linker. (libraries to pull into the .lib) -""" - - - -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Scanner.D -import SCons.Tool - -import SCons.Tool.DCommon as DCommon - - -def generate(env): - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - static_obj.add_action('.d', SCons.Defaults.DAction) - shared_obj.add_action('.d', SCons.Defaults.ShDAction) - static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) - - env['DC'] = env.Detect('ldc2') or 'ldc2' - 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__)}' - env['_DDEBUGFLAGS'] = '${_concat(DDEBUGPREFIX, DDEBUG, DDEBUGSUFFIX, __env__)}' - env['_DFLAGS'] = '${_concat(DFLAGPREFIX, DFLAGS, DFLAGSUFFIX, __env__)}' - - env['SHDC'] = '$DC' - env['SHDCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -relocation-model=pic -of=$TARGET $SOURCES' - - env['DPATH'] = ['#/'] - env['DFLAGS'] = [] - env['DVERSIONS'] = [] - env['DDEBUG'] = [] - - if env['DC']: - DCommon.addDPATHToEnv(env, env['DC']) - - env['DINCPREFIX'] = '-I=' - env['DINCSUFFIX'] = '' - env['DVERPREFIX'] = '-version=' - env['DVERSUFFIX'] = '' - env['DDEBUGPREFIX'] = '-debug=' - env['DDEBUGSUFFIX'] = '' - env['DFLAGPREFIX'] = '-' - env['DFLAGSUFFIX'] = '' - env['DFILESUFFIX'] = '.d' - - env['DLINK'] = '$DC' - env['DLINKFLAGS'] = SCons.Util.CLVar('') - env['DLINKCOM'] = '$DLINK -of=$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' - - env['SHDLINK'] = '$DC' - env['SHDLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos2-ldc') - - env['SHDLINKCOM'] = '$DLINK -of=$TARGET $SHDLINKFLAGS $__SHDLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS -L-ldruntime-ldc' - - env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' - env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else '' - # env['_DLIBFLAGS'] = '${_concat(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, __env__, RDirs, TARGET, SOURCE)}' - env['_DLIBFLAGS'] = '${_stripixes(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}' - - env['DLIBDIRPREFIX'] = '-L-L' - env['DLIBDIRSUFFIX'] = '' - env['_DLIBDIRFLAGS'] = '${_concat(DLIBDIRPREFIX, LIBPATH, DLIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)}' - - env['DLIB'] = 'lib' if env['PLATFORM'] == 'win32' else 'ar cr' - env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLIBFLAGS'.format('-c ' if env['PLATFORM'] == 'win32' else '') - - # env['_DLIBFLAGS'] = '${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)}' - - env['DLIBFLAGPREFIX'] = '-' - env['DLIBFLAGSUFFIX'] = '' - - # __RPATH is set to $_RPATH in the platform specification if that - # platform supports it. - env['DRPATHPREFIX'] = '-L-Wl,-rpath,' if env['PLATFORM'] == 'darwin' else '-L-rpath=' - env['DRPATHSUFFIX'] = '' - env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' - - # Support for versioned libraries - env['_SHDLIBVERSIONFLAGS'] = '$SHDLIBVERSIONFLAGS -L-soname=$_SHLIBSONAME' - - - env['BUILDERS']['ProgramAllAtOnce'] = SCons.Builder.Builder( - action='$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -of=$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS', - emitter=DCommon.allAtOnceEmitter, - ) - - -def exists(env): - return env.Detect('ldc2') - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/lex.py b/scons/scons-local-4.1.0/SCons/Tool/lex.py deleted file mode 100644 index a9f7a8abd..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/lex.py +++ /dev/null @@ -1,141 +0,0 @@ -"""SCons.Tool.lex - -Tool-specific initialization for lex. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path -import sys - -import SCons.Action -import SCons.Tool -import SCons.Util -from SCons.Platform.mingw import MINGW_DEFAULT_PATHS -from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS -from SCons.Platform.win32 import CHOCO_DEFAULT_PATH - -LexAction = SCons.Action.Action("$LEXCOM", "$LEXCOMSTR") - -if sys.platform == 'win32': - BINS = ['flex', 'lex', 'win_flex'] -else: - BINS = ["flex", "lex"] - -def lexEmitter(target, source, env): - sourceBase, sourceExt = os.path.splitext(SCons.Util.to_String(source[0])) - - if sourceExt == ".lm": # If using Objective-C - target = [sourceBase + ".m"] # the extension is ".m". - - # This emitter essentially tries to add to the target all extra - # files generated by flex. - - # Different options that are used to trigger the creation of extra files. - fileGenOptions = ["--header-file=", "--tables-file="] - - lexflags = env.subst("$LEXFLAGS", target=target, source=source) - for option in SCons.Util.CLVar(lexflags): - for fileGenOption in fileGenOptions: - l = len(fileGenOption) - if option[:l] == fileGenOption: - # A file generating option is present, so add the - # file name to the target list. - fileName = option[l:].strip() - target.append(fileName) - return (target, source) - -def get_lex_path(env, append_paths=False): - """ - Find the path to the lex tool, searching several possible names - - Only called in the Windows case, so the default_path - can be Windows-specific - - :param env: current construction environment - :param append_paths: if set, add the path to the tool to PATH - :return: path to lex tool, if found - """ - for prog in BINS: - bin_path = SCons.Tool.find_program_path( - env, - prog, - default_paths=CHOCO_DEFAULT_PATH + MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if bin_path: - if append_paths: - env.AppendENVPath('PATH', os.path.dirname(bin_path)) - return bin_path - SCons.Warnings.SConsWarning('lex tool requested, but lex or flex binary not found in ENV PATH') - - -def generate(env): - """Add Builders and construction variables for lex to an Environment.""" - c_file, cxx_file = SCons.Tool.createCFileBuilders(env) - - # C - c_file.add_action(".l", LexAction) - c_file.add_emitter(".l", lexEmitter) - - c_file.add_action(".lex", LexAction) - c_file.add_emitter(".lex", lexEmitter) - - # Objective-C - cxx_file.add_action(".lm", LexAction) - cxx_file.add_emitter(".lm", lexEmitter) - - # C++ - cxx_file.add_action(".ll", LexAction) - cxx_file.add_emitter(".ll", lexEmitter) - - env["LEXFLAGS"] = SCons.Util.CLVar("") - - if sys.platform == 'win32': - # ignore the return - we do not need the full path here - _ = get_lex_path(env, append_paths=True) - env["LEX"] = env.Detect(BINS) - if not env.get("LEXUNISTD"): - env["LEXUNISTD"] = SCons.Util.CLVar("") - env["LEXCOM"] = "$LEX $LEXUNISTD $LEXFLAGS -t $SOURCES > $TARGET" - else: - env["LEX"] = env.Detect(BINS) - env["LEXCOM"] = "$LEX $LEXFLAGS -t $SOURCES > $TARGET" - -def exists(env): - if sys.platform == 'win32': - return get_lex_path(env) - else: - return env.Detect(BINS) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/link.py b/scons/scons-local-4.1.0/SCons/Tool/link.py deleted file mode 100644 index efc84f116..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/link.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# MIT License -# -# Copyright 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. -# -""" -Tool-specific initialization for the generic Posix linker. - -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. - -""" - -import SCons.Tool -import SCons.Util -import SCons.Warnings -from SCons.Tool import createProgBuilder -from SCons.Tool.linkCommon import smart_link -from SCons.Tool.linkCommon.LoadableModule import setup_loadable_module_logic -from SCons.Tool.linkCommon.SharedLibrary import setup_shared_lib_logic - - -def generate(env): - """Add Builders and construction variables for gnulink to an Environment.""" - createProgBuilder(env) - - setup_shared_lib_logic(env) - setup_loadable_module_logic(env) - - env['SMARTLINK'] = smart_link - env['LINK'] = "$SMARTLINK" - env['LINKFLAGS'] = SCons.Util.CLVar('') - - # __RPATH is only set to something ($_RPATH typically) on platforms that support it. - env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - env['LIBDIRPREFIX'] = '-L' - env['LIBDIRSUFFIX'] = '' - env['_LIBFLAGS'] = '${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}' - env['LIBLINKPREFIX'] = '-l' - env['LIBLINKSUFFIX'] = '' - - -def exists(env): - # This module isn't really a Tool on its own, it's common logic for - # other linkers. - return None - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/LoadableModule.py b/scons/scons-local-4.1.0/SCons/Tool/linkCommon/LoadableModule.py deleted file mode 100644 index c8124a088..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/LoadableModule.py +++ /dev/null @@ -1,131 +0,0 @@ -# MIT License -# -# Copyright 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. - -from SCons.Tool import createLoadableModuleBuilder -from .SharedLibrary import shlib_symlink_emitter -from . import lib_emitter - - -def ldmod_symlink_emitter(target, source, env, **kw): - return shlib_symlink_emitter(target, source, env, variable_prefix='LDMODULE') - - -def _get_ldmodule_stem(target, source, env, for_signature): - """ - Get the basename for a library (so for libxyz.so, return xyz) - :param target: - :param source: - :param env: - :param for_signature: - :return: - """ - target_name = str(target) - ldmodule_prefix = env.subst('$LDMODULEPREFIX') - ldmodule_suffix = env.subst("$_LDMODULESUFFIX") - - if target_name.startswith(ldmodule_prefix): - target_name = target_name[len(ldmodule_prefix):] - - if target_name.endswith(ldmodule_suffix): - target_name = target_name[:-len(ldmodule_suffix)] - - return target_name - - -def _ldmodule_soversion(target, source, env, for_signature): - """Function to determine what to use for SOVERSION""" - - if 'SOVERSION' in env: - return '.$SOVERSION' - elif 'LDMODULEVERSION' in env: - ldmod_version = env.subst('$LDMODULEVERSION') - # We use only the most significant digit of LDMODULEVERSION - return '.' + ldmod_version.split('.')[0] - else: - return '' - - -def _ldmodule_soname(target, source, env, for_signature): - if 'SONAME' in env: - return '$SONAME' - else: - return "$LDMODULEPREFIX$_get_ldmodule_stem${LDMODULESUFFIX}$_LDMODULESOVERSION" - -def _LDMODULEVERSION(target, source, env, for_signature): - """ - Return "." + version if it's set, otherwise just a blank - """ - value = env.subst('$LDMODULEVERSION', target=target, source=source) - # print("_has_LDMODULEVERSION:%s"%value) - if value: - return "."+value - else: - return "" - -def setup_loadable_module_logic(env): - """ - Just the logic for loadable modules - - For most platforms, a loadable module is the same as a shared - library. Platforms which are different can override these, but - setting them the same means that LoadableModule works everywhere. - - :param env: - :return: - """ - - createLoadableModuleBuilder(env) - - env['_get_ldmodule_stem'] = _get_ldmodule_stem - env['_LDMODULESOVERSION'] = _ldmodule_soversion - env['_LDMODULESONAME'] = _ldmodule_soname - - env['LDMODULENAME'] = '${LDMODULEPREFIX}$_get_ldmodule_stem${_LDMODULESUFFIX}' - - # This is the non versioned LDMODULE filename - # If LDMODULEVERSION is defined then this will symlink to $LDMODULENAME - env['LDMODULE_NOVERSION_SYMLINK'] = '$_get_shlib_dir${LDMODULEPREFIX}$_get_ldmodule_stem${LDMODULESUFFIX}' - - # This is the sonamed file name - # If LDMODULEVERSION is defined then this will symlink to $LDMODULENAME - env['LDMODULE_SONAME_SYMLINK'] = '$_get_shlib_dir$_LDMODULESONAME' - - env['_LDMODULEVERSION'] = _LDMODULEVERSION - - env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME' - - env['LDMODULEEMITTER'] = [lib_emitter, ldmod_symlink_emitter] - - env['LDMODULEPREFIX'] = '$SHLIBPREFIX' - env['_LDMODULESUFFIX'] = '${LDMODULESUFFIX}${_LDMODULEVERSION}' - env['LDMODULESUFFIX'] = '$SHLIBSUFFIX' - - env['LDMODULE'] = '$SHLINK' - - env['LDMODULEFLAGS'] = '$SHLINKFLAGS' - - env['LDMODULECOM'] = '$LDMODULE -o $TARGET $LDMODULEFLAGS $__LDMODULEVERSIONFLAGS $__RPATH $SOURCES ' \ - '$_LIBDIRFLAGS $_LIBFLAGS ' - - env['LDMODULEVERSION'] = '$SHLIBVERSION' - env['LDMODULENOVERSIONSYMLINKS'] = '$SHLIBNOVERSIONSYMLINKS' \ No newline at end of file diff --git a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/README.md b/scons/scons-local-4.1.0/SCons/Tool/linkCommon/README.md deleted file mode 100644 index 4a83c16bb..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# Current implementation details - -The code has been simplified to use Subst expansion do most of the work. - -The following internal env vars have been added which are python functions (note also ldmodule where shlib is below) -* `_get_shlib_stem` - given a library name `libxyz.so.1.1.0` it will retrievve `xyz` -* `_get_shlib_dir` - given a library with a path `DEF/a/b/libxyz.so.1.1.0` it will retrieve `DEF` -* `_SHLIBSOVERSION` - will look for `SOVERSION` and then `SHLIBVERSION` to determine the `SOVERSION` to be used in file naming -* `_SHLIBSONAME` - will check for and error if both `SONAME` and `SOVERSION` are defined, otherwise will generate the proper filenaming for SONAME -* `_SHLIBVERSION` - will return `SHLIBVERSION` or "" if SHLIBVERSION is defined -* `_SHLIBVERSIONFLAGS` - will return proper compiler flags for SHLIBVERSION -* `__SHLIBVERSIONFLAGS` - compiler defined proper versioned shared library flags -* `SHLIB_SONAME_SYMLINK` - this is the symlink for SONAME to be used (`libxyz.1.so`) -* `SHLIB_NOVERSION_SYMLINK` - this is the symlink for non-versioned filename (`libxyz.so`) -Shared library file nodes will have `node.attributes.shliblinks` which is a tuple of the symlinks to be created - - - -# Versioned Shared Library and Loadable modules requirements - -The following env variables can affect the command line and created files for these - -* `SHLIBVERSION` - If this is not set, the all of the following will be ignored? -* `SONAME` -* `SOVERSION` -* `APPLELINK_NO_CURRENT_VERSION` (applelink only) -* `APPLELINK_CURRENT_VERSION` (applelink only) -* `APPLELINK_COMPATIBILITY_VERSION` (applelink only) - -In most cases the linker will create a file named as - -`${SHLIBPREFIX}lib_name${SHLIBVERSION}${SHLIBSUFFIX}` - -Which will have a soname baked into it as one of the - -* `${SONAME}` -* `${SHLIBPREFIX}lib_name${SOVERSION}${SHLIBSUFFIX}` -* `-Wl,-soname=$_SHLIBSONAME` (for gnulink as similar) -* (for applelink only) - * `${SHLIBPREFIX}lib_name${major version only from SHLIBVERSION}${SHLIBSUFFIX}` - * `-Wl,-compatibility_version,%s` - * `-Wl,-current_version,%s` - -For **applelink** the version has to follow these rules to verify that the version # is valid. - -* For version # = X[.Y[.Z]] -* where X 0-65535 -* where Y either not specified or 0-255 -* where Z either not specified or 0-255 - - -For most platforms this will lead to a series of symlinks eventually pointing to the actual shared library (or loadable module file). -1. `${SHLIBPREFIX}lib_name${SHLIBSUFFIX} -> ${SHLIBPREFIX}lib_name${SHLIBVERSION}${SHLIBSUFFIX}` -1. `${SHLIBPREFIX}lib_name${SOVERSION}${SHLIBSUFFIX} -> ${SHLIBPREFIX}lib_name${SHLIBVERSION}${SHLIBSUFFIX}` - -These symlinks are stored by the emitter in the following -`target[0].attributes.shliblinks = symlinks` -This means that those values are fixed a the time SharedLibrary() is called (generally) - -For **openbsd** the following rules for symlinks apply - - * OpenBSD uses x.y shared library versioning numbering convention and doesn't use symlinks to backwards-compatible libraries - - - -User can request: -env.SharedLibrary('a',sources, SHLIBVERSION) -env.SharedLibrary('liba.so',sources, SHLIBVERSION) -Ideally we'll keep the 'a' for use in constructing all follow on. To do this we have to do it in the Builder() or at -least prevent BuilderBase._create_nodes() from discarding this info if it's available. - - -Firstly check if [SH|LD]LIBNOVERSIONSYMLINKS defined or if [SH|LD]LIBVERSION is not defined, if so we do nothing special - -The emitter can calculate the filename stem 'a' above and store it on the target node. Then also create the symlinks -and store those on the node. We should have all the information needed by the time the emitter is called. -Same should apply for loadable modules.. -This should be vastly simpler. -Unfortunately we cannot depend on the target having an OverrideEnvironment() which we could populate all the related -env variables in the emitter... -Maybe we can force one at that point? - - -SOVERSION can be specified, if not, then defaults to major portion of SHLIBVERSION -SONAME can be specified, if not defaults to ${SHLIBPREFIX}lib_name${SOVERSION} - -NOTE: mongodb uses Append(SHLIBEMITTER=.. ) for their libdeps stuff. (So test -with that once you have new logic working) - diff --git a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/SharedLibrary.py b/scons/scons-local-4.1.0/SCons/Tool/linkCommon/SharedLibrary.py deleted file mode 100644 index e28addc61..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/SharedLibrary.py +++ /dev/null @@ -1,199 +0,0 @@ -# MIT License -# -# Copyright 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. - -from SCons.Errors import UserError -from SCons.Tool import createSharedLibBuilder -from SCons.Util import CLVar -from . import lib_emitter, EmitLibSymlinks, StringizeLibSymlinks - - -def shlib_symlink_emitter(target, source, env, **kw): - verbose = False - - if "variable_prefix" in kw: - var_prefix = kw["variable_prefix"] - else: - var_prefix = "SHLIB" - - do_symlinks = env.subst("$%sNOVERSIONSYMLINKS" % var_prefix) - if do_symlinks in ["1", "True", "true", True]: - return target, source - - shlibversion = env.subst("$%sVERSION" % var_prefix) - if shlibversion: - if verbose: - print("shlib_symlink_emitter: %sVERSION=%s" % (var_prefix, shlibversion)) - - libnode = target[0] - shlib_soname_symlink = env.subst( - "$%s_SONAME_SYMLINK" % var_prefix, target=target, source=source - ) - shlib_noversion_symlink = env.subst( - "$%s_NOVERSION_SYMLINK" % var_prefix, target=target, source=source - ) - - if verbose: - print("shlib_soname_symlink :%s" % shlib_soname_symlink) - print("shlib_noversion_symlink :%s" % shlib_noversion_symlink) - print("libnode :%s" % libnode) - - shlib_soname_symlink = env.File(shlib_soname_symlink) - shlib_noversion_symlink = env.File(shlib_noversion_symlink) - - symlinks = [] - if shlib_soname_symlink != libnode: - # If soname and library name machine, don't symlink them together - symlinks.append((env.File(shlib_soname_symlink), libnode)) - - symlinks.append((env.File(shlib_noversion_symlink), libnode)) - - if verbose: - print( - "_lib_emitter: symlinks={!r}".format( - ", ".join( - ["%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks)] - ) - ) - ) - - if symlinks: - # This does the actual symlinking - EmitLibSymlinks(env, symlinks, target[0]) - - # This saves the information so if the versioned shared library is installed - # it can faithfully reproduce the correct symlinks - target[0].attributes.shliblinks = symlinks - - return target, source - - -def _soversion(target, source, env, for_signature): - """Function to determine what to use for SOVERSION""" - - if "SOVERSION" in env: - return ".$SOVERSION" - elif "SHLIBVERSION" in env: - shlibversion = env.subst("$SHLIBVERSION") - # We use only the most significant digit of SHLIBVERSION - return "." + shlibversion.split(".")[0] - else: - return "" - - -def _soname(target, source, env, for_signature): - if "SONAME" in env: - # Now verify that SOVERSION is not also set as that is not allowed - if "SOVERSION" in env: - raise UserError( - "Ambiguous library .so naming, both SONAME: %s and SOVERSION: %s are defined. " - "Only one can be defined for a target library." - % (env["SONAME"], env["SOVERSION"]) - ) - return "$SONAME" - else: - return "$SHLIBPREFIX$_get_shlib_stem${SHLIBSUFFIX}$_SHLIBSOVERSION" - - -def _get_shlib_stem(target, source, env, for_signature): - """ - Get the basename for a library (so for libxyz.so, return xyz) - :param target: - :param source: - :param env: - :param for_signature: - :return: - """ - verbose = False - - target_name = str(target.name) - shlibprefix = env.subst("$SHLIBPREFIX") - shlibsuffix = env.subst("$_SHLIBSUFFIX") - - if verbose and not for_signature: - print( - "_get_shlib_stem: target_name:%s shlibprefix:%s shlibsuffix:%s" - % (target_name, shlibprefix, shlibsuffix) - ) - - if target_name.startswith(shlibprefix): - target_name = target_name[len(shlibprefix) :] - - if target_name.endswith(shlibsuffix): - target_name = target_name[: -len(shlibsuffix)] - - if verbose and not for_signature: - print("_get_shlib_stem: target_name:%s AFTER" % (target_name,)) - - return target_name - - -def _get_shlib_dir(target, source, env, for_signature): - """ - Get the directory the shlib is in. - """ - if target.dir and str(target.dir) != ".": - print("target.dir:%s" % target.dir) - return "%s/" % str(target.dir) - else: - return "" - - -def setup_shared_lib_logic(env): - """ - Just the logic for shared libraries - :param env: - :return: - """ - createSharedLibBuilder(env) - - env["_get_shlib_stem"] = _get_shlib_stem - env["_get_shlib_dir"] = _get_shlib_dir - env["_SHLIBSOVERSION"] = _soversion - env["_SHLIBSONAME"] = _soname - - env["SHLIBNAME"] = "${_get_shlib_dir}${SHLIBPREFIX}$_get_shlib_stem${_SHLIBSUFFIX}" - - # This is the non versioned shlib filename - # If SHLIBVERSION is defined then this will symlink to $SHLIBNAME - env["SHLIB_NOVERSION_SYMLINK"] = "${_get_shlib_dir}${SHLIBPREFIX}$_get_shlib_stem${SHLIBSUFFIX}" - - # This is the sonamed file name - # If SHLIBVERSION is defined then this will symlink to $SHLIBNAME - env["SHLIB_SONAME_SYMLINK"] = "${_get_shlib_dir}$_SHLIBSONAME" - - # Note this is gnu style - env["SHLIBSONAMEFLAGS"] = "-Wl,-soname=$_SHLIBSONAME" - env["_SHLIBVERSION"] = "${SHLIBVERSION and '.'+SHLIBVERSION or ''}" - env["_SHLIBVERSIONFLAGS"] = "$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLIBSONAME" - - env["SHLIBEMITTER"] = [lib_emitter, shlib_symlink_emitter] - - # If it's already set, then don't overwrite. - env["SHLIBPREFIX"] = env.get('SHLIBPREFIX',"lib") - env["_SHLIBSUFFIX"] = "${SHLIBSUFFIX}${_SHLIBVERSION}" - - env["SHLINKFLAGS"] = CLVar("$LINKFLAGS -shared") - - env["SHLINKCOM"] = "$SHLINK -o $TARGET $SHLINKFLAGS $__SHLIBVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS" - env["SHLINKCOMSTR"] = "$SHLINKCOM" - env["SHLINK"] = "$LINK" diff --git a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/__init__.py b/scons/scons-local-4.1.0/SCons/Tool/linkCommon/__init__.py deleted file mode 100644 index 7aaffab92..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/linkCommon/__init__.py +++ /dev/null @@ -1,167 +0,0 @@ -# MIT License -# -# Copyright 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. - -""" -Common link/shared library logic -""" - -import SCons.Util -import SCons.Warnings -from SCons.Tool.DCommon import isD -from SCons.Util import is_List - -issued_mixed_link_warning = False - - -def StringizeLibSymlinks(symlinks): - """Converts list with pairs of nodes to list with pairs of node paths - (strings). Used mainly for debugging.""" - if is_List(symlinks): - try: - return [(k.get_path(), v.get_path()) for k, v in symlinks] - except (TypeError, ValueError): - return symlinks - else: - return symlinks - - -def EmitLibSymlinks(env, symlinks, libnode, **kw): - """Used by emitters to handle (shared/versioned) library symlinks""" - Verbose = False - - # nodes involved in process... all symlinks + library - nodes = list(set([x for x, y in symlinks] + [libnode])) - - clean_targets = kw.get('clean_targets', []) - if not is_List(clean_targets): - clean_targets = [clean_targets] - - for link, linktgt in symlinks: - env.SideEffect(link, linktgt) - if Verbose: - print("EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path())) - clean_list = [x for x in nodes if x != linktgt] - env.Clean(list(set([linktgt] + clean_targets)), clean_list) - if Verbose: - print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list])) - - -def CreateLibSymlinks(env, symlinks): - """Physically creates symlinks. The symlinks argument must be a list in - form [ (link, linktarget), ... ], where link and linktarget are SCons - nodes. - """ - Verbose = False - - for link, linktgt in symlinks: - linktgt = link.get_dir().rel_path(linktgt) - link = link.get_path() - if Verbose: - print("CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt)) - # Delete the (previously created) symlink if exists. Let only symlinks - # to be deleted to prevent accidental deletion of source files... - if env.fs.islink(link): - env.fs.unlink(link) - if Verbose: - print("CreateLibSymlinks: removed old symlink %r" % link) - # If a file or directory exists with the same name as link, an OSError - # will be thrown, which should be enough, I think. - env.fs.symlink(linktgt, link) - if Verbose: - print("CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt)) - return 0 - - -def LibSymlinksActionFunction(target, source, env): - for tgt in target: - symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None) - if symlinks: - CreateLibSymlinks(env, symlinks) - return 0 - - -def LibSymlinksStrFun(target, source, env, *args): - cmd = None - for tgt in target: - symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None) - if symlinks: - if cmd is None: cmd = "" - if cmd: cmd += "\n" - cmd += "Create symlinks for: %r\n " % tgt.get_path() - try: - linkstr = '\n '.join(["%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks)]) - except (KeyError, ValueError): - pass - else: - cmd += "%s" % linkstr - return cmd - - -def _call_env_subst(env, string, *args, **kw): - kw2 = {} - for k in ('raw', 'target', 'source', 'conv', 'executor'): - try: - kw2[k] = kw[k] - except KeyError: - pass - return env.subst(string, *args, **kw2) - - -def smart_link(source, target, env, for_signature): - import SCons.Tool.cxx - import SCons.Tool.FortranCommon - - has_cplusplus = SCons.Tool.cxx.iscplusplus(source) - has_fortran = SCons.Tool.FortranCommon.isfortran(env, source) - has_d = isD(env, source) - if has_cplusplus and has_fortran and not has_d: - 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 % env.subst('$CXX')) - issued_mixed_link_warning = True - return '$CXX' - elif has_d: - env['LINKCOM'] = env['DLINKCOM'] - env['SHLINKCOM'] = env['SHDLINKCOM'] - return '$DC' - elif has_fortran: - return '$FORTRAN' - elif has_cplusplus: - return '$CXX' - return '$CC' - - -def lib_emitter(target, source, env, **kw): - verbose = False - if verbose: - print("_lib_emitter: target[0]={!r}".format(target[0].get_path())) - for tgt in target: - if SCons.Util.is_String(tgt): - tgt = env.File(tgt) - tgt.attributes.shared = 1 - - return target, source diff --git a/scons/scons-local-4.1.0/SCons/Tool/linkloc.py b/scons/scons-local-4.1.0/SCons/Tool/linkloc.py deleted file mode 100644 index 6ee5d6192..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/linkloc.py +++ /dev/null @@ -1,112 +0,0 @@ -"""SCons.Tool.linkloc - -Tool specification for the LinkLoc linker for the Phar Lap ETS embedded -operating system. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import re - -import SCons.Action -import SCons.Defaults -import SCons.Errors -import SCons.Tool -import SCons.Util - -from SCons.Tool.MSCommon import msvs_exists, merge_default_version -from SCons.Tool.PharLapCommon import addPharLapPaths - -_re_linker_command = re.compile(r'(\s)@\s*([^\s]+)') - -def repl_linker_command(m): - # Replaces any linker command file directives (e.g. "@foo.lnk") with - # the actual contents of the file. - try: - with open(m.group(2), "r") as f: - return m.group(1) + f.read() - except IOError: - # the linker should return an error if it can't - # find the linker command file so we will remain quiet. - # However, we will replace the @ with a # so we will not continue - # to find it with recursive substitution - return m.group(1) + '#' + m.group(2) - -class LinklocGenerator: - def __init__(self, cmdline): - self.cmdline = cmdline - - def __call__(self, env, target, source, for_signature): - if for_signature: - # Expand the contents of any linker command files recursively - subs = 1 - strsub = env.subst(self.cmdline, target=target, source=source) - while subs: - strsub, subs = _re_linker_command.subn(repl_linker_command, strsub) - return strsub - else: - return "${TEMPFILE('" + self.cmdline + "')}" - -def generate(env): - """Add Builders and construction variables for ar to an Environment.""" - SCons.Tool.createSharedLibBuilder(env) - SCons.Tool.createProgBuilder(env) - - env['SUBST_CMD_FILE'] = LinklocGenerator - env['SHLINK'] = '$LINK' - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS') - env['SHLINKCOM'] = '${SUBST_CMD_FILE("$SHLINK $SHLINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS -dll $TARGET $SOURCES")}' - env['SHLIBEMITTER']= None - env['LDMODULEEMITTER']= None - env['LINK'] = "linkloc" - env['LINKFLAGS'] = SCons.Util.CLVar('') - env['LINKCOM'] = '${SUBST_CMD_FILE("$LINK $LINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS -exe $TARGET $SOURCES")}' - env['LIBDIRPREFIX']='-libpath ' - env['LIBDIRSUFFIX']='' - env['LIBLINKPREFIX']='-lib ' - env['LIBLINKSUFFIX']='$LIBSUFFIX' - - # Set-up ms tools paths for default version - merge_default_version(env) - - addPharLapPaths(env) - -def exists(env): - if msvs_exists(env): - return env.Detect('linkloc') - else: - return 0 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/m4.py b/scons/scons-local-4.1.0/SCons/Tool/m4.py deleted file mode 100644 index 8506784de..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/m4.py +++ /dev/null @@ -1,63 +0,0 @@ -"""SCons.Tool.m4 - -Tool-specific initialization for m4. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Action -import SCons.Builder -import SCons.Util - -def generate(env): - """Add Builders and construction variables for m4 to an Environment.""" - M4Action = SCons.Action.Action('$M4COM', '$M4COMSTR') - bld = SCons.Builder.Builder(action = M4Action, src_suffix = '.m4') - - env['BUILDERS']['M4'] = bld - - # .m4 files might include other files, and it would be pretty hard - # to write a scanner for it, so let's just cd to the dir of the m4 - # file and run from there. - # The src_suffix setup is like so: file.c.m4 -> file.c, - # file.cpp.m4 -> file.cpp etc. - env['M4'] = 'm4' - env['M4FLAGS'] = SCons.Util.CLVar('-E') - env['M4COM'] = 'cd ${SOURCE.rsrcdir} && $M4 $M4FLAGS < ${SOURCE.file} > ${TARGET.abspath}' - -def exists(env): - return env.Detect('m4') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/masm.py b/scons/scons-local-4.1.0/SCons/Tool/masm.py deleted file mode 100644 index b9d88cd19..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/masm.py +++ /dev/null @@ -1,77 +0,0 @@ -"""SCons.Tool.masm - -Tool-specific initialization for the Microsoft Assembler. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util - -ASSuffixes = ['.s', '.asm', '.ASM'] -ASPPSuffixes = ['.spp', '.SPP', '.sx'] -if SCons.Util.case_sensitive_suffixes('.s', '.S'): - ASPPSuffixes.extend(['.S']) -else: - ASSuffixes.extend(['.S']) - -def generate(env): - """Add Builders and construction variables for masm to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in ASSuffixes: - static_obj.add_action(suffix, SCons.Defaults.ASAction) - shared_obj.add_action(suffix, SCons.Defaults.ASAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) - - for suffix in ASPPSuffixes: - static_obj.add_action(suffix, SCons.Defaults.ASPPAction) - shared_obj.add_action(suffix, SCons.Defaults.ASPPAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) - - env['AS'] = 'ml' - env['ASFLAGS'] = SCons.Util.CLVar('/nologo') - env['ASPPFLAGS'] = '$ASFLAGS' - env['ASCOM'] = '$AS $ASFLAGS /c /Fo$TARGET $SOURCES' - env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c /Fo$TARGET $SOURCES' - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 - -def exists(env): - return env.Detect('ml') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/midl.py b/scons/scons-local-4.1.0/SCons/Tool/midl.py deleted file mode 100644 index 2757c34cd..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/midl.py +++ /dev/null @@ -1,88 +0,0 @@ -"""SCons.Tool.midl - -Tool-specific initialization for midl (Microsoft IDL 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Scanner.IDL -import SCons.Util - -from .MSCommon import msvc_exists - -def midl_emitter(target, source, env): - """Produces a list of outputs from the MIDL compiler""" - base, _ = SCons.Util.splitext(str(target[0])) - tlb = target[0] - incl = base + '.h' - interface = base + '_i.c' - targets = [tlb, incl, interface] - - midlcom = env['MIDLCOM'] - - if midlcom.find('/proxy') != -1: - proxy = base + '_p.c' - targets.append(proxy) - if midlcom.find('/dlldata') != -1: - dlldata = base + '_data.c' - targets.append(dlldata) - - return (targets, source) - -idl_scanner = SCons.Scanner.IDL.IDLScan() - -midl_action = SCons.Action.Action('$MIDLCOM', '$MIDLCOMSTR') - -midl_builder = SCons.Builder.Builder(action = midl_action, - src_suffix = '.idl', - suffix='.tlb', - emitter = midl_emitter, - source_scanner = idl_scanner) - -def generate(env): - """Add Builders and construction variables for midl to an Environment.""" - - env['MIDL'] = 'MIDL.EXE' - env['MIDLFLAGS'] = SCons.Util.CLVar('/nologo') - env['MIDLCOM'] = '$MIDL $MIDLFLAGS /tlb ${TARGETS[0]} /h ${TARGETS[1]} /iid ${TARGETS[2]} /proxy ${TARGETS[3]} /dlldata ${TARGETS[4]} $SOURCE 2> NUL' - env['BUILDERS']['TypeLibrary'] = midl_builder - -def exists(env): - return msvc_exists(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/mingw.py b/scons/scons-local-4.1.0/SCons/Tool/mingw.py deleted file mode 100644 index f72c64df1..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/mingw.py +++ /dev/null @@ -1,215 +0,0 @@ -# MIT License -# -# Copyright 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.Tool.gcc - -Tool-specific initialization for MinGW (http://www.mingw.org/) - -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. - -""" - -import os -import os.path -import glob - -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Tool -import SCons.Util - -mingw_paths = [ - r'c:\MinGW\bin', - r'C:\cygwin64\bin', - r'C:\msys64', - r'C:\msys64\mingw64\bin', - r'C:\cygwin\bin', - r'C:\msys', - r'C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin' -] - - -def shlib_generator(target, source, env, for_signature): - cmd = SCons.Util.CLVar(['$SHLINK', '$SHLINKFLAGS']) - - dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') - if dll: cmd.extend(['-o', dll]) - - cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS']) - - implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') - if implib: cmd.append('-Wl,--out-implib,' + implib.get_string(for_signature)) - - def_target = env.FindIxes(target, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX') - insert_def = env.subst("$WINDOWS_INSERT_DEF") - if insert_def not in ['', '0', 0] and def_target: \ - cmd.append('-Wl,--output-def,' + def_target.get_string(for_signature)) - - return [cmd] - - -def shlib_emitter(target, source, env): - dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') - no_import_lib = env.get('no_import_lib', 0) - - if not dll: - raise SCons.Errors.UserError( - "A shared library should have exactly one target with the suffix: %s Target(s) are:%s" % \ - (env.subst("$SHLIBSUFFIX"), ",".join([str(t) for t in target]))) - - if not no_import_lib and \ - not env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX'): - # Create list of target libraries as strings - targetStrings = env.ReplaceIxes(dll, - 'SHLIBPREFIX', 'SHLIBSUFFIX', - 'LIBPREFIX', 'LIBSUFFIX') - - # Now add file nodes to target list - target.append(env.fs.File(targetStrings)) - - # Append a def file target if there isn't already a def file target - # or a def file source or the user has explicitly asked for the target - # to be emitted. - def_source = env.FindIxes(source, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX') - def_target = env.FindIxes(target, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX') - skip_def_insert = env.subst("$WINDOWS_INSERT_DEF") in ['', '0', 0] - if not def_source and not def_target and not skip_def_insert: - # Create list of target libraries and def files as strings - targetStrings = env.ReplaceIxes(dll, - 'SHLIBPREFIX', 'SHLIBSUFFIX', - 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX') - - # Now add file nodes to target list - target.append(env.fs.File(targetStrings)) - - return (target, source) - - -shlib_action = SCons.Action.Action(shlib_generator, '$SHLINKCOMSTR', generator=1) -ldmodule_action = SCons.Action.Action(shlib_generator, '$LDMODULECOMSTR', generator=1) - -res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') - -res_builder = SCons.Builder.Builder(action=res_action, suffix='.o', - source_scanner=SCons.Tool.SourceFileScanner) -SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) - -# This is what we search for to find mingw: -# key_program = 'mingw32-gcc' -key_program = 'mingw32-make' - - -def find_version_specific_mingw_paths(): - r""" - One example of default mingw install paths is: - C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev2\mingw64\bin - - Use glob'ing to find such and add to mingw_paths - """ - new_paths = glob.glob(r"C:\mingw-w64\*\mingw64\bin") - - return new_paths - - -def generate(env): - global mingw_paths - # Check for reasoanble mingw default paths - mingw_paths += find_version_specific_mingw_paths() - - mingw = SCons.Tool.find_program_path(env, key_program, default_paths=mingw_paths) - if mingw: - mingw_bin_dir = os.path.dirname(mingw) - - # Adjust path if we found it in a chocolatey install - if mingw_bin_dir == r'C:\ProgramData\chocolatey\bin': - mingw_bin_dir = r'C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin' - - env.AppendENVPath('PATH', mingw_bin_dir) - - # Most of mingw is the same as gcc and friends... - gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas', 'gfortran', 'm4'] - for tool in gnu_tools: - SCons.Tool.Tool(tool)(env) - - # ... but a few things differ: - env['CC'] = 'gcc' - # make sure the msvc tool doesnt break us, it added a /flag - if 'CCFLAGS' in env: - # make sure its a CLVar to handle list or str cases - if type(env['CCFLAGS']) is not SCons.Util.CLVar: - env['CCFLAGS'] = SCons.Util.CLVar(env['CCFLAGS']) - env['CCFLAGS'] = SCons.Util.CLVar(str(env['CCFLAGS']).replace('/nologo', '')) - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - env['CXX'] = 'g++' - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') - env['SHLINKCOM'] = shlib_action - env['SHLINKCOMSTR'] = shlib_generator - env['LDMODULECOM'] = ldmodule_action - env.Append(SHLIBEMITTER=[shlib_emitter]) - env.Append(LDMODULEEMITTER=[shlib_emitter]) - env['AS'] = 'as' - - env['WIN32DEFPREFIX'] = '' - env['WIN32DEFSUFFIX'] = '.def' - env['WINDOWSDEFPREFIX'] = '${WIN32DEFPREFIX}' - env['WINDOWSDEFSUFFIX'] = '${WIN32DEFSUFFIX}' - - env['SHOBJSUFFIX'] = '.o' - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 - env['RC'] = 'windres' - env['RCFLAGS'] = SCons.Util.CLVar('') - env['RCINCFLAGS'] = '$( ${_concat(RCINCPREFIX, CPPPATH, RCINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - env['RCINCPREFIX'] = '--include-dir ' - env['RCINCSUFFIX'] = '' - env['RCCOM'] = '$RC $_CPPDEFFLAGS $RCINCFLAGS ${RCINCPREFIX} ${SOURCE.dir} $RCFLAGS -i $SOURCE -o $TARGET' - env['BUILDERS']['RES'] = res_builder - - # Some setting from the platform also have to be overridden: - env['OBJSUFFIX'] = '.o' - env['LIBPREFIX'] = 'lib' - env['LIBSUFFIX'] = '.a' - env['PROGSUFFIX'] = '.exe' - - # Handle new versioned shared library logic - env['_SHLIBSUFFIX'] = '$SHLIBSUFFIX' - env["SHLIBPREFIX"] = "" - - - -def exists(env): - mingw = SCons.Tool.find_program_path(env, key_program, default_paths=mingw_paths) - if mingw: - mingw_bin_dir = os.path.dirname(mingw) - env.AppendENVPath('PATH', mingw_bin_dir) - - return mingw - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/msgfmt.py b/scons/scons-local-4.1.0/SCons/Tool/msgfmt.py deleted file mode 100644 index 3a77fc6d4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/msgfmt.py +++ /dev/null @@ -1,122 +0,0 @@ -""" msgfmt tool """ - -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Builder import BuilderBase -############################################################################# -class _MOFileBuilder(BuilderBase): - """ The builder class for `MO` files. - - The reason for this builder to exists and its purpose is quite simillar - as for `_POFileBuilder`. This time, we extend list of sources, not targets, - and call `BuilderBase._execute()` only once (as we assume single-target - here). - """ - - def _execute(self, env, target, source, *args, **kw): - # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable - # in this case, as it is called too late (after multiple sources - # are handled single_source builder. - import SCons.Util - from SCons.Tool.GettextCommon import _read_linguas_from_files - linguas_files = None - if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: - linguas_files = env['LINGUAS_FILE'] - # This should prevent from endless recursion. - env['LINGUAS_FILE'] = None - # We read only languages. Suffixes shall be added automatically. - linguas = _read_linguas_from_files(env, linguas_files) - if SCons.Util.is_List(source): - source.extend(linguas) - elif source is not None: - source = [source] + linguas - else: - source = linguas - result = BuilderBase._execute(self,env,target,source,*args, **kw) - if linguas_files is not None: - env['LINGUAS_FILE'] = linguas_files - return result -############################################################################# - -############################################################################# -def _create_mo_file_builder(env, **kw): - """ Create builder object for `MOFiles` builder """ - import SCons.Action - # FIXME: What factory use for source? Ours or their? - kw['action'] = SCons.Action.Action('$MSGFMTCOM','$MSGFMTCOMSTR') - kw['suffix'] = '$MOSUFFIX' - kw['src_suffix'] = '$POSUFFIX' - kw['src_builder'] = '_POUpdateBuilder' - kw['single_source'] = True - return _MOFileBuilder(**kw) -############################################################################# - -############################################################################# -def generate(env,**kw): - """ Generate `msgfmt` tool """ - import sys - import os - import SCons.Util - import SCons.Tool - from SCons.Tool.GettextCommon import _detect_msgfmt - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msgfmt = SCons.Tool.find_program_path(env, 'msgfmt', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msgfmt: - msgfmt_bin_dir = os.path.dirname(msgfmt) - env.AppendENVPath('PATH', msgfmt_bin_dir) - else: - SCons.Warnings.SConsWarning('msgfmt tool requested, but binary not found in ENV PATH') - - try: - env['MSGFMT'] = _detect_msgfmt(env) - except: - env['MSGFMT'] = 'msgfmt' - env.SetDefault( - MSGFMTFLAGS = [ SCons.Util.CLVar('-c') ], - MSGFMTCOM = '$MSGFMT $MSGFMTFLAGS -o $TARGET $SOURCE', - MSGFMTCOMSTR = '', - MOSUFFIX = ['.mo'], - POSUFFIX = ['.po'] - ) - env.Append( BUILDERS = { 'MOFiles' : _create_mo_file_builder(env) } ) -############################################################################# - -############################################################################# -def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgfmt_exists - try: - return _msgfmt_exists(env) - except: - return False -############################################################################# - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/msginit.py b/scons/scons-local-4.1.0/SCons/Tool/msginit.py deleted file mode 100644 index 4b72c3000..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/msginit.py +++ /dev/null @@ -1,133 +0,0 @@ -""" msginit tool - -Tool specific initialization of msginit tool. -""" - -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Warnings -import SCons.Builder - -############################################################################# -def _optional_no_translator_flag(env): - """ Return '--no-translator' flag if we run *msginit(1)* in non-interactive - mode.""" - import SCons.Util - if 'POAUTOINIT' in env: - autoinit = env['POAUTOINIT'] - else: - autoinit = False - if autoinit: - return [SCons.Util.CLVar('--no-translator')] - else: - return [SCons.Util.CLVar('')] -############################################################################# - -############################################################################# -def _POInitBuilder(env, **kw): - """ Create builder object for `POInit` builder. """ - import SCons.Action - from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder - action = SCons.Action.Action(_init_po_files, None) - return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') -############################################################################# - -############################################################################# -from SCons.Environment import _null -############################################################################# -def _POInitBuilderWrapper(env, target=None, source=_null, **kw): - """ Wrapper for _POFileBuilder. We use it to make user's life easier. - - This wrapper checks for `$POTDOMAIN` construction variable (or override in - `**kw`) and treats it appropriatelly. - """ - if source is _null: - if 'POTDOMAIN' in kw: - domain = kw['POTDOMAIN'] - elif 'POTDOMAIN' in env: - domain = env['POTDOMAIN'] - else: - domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically - return env._POInitBuilder(target, source, **kw) -############################################################################# - -############################################################################# -def generate(env,**kw): - """ Generate the `msginit` tool """ - import sys - import os - import SCons.Util - import SCons.Tool - from SCons.Tool.GettextCommon import _detect_msginit - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msginit = SCons.Tool.find_program_path(env, 'msginit', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msginit: - msginit_bin_dir = os.path.dirname(msginit) - env.AppendENVPath('PATH', msginit_bin_dir) - else: - SCons.Warnings.SConsWarning('msginit tool requested, but binary not found in ENV PATH') - - try: - env['MSGINIT'] = _detect_msginit(env) - except: - env['MSGINIT'] = 'msginit' - msginitcom = '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' \ - + ' $MSGINITFLAGS -i $SOURCE -o $TARGET' - # NOTE: We set POTSUFFIX here, in case the 'xgettext' is not loaded - # (sometimes we really don't need it) - env.SetDefault( - POSUFFIX = ['.po'], - POTSUFFIX = ['.pot'], - _MSGINITLOCALE = '${TARGET.filebase}', - _MSGNoTranslator = _optional_no_translator_flag, - MSGINITCOM = msginitcom, - MSGINITCOMSTR = '', - MSGINITFLAGS = [ ], - POAUTOINIT = False, - POCREATE_ALIAS = 'po-create' - ) - env.Append( BUILDERS = { '_POInitBuilder' : _POInitBuilder(env) } ) - env.AddMethod(_POInitBuilderWrapper, 'POInit') - env.AlwaysBuild(env.Alias('$POCREATE_ALIAS')) -############################################################################# - -############################################################################# -def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msginit_exists - try: - return _msginit_exists(env) - except: - return False -############################################################################# - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/msgmerge.py b/scons/scons-local-4.1.0/SCons/Tool/msgmerge.py deleted file mode 100644 index 4551235f1..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/msgmerge.py +++ /dev/null @@ -1,117 +0,0 @@ -""" msgmerget tool - -Tool specific initialization for `msgmerge` tool. -""" - -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -############################################################################# -def _update_or_init_po_files(target, source, env): - """ Action function for `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _init_po_files - for tgt in target: - if tgt.rexists(): - action = SCons.Action.Action('$MSGMERGECOM', '$MSGMERGECOMSTR') - else: - action = _init_po_files - status = action([tgt], source, env) - if status : return status - return 0 -############################################################################# - -############################################################################# -def _POUpdateBuilder(env, **kw): - """ Create an object of `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _POFileBuilder - action = SCons.Action.Action(_update_or_init_po_files, None) - return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') -############################################################################# - -############################################################################# -from SCons.Environment import _null -############################################################################# -def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): - """ Wrapper for `POUpdate` builder - make user's life easier """ - if source is _null: - if 'POTDOMAIN' in kw: - domain = kw['POTDOMAIN'] - elif 'POTDOMAIN' in env and env['POTDOMAIN']: - domain = env['POTDOMAIN'] - else: - domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically - return env._POUpdateBuilder(target, source, **kw) -############################################################################# - -############################################################################# -def generate(env,**kw): - """ Generate the `msgmerge` tool """ - import sys - import os - import SCons.Tool - from SCons.Tool.GettextCommon import _detect_msgmerge - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msgmerge = SCons.Tool.find_program_path(env, 'msgmerge', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msgmerge: - msgmerge_bin_dir = os.path.dirname(msgmerge) - env.AppendENVPath('PATH', msgmerge_bin_dir) - else: - SCons.Warnings.SConsWarning('msgmerge tool requested, but binary not found in ENV PATH') - try: - env['MSGMERGE'] = _detect_msgmerge(env) - except: - env['MSGMERGE'] = 'msgmerge' - env.SetDefault( - POTSUFFIX = ['.pot'], - POSUFFIX = ['.po'], - MSGMERGECOM = '$MSGMERGE $MSGMERGEFLAGS --update $TARGET $SOURCE', - MSGMERGECOMSTR = '', - MSGMERGEFLAGS = [ ], - POUPDATE_ALIAS = 'po-update' - ) - env.Append(BUILDERS = { '_POUpdateBuilder':_POUpdateBuilder(env) }) - env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate') - env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS')) -############################################################################# - -############################################################################# -def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgmerge_exists - try: - return _msgmerge_exists(env) - except: - return False -############################################################################# - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/mslib.py b/scons/scons-local-4.1.0/SCons/Tool/mslib.py deleted file mode 100644 index 354f5cfe5..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/mslib.py +++ /dev/null @@ -1,73 +0,0 @@ -"""SCons.Tool.mslib - -Tool-specific initialization for lib (MicroSoft library archiver). - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os - -import SCons.Defaults -import SCons.Tool -import SCons.Tool.msvs -import SCons.Tool.msvc -import SCons.Util - -from .MSCommon import msvc_exists, msvc_setup_env_once - -def generate(env): - """Add Builders and construction variables for lib to an Environment.""" - SCons.Tool.createStaticLibBuilder(env) - - # Set-up ms tools paths - msvc_setup_env_once(env) - - env['AR'] = 'lib' - env['ARFLAGS'] = SCons.Util.CLVar('/nologo') - env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES','$ARCOMSTR')}" - env['LIBPREFIX'] = '' - env['LIBSUFFIX'] = '.lib' - - # Issue #3350 - # Change tempfile argument joining character from a space to a newline - # mslink will fail if any single line is too long, but is fine with many lines - # in a tempfile - env['TEMPFILEARGJOIN'] = os.linesep - - -def exists(env): - return msvc_exists(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/mslink.py b/scons/scons-local-4.1.0/SCons/Tool/mslink.py deleted file mode 100644 index 795807cd4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/mslink.py +++ /dev/null @@ -1,339 +0,0 @@ -"""SCons.Tool.mslink - -Tool-specific initialization for the Microsoft linker. - -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. - -""" - -# -# 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. -# - -import os -import os.path - -import SCons.Action -import SCons.Defaults -import SCons.Errors -import SCons.Platform.win32 -import SCons.Tool -import SCons.Tool.msvc -import SCons.Tool.msvs -import SCons.Util - -from .MSCommon import msvc_setup_env_once, msvc_exists - -def pdbGenerator(env, target, source, for_signature): - try: - return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG'] - except (AttributeError, IndexError): - return None - -def _dllTargets(target, source, env, for_signature, paramtp): - listCmd = [] - dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp) - if dll: listCmd.append("/out:%s"%dll.get_string(for_signature)) - - implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') - if implib: listCmd.append("/implib:%s"%implib.get_string(for_signature)) - - return listCmd - -def _dllSources(target, source, env, for_signature, paramtp): - listCmd = [] - - deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX") - for src in source: - # Check explicitly for a non-None deffile so that the __cmp__ - # method of the base SCons.Util.Proxy class used for some Node - # proxies doesn't try to use a non-existent __dict__ attribute. - if deffile and src == deffile: - # Treat this source as a .def file. - listCmd.append("/def:%s" % src.get_string(for_signature)) - else: - # Just treat it as a generic source file. - listCmd.append(src) - return listCmd - -def windowsShlinkTargets(target, source, env, for_signature): - return _dllTargets(target, source, env, for_signature, 'SHLIB') - -def windowsShlinkSources(target, source, env, for_signature): - return _dllSources(target, source, env, for_signature, 'SHLIB') - -def _windowsLdmodTargets(target, source, env, for_signature): - """Get targets for loadable modules.""" - return _dllTargets(target, source, env, for_signature, 'LDMODULE') - -def _windowsLdmodSources(target, source, env, for_signature): - """Get sources for loadable modules.""" - return _dllSources(target, source, env, for_signature, 'LDMODULE') - -def _dllEmitter(target, source, env, paramtp): - """Common implementation of dll emitter.""" - SCons.Tool.msvc.validate_vars(env) - - extratargets = [] - extrasources = [] - - dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp) - no_import_lib = env.get('no_import_lib', 0) - - if not dll: - raise SCons.Errors.UserError('A shared library should have exactly one target with the suffix: %s' % env.subst('$%sSUFFIX' % paramtp)) - - insert_def = env.subst("$WINDOWS_INSERT_DEF") - if insert_def not in ['', '0', 0] and \ - not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"): - - # append a def file to the list of sources - extrasources.append( - env.ReplaceIxes(dll, - '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, - "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) or env.get('WINDOWS_EMBED_MANIFEST', 0)): - # MSVC 8 and above automatically generate .manifest files that must be installed - extratargets.append( - env.ReplaceIxes(dll, - '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, - "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX")) - - if 'PDB' in env and env['PDB']: - pdb = env.arg2nodes('$PDB', target=target, source=source)[0] - extratargets.append(pdb) - target[0].attributes.pdb = pdb - - if version_num >= 11.0 and env.get('PCH', 0): - # MSVC 11 and above need the PCH object file to be added to the link line, - # otherwise you get link error LNK2011. - pchobj = SCons.Util.splitext(str(env['PCH']))[0] + '.obj' - # print "prog_emitter, version %s, appending pchobj %s"%(version_num, pchobj) - if pchobj not in extrasources: - extrasources.append(pchobj) - - if not no_import_lib and \ - not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"): - # Append an import library to the list of targets. - extratargets.append( - env.ReplaceIxes(dll, - '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, - "LIBPREFIX", "LIBSUFFIX")) - # and .exp file is created if there are exports from a DLL - extratargets.append( - env.ReplaceIxes(dll, - '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, - "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX")) - - return (target+extratargets, source+extrasources) - -def windowsLibEmitter(target, source, env): - return _dllEmitter(target, source, env, 'SHLIB') - -def ldmodEmitter(target, source, env): - """Emitter for loadable modules. - - Loadable modules are identical to shared libraries on Windows, but building - them is subject to different parameters (LDMODULE*). - """ - return _dllEmitter(target, source, env, 'LDMODULE') - -def prog_emitter(target, source, env): - SCons.Tool.msvc.validate_vars(env) - - extratargets = [] - extrasources = [] - - 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")) - - 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) or env.get('WINDOWS_EMBED_MANIFEST', 0)): - # MSVC 8 and above automatically generate .manifest files that have to be installed - extratargets.append( - env.ReplaceIxes(exe, - "PROGPREFIX", "PROGSUFFIX", - "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX")) - - if 'PDB' in env and env['PDB']: - pdb = env.arg2nodes('$PDB', target=target, source=source)[0] - extratargets.append(pdb) - target[0].attributes.pdb = pdb - - if version_num >= 11.0 and env.get('PCH', 0): - # MSVC 11 and above need the PCH object file to be added to the link line, - # otherwise you get link error LNK2011. - pchobj = SCons.Util.splitext(str(env['PCH']))[0] + '.obj' - # print("prog_emitter, version %s, appending pchobj %s"%(version_num, pchobj)) - if pchobj not in extrasources: - extrasources.append(pchobj) - - return (target+extratargets,source+extrasources) - -def RegServerFunc(target, source, env): - if 'register' in env and env['register']: - ret = regServerAction([target[0]], [source[0]], env) - if ret: - raise SCons.Errors.UserError("Unable to register %s" % target[0]) - else: - print("Registered %s sucessfully" % target[0]) - return ret - return 0 - -# These are the actual actions run to embed the manifest. -# They are only called from the Check versions below. -embedManifestExeAction = SCons.Action.Action('$MTEXECOM') -embedManifestDllAction = SCons.Action.Action('$MTSHLIBCOM') - -def embedManifestDllCheck(target, source, env): - """Function run by embedManifestDllCheckAction to check for existence of manifest - and other conditions, and embed the manifest by calling embedManifestDllAction if so.""" - if env.get('WINDOWS_EMBED_MANIFEST', 0): - manifestSrc = target[0].get_abspath() + '.manifest' - if os.path.exists(manifestSrc): - ret = embedManifestDllAction([target[0]], None, env) - if ret: - raise SCons.Errors.UserError("Unable to embed manifest into %s" % (target[0])) - return ret - else: - print('(embed: no %s.manifest found; not embedding.)'%str(target[0])) - return 0 - -def embedManifestExeCheck(target, source, env): - """Function run by embedManifestExeCheckAction to check for existence of manifest - and other conditions, and embed the manifest by calling embedManifestExeAction if so.""" - if env.get('WINDOWS_EMBED_MANIFEST', 0): - manifestSrc = target[0].get_abspath() + '.manifest' - if os.path.exists(manifestSrc): - ret = embedManifestExeAction([target[0]], None, env) - if ret: - raise SCons.Errors.UserError("Unable to embed manifest into %s" % (target[0])) - return ret - else: - print('(embed: no %s.manifest found; not embedding.)'%str(target[0])) - return 0 - -embedManifestDllCheckAction = SCons.Action.Action(embedManifestDllCheck, None) -embedManifestExeCheckAction = SCons.Action.Action(embedManifestExeCheck, None) - -regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR") -regServerCheck = SCons.Action.Action(RegServerFunc, None) -shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES", "$SHLINKCOMSTR")}', '$SHLINKCOMSTR') -compositeShLinkAction = shlibLinkAction + regServerCheck + embedManifestDllCheckAction -ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES", "$LDMODULECOMSTR")}', '$LDMODULECOMSTR') -compositeLdmodAction = ldmodLinkAction + regServerCheck + embedManifestDllCheckAction -exeLinkAction = SCons.Action.Action('${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows", "$LINKCOMSTR")}', '$LINKCOMSTR') -compositeLinkAction = exeLinkAction + embedManifestExeCheckAction - -def generate(env): - """Add Builders and construction variables for ar to an Environment.""" - SCons.Tool.createSharedLibBuilder(env, shlib_suffix='$SHLIBSUFFIX') - SCons.Tool.createProgBuilder(env) - - env['SHLINK'] = '$LINK' - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll') - env['_SHLINK_TARGETS'] = windowsShlinkTargets - env['_SHLINK_SOURCES'] = windowsShlinkSources - env['SHLINKCOM'] = compositeShLinkAction - env.Append(SHLIBEMITTER = [windowsLibEmitter]) - env.Append(LDMODULEEMITTER = [windowsLibEmitter]) - env['LINK'] = 'link' - env['LINKFLAGS'] = SCons.Util.CLVar('/nologo') - env['_PDB'] = pdbGenerator - env['LINKCOM'] = compositeLinkAction - env.Append(PROGEMITTER = [prog_emitter]) - env['LIBDIRPREFIX']='/LIBPATH:' - env['LIBDIRSUFFIX']='' - env['LIBLINKPREFIX']='' - env['LIBLINKSUFFIX']='$LIBSUFFIX' - - env['WIN32DEFPREFIX'] = '' - env['WIN32DEFSUFFIX'] = '.def' - env['WIN32_INSERT_DEF'] = 0 - env['WINDOWSDEFPREFIX'] = '${WIN32DEFPREFIX}' - env['WINDOWSDEFSUFFIX'] = '${WIN32DEFSUFFIX}' - env['WINDOWS_INSERT_DEF'] = '${WIN32_INSERT_DEF}' - - env['WIN32EXPPREFIX'] = '' - env['WIN32EXPSUFFIX'] = '.exp' - env['WINDOWSEXPPREFIX'] = '${WIN32EXPPREFIX}' - env['WINDOWSEXPSUFFIX'] = '${WIN32EXPSUFFIX}' - - env['WINDOWSSHLIBMANIFESTPREFIX'] = '' - env['WINDOWSSHLIBMANIFESTSUFFIX'] = '${SHLIBSUFFIX}.manifest' - env['WINDOWSPROGMANIFESTPREFIX'] = '' - env['WINDOWSPROGMANIFESTSUFFIX'] = '${PROGSUFFIX}.manifest' - - env['REGSVRACTION'] = regServerCheck - env['REGSVR'] = os.path.join(SCons.Platform.win32.get_system_root(),'System32','regsvr32') - env['REGSVRFLAGS'] = '/s ' - env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}' - - env['WINDOWS_EMBED_MANIFEST'] = 0 - env['MT'] = 'mt' - #env['MTFLAGS'] = ['-hashupdate'] - env['MTFLAGS'] = SCons.Util.CLVar('/nologo') - # Note: use - here to prevent build failure if no manifest produced. - # This seems much simpler than a fancy system using a function action to see - # if the manifest actually exists before trying to run mt with it. - env['MTEXECOM'] = '-$MT $MTFLAGS -manifest ${TARGET}.manifest $_MANIFEST_SOURCES -outputresource:$TARGET;1' - env['MTSHLIBCOM'] = '-$MT $MTFLAGS -manifest ${TARGET}.manifest $_MANIFEST_SOURCES -outputresource:$TARGET;2' - # TODO Future work garyo 27-Feb-11 - env['_MANIFEST_SOURCES'] = None # _windowsManifestSources - - # Set-up ms tools paths - msvc_setup_env_once(env) - - - # Loadable modules are on Windows the same as shared libraries, but they - # are subject to different build parameters (LDMODULE* variables). - # Therefore LDMODULE* variables correspond as much as possible to - # SHLINK*/SHLIB* ones. - SCons.Tool.createLoadableModuleBuilder(env, loadable_module_suffix='$LDMODULESUFFIX') - env['LDMODULE'] = '$SHLINK' - env['LDMODULEPREFIX'] = '$SHLIBPREFIX' - env['LDMODULESUFFIX'] = '$SHLIBSUFFIX' - env['LDMODULEFLAGS'] = '$SHLINKFLAGS' - env['_LDMODULE_TARGETS'] = _windowsLdmodTargets - env['_LDMODULE_SOURCES'] = _windowsLdmodSources - env['LDMODULEEMITTER'] = [ldmodEmitter] - env['LDMODULECOM'] = compositeLdmodAction - - # Issue #3350 - # Change tempfile argument joining character from a space to a newline - # mslink will fail if any single line is too long, but is fine with many lines - # in a tempfile - env['TEMPFILEARGJOIN'] = os.linesep - -def exists(env): - return msvc_exists(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/mssdk.py b/scons/scons-local-4.1.0/SCons/Tool/mssdk.py deleted file mode 100644 index b94f105f0..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/mssdk.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -"""SCons.Tool.mssdk - -Tool-specific initialization for Microsoft SDKs, both Platform -SDKs and Windows SDKs. - -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. -""" - -from .MSCommon import mssdk_exists, \ - mssdk_setup_env - -def generate(env): - """Add construction variables for an MS SDK to an Environment.""" - mssdk_setup_env(env) - -def exists(env): - return mssdk_exists() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/msvc.py b/scons/scons-local-4.1.0/SCons/Tool/msvc.py deleted file mode 100644 index a06a434fa..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/msvc.py +++ /dev/null @@ -1,311 +0,0 @@ -"""SCons.Tool.msvc - -Tool-specific initialization for Microsoft Visual C/C++. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path -import os - -import SCons.Action -import SCons.Builder -import SCons.Errors -import SCons.Platform.win32 -import SCons.Tool -import SCons.Tool.msvs -import SCons.Util -import SCons.Warnings -import SCons.Scanner.RC - -from .MSCommon import msvc_exists, msvc_setup_env_once, msvc_version_to_maj_min, msvc_find_vswhere - -CSuffixes = ['.c', '.C'] -CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] - -def validate_vars(env): - """Validate the PCH and PCHSTOP construction variables.""" - if 'PCH' in env and env['PCH']: - if 'PCHSTOP' not in env: - raise SCons.Errors.UserError("The PCHSTOP construction must be defined if PCH is defined.") - if not SCons.Util.is_String(env['PCHSTOP']): - raise SCons.Errors.UserError("The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']) - -def msvc_set_PCHPDBFLAGS(env): - """ - Set appropriate PCHPDBFLAGS for the MSVC version being used. - """ - if env.get('MSVC_VERSION',False): - maj, min = msvc_version_to_maj_min(env['MSVC_VERSION']) - if maj < 8: - env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}']) - else: - env['PCHPDBFLAGS'] = '' - else: - # Default if we can't determine which version of MSVC we're using - env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}']) - - -def pch_emitter(target, source, env): - """Adds the object file target.""" - - validate_vars(env) - - pch = None - obj = None - - for t in target: - if SCons.Util.splitext(str(t))[1] == '.pch': - pch = t - if SCons.Util.splitext(str(t))[1] == '.obj': - obj = t - - if not obj: - obj = SCons.Util.splitext(str(pch))[0]+'.obj' - - target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work - - return (target, source) - -def object_emitter(target, source, env, parent_emitter): - """Sets up the PCH dependencies for an object file.""" - - validate_vars(env) - - parent_emitter(target, source, env) - - # Add a dependency, but only if the target (e.g. 'Source1.obj') - # doesn't correspond to the pre-compiled header ('Source1.pch'). - # If the basenames match, then this was most likely caused by - # someone adding the source file to both the env.PCH() and the - # env.Program() calls, and adding the explicit dependency would - # cause a cycle on the .pch file itself. - # - # See issue #2505 for a discussion of what to do if it turns - # out this assumption causes trouble in the wild: - # https://github.com/SCons/scons/issues/2505 - if 'PCH' in env: - pch = env['PCH'] - if str(target[0]) != SCons.Util.splitext(str(pch))[0] + '.obj': - env.Depends(target, pch) - - return (target, source) - -def static_object_emitter(target, source, env): - return object_emitter(target, source, env, - SCons.Defaults.StaticObjectEmitter) - -def shared_object_emitter(target, source, env): - return object_emitter(target, source, env, - SCons.Defaults.SharedObjectEmitter) - -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) - - -# 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=res_scanner) - -def msvc_batch_key(action, env, target, source): - """ - Returns a key to identify unique batches of sources for compilation. - - If batching is enabled (via the $MSVC_BATCH setting), then all - target+source pairs that use the same action, defined by the same - environment, and have the same target and source directories, will - be batched. - - Returning None specifies that the specified target+source should not - be batched with other compilations. - """ - - # Fixing MSVC_BATCH mode. Previous if did not work when MSVC_BATCH - # was set to False. This new version should work better. - # Note we need to do the env.subst so $MSVC_BATCH can be a reference to - # another construction variable, which is why we test for False and 0 - # as strings. - if 'MSVC_BATCH' not in env or env.subst('$MSVC_BATCH') in ('0', 'False', '', None): - # We're not using batching; return no key. - return None - t = target[0] - s = source[0] - if os.path.splitext(t.name)[0] != os.path.splitext(s.name)[0]: - # The base names are different, so this *must* be compiled - # separately; return no key. - return None - return (id(action), id(env), t.dir, s.dir) - -def msvc_output_flag(target, source, env, for_signature): - """ - Returns the correct /Fo flag for batching. - - If batching is disabled or there's only one source file, then we - return an /Fo string that specifies the target explicitly. Otherwise, - we return an /Fo string that just specifies the first target's - directory (where the Visual C/C++ compiler will put the .obj files). - """ - - # Fixing MSVC_BATCH mode. Previous if did not work when MSVC_BATCH - # was set to False. This new version should work better. Removed - # len(source)==1 as batch mode can compile only one file - # (and it also fixed problem with compiling only one changed file - # with batch mode enabled) - if 'MSVC_BATCH' not in env or env.subst('$MSVC_BATCH') in ('0', 'False', '', None): - return '/Fo$TARGET' - else: - # The Visual C/C++ compiler requires a \ at the end of the /Fo - # option to indicate an output directory. We use os.sep here so - # that the test(s) for this can be run on non-Windows systems - # without having a hard-coded backslash mess up command-line - # argument parsing. - # Adding double os.sep's as if the TARGET.dir has a space or otherwise - # needs to be quoted they are needed per MSVC's odd behavior - # See: https://github.com/SCons/scons/issues/3106 - return '/Fo${TARGET.dir}' + os.sep*2 - -CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR", - batch_key=msvc_batch_key, - targets='$CHANGED_TARGETS') -ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR", - batch_key=msvc_batch_key, - targets='$CHANGED_TARGETS') -CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR", - batch_key=msvc_batch_key, - targets='$CHANGED_TARGETS') -ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR", - batch_key=msvc_batch_key, - targets='$CHANGED_TARGETS') - - -def generate(env): - """Add Builders and construction variables for MSVC++ to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - # TODO(batch): shouldn't reach in to cmdgen this way; necessary - # for now to bypass the checks in Builder.DictCmdGenerator.__call__() - # and allow .cc and .cpp to be compiled in the same command line. - static_obj.cmdgen.source_ext_match = False - shared_obj.cmdgen.source_ext_match = False - - for suffix in CSuffixes: - static_obj.add_action(suffix, CAction) - shared_obj.add_action(suffix, ShCAction) - static_obj.add_emitter(suffix, static_object_emitter) - shared_obj.add_emitter(suffix, shared_object_emitter) - - for suffix in CXXSuffixes: - static_obj.add_action(suffix, CXXAction) - shared_obj.add_action(suffix, ShCXXAction) - static_obj.add_emitter(suffix, static_object_emitter) - shared_obj.add_emitter(suffix, shared_object_emitter) - - 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['_MSVC_OUTPUT_FLAG'] = msvc_output_flag - env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS' - env['CC'] = 'cl' - env['CCFLAGS'] = SCons.Util.CLVar('/nologo') - env['CFLAGS'] = SCons.Util.CLVar('') - env['CCCOM'] = '${TEMPFILE("$CC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM","$CCCOMSTR")}' - env['SHCC'] = '$CC' - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') - env['SHCCCOM'] = '${TEMPFILE("$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCCCOMSTR")}' - env['CXX'] = '$CC' - env['CXXFLAGS'] = SCons.Util.CLVar('$( /TP $)') - env['CXXCOM'] = '${TEMPFILE("$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM","$CXXCOMSTR")}' - env['SHCXX'] = '$CXX' - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - env['SHCXXCOM'] = '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCXXCOMSTR")}' - env['CPPDEFPREFIX'] = '/D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '/I' - env['INCSUFFIX'] = '' -# env.Append(OBJEMITTER = [static_object_emitter]) -# env.Append(SHOBJEMITTER = [shared_object_emitter]) - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 - - env['RC'] = 'rc' - env['RCFLAGS'] = SCons.Util.CLVar('/nologo') - env['RCSUFFIXES']=['.rc','.rc2'] - env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES' - env['BUILDERS']['RES'] = res_builder - env['OBJPREFIX'] = '' - env['OBJSUFFIX'] = '.obj' - env['SHOBJPREFIX'] = '$OBJPREFIX' - env['SHOBJSUFFIX'] = '$OBJSUFFIX' - - # MSVC probably wont support unistd.h so default - # without it for lex generation - env["LEXUNISTD"] = SCons.Util.CLVar("--nounistd") - - # Get user specified vswhere location or locate. - env['VSWHERE'] = env.get('VSWHERE', msvc_find_vswhere()) - - # Set-up ms tools paths - msvc_setup_env_once(env) - - env['CFILESUFFIX'] = '.c' - env['CXXFILESUFFIX'] = '.cc' - - msvc_set_PCHPDBFLAGS(env) - - # Issue #3350 - # Change tempfile argument joining character from a space to a newline - # mslink will fail if any single line is too long, but is fine with many lines - # in a tempfile - env['TEMPFILEARGJOIN'] = os.linesep - - - env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS' - env['BUILDERS']['PCH'] = pch_builder - - if 'ENV' not in env: - env['ENV'] = {} - if 'SystemRoot' not in env['ENV']: # required for dlls in the winsxs folders - env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root() - -def exists(env): - return msvc_exists(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/msvs.py b/scons/scons-local-4.1.0/SCons/Tool/msvs.py deleted file mode 100644 index c398365c3..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/msvs.py +++ /dev/null @@ -1,2116 +0,0 @@ -"""SCons.Tool.msvs - -Tool-specific initialization for Microsoft Visual Studio project files. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.compat - -import base64 -import uuid -import ntpath -import os -import pickle -import re -import sys - -import SCons.Builder -import SCons.Node.FS -import SCons.Platform.win32 -import SCons.Script.SConscript -import SCons.PathList -import SCons.Util -import SCons.Warnings - -from .MSCommon import msvc_exists, msvc_setup_env_once -from SCons.Defaults import processDefines -from SCons.compat import PICKLE_PROTOCOL - -############################################################################## -# Below here are the classes and functions for generation of -# DSP/DSW/SLN/VCPROJ files. -############################################################################## - -def xmlify(s): - s = s.replace("&", "&") # do this first - s = s.replace("'", "'") - s = s.replace('"', """) - s = s.replace('<', "<") - s = s.replace('>', ">") - s = s.replace('\n', ' ') - return s - - -def processIncludes(includes, env, target, source): - """ - Process a CPPPATH list in includes, given the env, target and source. - Returns a list of directory paths. These paths are absolute so we avoid - putting pound-prefixed paths in a Visual Studio project file. - """ - return [env.Dir(i).abspath for i in - SCons.PathList.PathList(includes).subst_path(env, target, source)] - -# Work-in-progress -# individual elements each get a globally unique identifier. -# however, there also are some "well known" guids that either -# represent something, or are used as a namespace to base -# generating guids that should be "in" the namespace -#NAMESPACE_PROJECT = uuid.UUID("{D9BD5916-F055-4D77-8C69-9448E02BF433}") -#NAMESPACE_SLN_GROUP = uuid.UUID("{2D0C29E0-512F-47BE-9AC4-F4CAE74AE16E}") -#NAMESPACE_INTERNAL = uuid.UUID("{BAA4019E-6D67-4EF1-B3CB-AE6CD82E4060}") - -# Kinds of projects, as used in solution files -#PROJECT_KIND_C = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}" -#PROJECT_KIND_PCL = "{786C830F-07A1-408B-BD7F-6EE04809D6DB}" -#NAMESPACE_PRJ_FOLDER = "{66A26720-8FB5-11D2-AA7E-00C04F688DDE}" -#NAMESPACE_SLN_FOLDER = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}" -#NAMESPACE_TEST = "{3AC096D0-A1C2-E12C-1390-A8335801FDAB}" - -def processFlags(flags, env): - """ - If /std:c++XX is in flags then we need to ensure /Zc:__cplusplus is in - flags to tell intellisense to respect our specified standard - """ - if any(f.startswith('/std:c++') for f in flags) and \ - not any(f == '/Zc:__cplusplus' for f in flags): - flags.append('/Zc:__cplusplus') - return [env.subst(f) for f in flags] - - -external_makefile_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' - -def _generateGUID(slnfile, name, namespace=external_makefile_guid): - """Generates a GUID for the sln file to use. - - The uuid5 function is used to combine an existing namespace uuid - - the one VS uses for C projects (external_makedile_guid) - - and a combination of the solution file name (slnfile) and the - project name (name). We just need uniqueness/repeatability. - - Returns (str) "displayable" GUID, already wrapped in braces - """ - - # Normalize the slnfile path to a Windows path (\ separators) so - # the generated file has a consistent GUID even if we generate - # it on a non-Windows platform. - slnfile = ntpath.normpath(str(slnfile)) - solution = uuid.uuid5(uuid.UUID(namespace), "%s-%s" %(slnfile, name)) - return '{' + str(solution).upper() + '}' - - -version_re = re.compile(r'(\d+\.\d+)(.*)') - - -def msvs_parse_version(s): - """ - Split a Visual Studio version, which may in fact be something like - '7.0Exp', into is version number (returned as a float) and trailing - "suite" portion. - """ - num, suite = version_re.match(s).groups() - return float(num), suite - -# This is how we re-invoke SCons from inside MSVS Project files. -# The problem is that we might have been invoked as either scons.bat -# or scons.py. If we were invoked directly as scons.py, then we could -# use sys.argv[0] to find the SCons "executable," but that doesn't work -# if we were invoked as scons.bat, which uses "python -c" to execute -# things and ends up with "-c" as sys.argv[0]. Consequently, we have -# the MSVS Project file invoke SCons the same way that scons.bat does, -# which works regardless of how we were invoked. -def getExecScriptMain(env, xml=None): - scons_home = env.get('SCONS_HOME') - if not scons_home and 'SCONS_LIB_DIR' in os.environ: - scons_home = os.environ['SCONS_LIB_DIR'] - if scons_home: - exec_script_main = "from os.path import join; import sys; sys.path = [ r'%s' ] + sys.path; import SCons.Script; SCons.Script.main()" % scons_home - else: - version = SCons.__version__ - exec_script_main = "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-%(version)s'), join(sys.prefix, 'scons-%(version)s'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()" % locals() - if xml: - exec_script_main = xmlify(exec_script_main) - return exec_script_main - -# The string for the Python executable we tell the Project file to use -# is either sys.executable or, if an external PYTHON_ROOT environment -# variable exists, $(PYTHON)ROOT\\python.exe (generalized a little to -# pluck the actual executable name from sys.executable). -try: - python_root = os.environ['PYTHON_ROOT'] -except KeyError: - python_executable = sys.executable -else: - python_executable = os.path.join('$$(PYTHON_ROOT)', - os.path.split(sys.executable)[1]) - -class Config: - pass - -def splitFully(path): - dir, base = os.path.split(path) - if dir and dir != '' and dir != path: - return splitFully(dir)+[base] - if base == '': - return [] - return [base] - -def makeHierarchy(sources): - """Break a list of files into a hierarchy; for each value, if it is a string, - then it is a file. If it is a dictionary, it is a folder. The string is - the original path of the file.""" - - hierarchy = {} - for file in sources: - path = splitFully(file) - if len(path): - dict = hierarchy - for part in path[:-1]: - if part not in dict: - dict[part] = {} - dict = dict[part] - dict[path[-1]] = file - #else: - # print 'Warning: failed to decompose path for '+str(file) - return hierarchy - -class _UserGenerator: - """ - Base class for .dsp.user file generator - """ - # Default instance values. - # Ok ... a bit defensive, but it does not seem reasonable to crash the - # build for a workspace user file. :-) - usrhead = None - usrdebg = None - usrconf = None - createfile = False - def __init__(self, dspfile, source, env): - # DebugSettings should be a list of debug dictionary sorted in the same order - # as the target list and variants - if 'variant' not in env: - raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\ - "'Release') to create an MSVSProject.") - elif SCons.Util.is_String(env['variant']): - variants = [env['variant']] - elif SCons.Util.is_List(env['variant']): - variants = env['variant'] - - if 'DebugSettings' not in env or env['DebugSettings'] is None: - dbg_settings = [] - elif SCons.Util.is_Dict(env['DebugSettings']): - dbg_settings = [env['DebugSettings']] - elif SCons.Util.is_List(env['DebugSettings']): - if len(env['DebugSettings']) != len(variants): - raise SCons.Errors.InternalError("Sizes of 'DebugSettings' and 'variant' lists must be the same.") - dbg_settings = [] - for ds in env['DebugSettings']: - if SCons.Util.is_Dict(ds): - dbg_settings.append(ds) - else: - dbg_settings.append({}) - else: - dbg_settings = [] - - if len(dbg_settings) == 1: - dbg_settings = dbg_settings * len(variants) - - self.createfile = self.usrhead and self.usrdebg and self.usrconf and \ - dbg_settings and bool([ds for ds in dbg_settings if ds]) - - if self.createfile: - dbg_settings = dict(list(zip(variants, dbg_settings))) - for var, src in dbg_settings.items(): - # Update only expected keys - trg = {} - for key in [k for k in self.usrdebg.keys() if k in src]: - trg[key] = str(src[key]) - self.configs[var].debug = trg - - def UserHeader(self): - encoding = self.env.subst('$MSVSENCODING') - versionstr = self.versionstr - self.usrfile.write(self.usrhead % locals()) - - def UserProject(self): - pass - - def Build(self): - if not self.createfile: - return - try: - filename = self.dspabs +'.user' - self.usrfile = open(filename, 'w') - except IOError as detail: - raise SCons.Errors.InternalError('Unable to open "' + filename + '" for writing:' + str(detail)) - else: - self.UserHeader() - self.UserProject() - self.usrfile.close() - -V9UserHeader = """\ - - -\t -""" - -V9UserConfiguration = """\ -\t\t -\t\t\t -\t\t -""" - -V9DebugSettings = { -'Command':'$(TargetPath)', -'WorkingDirectory': None, -'CommandArguments': None, -'Attach':'false', -'DebuggerType':'3', -'Remote':'1', -'RemoteMachine': None, -'RemoteCommand': None, -'HttpUrl': None, -'PDBPath': None, -'SQLDebugging': None, -'Environment': None, -'EnvironmentMerge':'true', -'DebuggerFlavor': None, -'MPIRunCommand': None, -'MPIRunArguments': None, -'MPIRunWorkingDirectory': None, -'ApplicationCommand': None, -'ApplicationArguments': None, -'ShimCommand': None, -'MPIAcceptMode': None, -'MPIAcceptFilter': None, -} - -class _GenerateV7User(_UserGenerator): - """Generates a Project file for MSVS .NET""" - def __init__(self, dspfile, source, env): - if self.version_num >= 9.0: - self.usrhead = V9UserHeader - self.usrconf = V9UserConfiguration - self.usrdebg = V9DebugSettings - _UserGenerator.__init__(self, dspfile, source, env) - - def UserProject(self): - confkeys = sorted(self.configs.keys()) - for kind in confkeys: - variant = self.configs[kind].variant - platform = self.configs[kind].platform - debug = self.configs[kind].debug - if debug: - debug_settings = '\n'.join(['\t\t\t\t%s="%s"' % (key, xmlify(value)) - for key, value in debug.items() - if value is not None]) - self.usrfile.write(self.usrconf % locals()) - self.usrfile.write('\t\n') - -V10UserHeader = """\ - - -""" - -V10UserConfiguration = """\ -\t -%(debug_settings)s -\t -""" - -V10DebugSettings = { -'LocalDebuggerCommand': None, -'LocalDebuggerCommandArguments': None, -'LocalDebuggerEnvironment': None, -'DebuggerFlavor': 'WindowsLocalDebugger', -'LocalDebuggerWorkingDirectory': None, -'LocalDebuggerAttach': None, -'LocalDebuggerDebuggerType': None, -'LocalDebuggerMergeEnvironment': None, -'LocalDebuggerSQLDebugging': None, -'RemoteDebuggerCommand': None, -'RemoteDebuggerCommandArguments': None, -'RemoteDebuggerWorkingDirectory': None, -'RemoteDebuggerServerName': None, -'RemoteDebuggerConnection': None, -'RemoteDebuggerDebuggerType': None, -'RemoteDebuggerAttach': None, -'RemoteDebuggerSQLDebugging': None, -'DeploymentDirectory': None, -'AdditionalFiles': None, -'RemoteDebuggerDeployDebugCppRuntime': None, -'WebBrowserDebuggerHttpUrl': None, -'WebBrowserDebuggerDebuggerType': None, -'WebServiceDebuggerHttpUrl': None, -'WebServiceDebuggerDebuggerType': None, -'WebServiceDebuggerSQLDebugging': None, -} - -class _GenerateV10User(_UserGenerator): - """Generates a Project'user file for MSVS 2010 or later""" - - def __init__(self, dspfile, source, env): - version_num, suite = msvs_parse_version(env['MSVS_VERSION']) - if version_num >= 14.2: - # Visual Studio 2019 is considered to be version 16. - self.versionstr = '16.0' - elif version_num >= 14.1: - # Visual Studio 2017 is considered to be version 15. - self.versionstr = '15.0' - elif version_num == 14.0: - self.versionstr = '14.0' - else: - self.versionstr = '4.0' - self.usrhead = V10UserHeader - self.usrconf = V10UserConfiguration - self.usrdebg = V10DebugSettings - _UserGenerator.__init__(self, dspfile, source, env) - - def UserProject(self): - confkeys = sorted(self.configs.keys()) - for kind in confkeys: - variant = self.configs[kind].variant - platform = self.configs[kind].platform - debug = self.configs[kind].debug - if debug: - debug_settings = '\n'.join(['\t\t<%s>%s' % (key, xmlify(value), key) - for key, value in debug.items() - if value is not None]) - self.usrfile.write(self.usrconf % locals()) - self.usrfile.write('') - -class _DSPGenerator: - """ Base class for DSP generators """ - - srcargs = [ - 'srcs', - 'incs', - 'localincs', - 'resources', - 'misc'] - - def __init__(self, dspfile, source, env): - self.dspfile = str(dspfile) - try: - get_abspath = dspfile.get_abspath - except AttributeError: - self.dspabs = os.path.abspath(dspfile) - else: - self.dspabs = get_abspath() - - if 'variant' not in env: - raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\ - "'Release') to create an MSVSProject.") - elif SCons.Util.is_String(env['variant']): - variants = [env['variant']] - elif SCons.Util.is_List(env['variant']): - variants = env['variant'] - - if 'buildtarget' not in env or env['buildtarget'] is None: - buildtarget = [''] - elif SCons.Util.is_String(env['buildtarget']): - buildtarget = [env['buildtarget']] - elif SCons.Util.is_List(env['buildtarget']): - if len(env['buildtarget']) != len(variants): - raise SCons.Errors.InternalError("Sizes of 'buildtarget' and 'variant' lists must be the same.") - buildtarget = [] - for bt in env['buildtarget']: - if SCons.Util.is_String(bt): - buildtarget.append(bt) - else: - buildtarget.append(bt.get_abspath()) - else: - buildtarget = [env['buildtarget'].get_abspath()] - if len(buildtarget) == 1: - bt = buildtarget[0] - buildtarget = [] - for _ in variants: - buildtarget.append(bt) - - if 'outdir' not in env or env['outdir'] is None: - outdir = [''] - elif SCons.Util.is_String(env['outdir']): - outdir = [env['outdir']] - elif SCons.Util.is_List(env['outdir']): - if len(env['outdir']) != len(variants): - raise SCons.Errors.InternalError("Sizes of 'outdir' and 'variant' lists must be the same.") - outdir = [] - for s in env['outdir']: - if SCons.Util.is_String(s): - outdir.append(s) - else: - outdir.append(s.get_abspath()) - else: - outdir = [env['outdir'].get_abspath()] - if len(outdir) == 1: - s = outdir[0] - outdir = [] - for v in variants: - outdir.append(s) - - if 'runfile' not in env or env['runfile'] is None: - runfile = buildtarget[-1:] - elif SCons.Util.is_String(env['runfile']): - runfile = [env['runfile']] - elif SCons.Util.is_List(env['runfile']): - if len(env['runfile']) != len(variants): - raise SCons.Errors.InternalError("Sizes of 'runfile' and 'variant' lists must be the same.") - runfile = [] - for s in env['runfile']: - if SCons.Util.is_String(s): - runfile.append(s) - else: - runfile.append(s.get_abspath()) - else: - runfile = [env['runfile'].get_abspath()] - if len(runfile) == 1: - s = runfile[0] - runfile = [] - for v in variants: - runfile.append(s) - - self.sconscript = env['MSVSSCONSCRIPT'] - - def GetKeyFromEnv(env, key, variants): - """ - Retrieves a specific key from the environment. If the key is - present, it is expected to either be a string or a list with length - equal to the number of variants. The function returns a list of - the desired value (e.g. cpp include paths) guaranteed to be of - length equal to the length of the variants list. - """ - if key not in env or env[key] is None: - return [''] * len(variants) - elif SCons.Util.is_String(env[key]): - return [env[key]] * len(variants) - elif SCons.Util.is_List(env[key]): - if len(env[key]) != len(variants): - raise SCons.Errors.InternalError("Sizes of '%s' and 'variant' lists must be the same." % key) - else: - return env[key] - else: - raise SCons.Errors.InternalError("Unsupported type for key '%s' in environment: %s" % - (key, type(env[key]))) - - cmdargs = GetKeyFromEnv(env, 'cmdargs', variants) - - # The caller is allowed to put 'cppdefines' and/or 'cpppaths' in the - # environment, which is useful if they want to provide per-variant - # values for these. Otherwise, we fall back to using the global - # 'CPPDEFINES' and 'CPPPATH' functions. - if 'cppdefines' in env: - cppdefines = GetKeyFromEnv(env, 'cppdefines', variants) - else: - cppdefines = [env.get('CPPDEFINES', [])] * len(variants) - if 'cpppaths' in env: - cpppaths = GetKeyFromEnv(env, 'cpppaths', variants) - else: - cpppaths = [env.get('CPPPATH', [])] * len(variants) - if 'cppflags' in env: - cppflags = GetKeyFromEnv(env, 'cppflags', variants) - else: - cppflags = [env.get('CCFLAGS', []) + env.get('CXXFLAGS', []) + env.get('CPPFLAGS', [])] * len(variants) - - self.env = env - - if 'name' in self.env: - self.name = self.env['name'] - else: - self.name = os.path.basename(SCons.Util.splitext(self.dspfile)[0]) - self.name = self.env.subst(self.name) - - sourcenames = [ - 'Source Files', - 'Header Files', - 'Local Headers', - 'Resource Files', - 'Other Files'] - - self.sources = {} - for n in sourcenames: - self.sources[n] = [] - - self.configs = {} - - self.nokeep = 0 - if 'nokeep' in env and env['variant'] != 0: - self.nokeep = 1 - - if self.nokeep == 0 and os.path.exists(self.dspabs): - self.Parse() - - for t in zip(sourcenames,self.srcargs): - if t[1] in self.env: - if SCons.Util.is_List(self.env[t[1]]): - for i in self.env[t[1]]: - if i not in self.sources[t[0]]: - self.sources[t[0]].append(i) - else: - if not self.env[t[1]] in self.sources[t[0]]: - self.sources[t[0]].append(self.env[t[1]]) - - for n in sourcenames: - self.sources[n].sort(key=lambda a: a.lower()) - - def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, cppdefines, cpppaths, cppflags, dspfile=dspfile, env=env): - config = Config() - config.buildtarget = buildtarget - config.outdir = outdir - config.cmdargs = cmdargs - config.cppdefines = cppdefines - config.cppflags = cppflags - config.runfile = runfile - - # Dir objects can't be pickled, so we need an absolute path here. - config.cpppaths = processIncludes(cpppaths, env, None, None) - - match = re.match(r'(.*)\|(.*)', variant) - if match: - config.variant = match.group(1) - config.platform = match.group(2) - else: - config.variant = variant - config.platform = 'Win32' - - self.configs[variant] = config - # DEBUG: leave enabled, test/MSVS/CPPPATH-dirs.py expects this - print("Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dspfile) + "'") - - for i in range(len(variants)): - AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs[i], cppdefines[i], cpppaths[i], cppflags[i]) - - seen = set() - self.platforms = [p.platform for p in self.configs.values() - if not (p.platform in seen or seen.add(p.platform))] - - - def Build(self): - pass - -V6DSPHeader = """\ -# Microsoft Developer Studio Project File - Name="%(name)s" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) External Target" 0x0106 - -CFG=%(name)s - Win32 %(confkey)s -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "%(name)s.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "%(name)s.mak" CFG="%(name)s - Win32 %(confkey)s" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -""" - -class _GenerateV6DSP(_DSPGenerator): - """Generates a Project file for MSVS 6.0""" - - def PrintHeader(self): - # pick a default config - confkeys = sorted(self.configs.keys()) - - name = self.name - confkey = confkeys[0] - - self.file.write(V6DSPHeader % locals()) - - for kind in confkeys: - self.file.write('!MESSAGE "%s - Win32 %s" (based on "Win32 (x86) External Target")\n' % (name, kind)) - - self.file.write('!MESSAGE\n\n') - - def PrintProject(self): - name = self.name - self.file.write('# Begin Project\n' - '# PROP AllowPerConfigDependencies 0\n' - '# PROP Scc_ProjName ""\n' - '# PROP Scc_LocalPath ""\n\n') - - first = 1 - confkeys = sorted(self.configs.keys()) - for kind in confkeys: - outdir = self.configs[kind].outdir - buildtarget = self.configs[kind].buildtarget - if first == 1: - self.file.write('!IF "$(CFG)" == "%s - Win32 %s"\n\n' % (name, kind)) - first = 0 - else: - self.file.write('\n!ELSEIF "$(CFG)" == "%s - Win32 %s"\n\n' % (name, kind)) - - env_has_buildtarget = 'MSVSBUILDTARGET' in self.env - if not env_has_buildtarget: - self.env['MSVSBUILDTARGET'] = buildtarget - - # have to write this twice, once with the BASE settings, and once without - for base in ("BASE ",""): - self.file.write('# PROP %sUse_MFC 0\n' - '# PROP %sUse_Debug_Libraries ' % (base, base)) - if 'debug' not in kind.lower(): - self.file.write('0\n') - else: - self.file.write('1\n') - self.file.write('# PROP %sOutput_Dir "%s"\n' - '# PROP %sIntermediate_Dir "%s"\n' % (base,outdir,base,outdir)) - cmd = 'echo Starting SCons && ' + self.env.subst('$MSVSBUILDCOM', 1) - self.file.write('# PROP %sCmd_Line "%s"\n' - '# PROP %sRebuild_Opt "-c && %s"\n' - '# PROP %sTarget_File "%s"\n' - '# PROP %sBsc_Name ""\n' - '# PROP %sTarget_Dir ""\n'\ - %(base,cmd,base,cmd,base,buildtarget,base,base)) - - if not env_has_buildtarget: - del self.env['MSVSBUILDTARGET'] - - self.file.write('\n!ENDIF\n\n' - '# Begin Target\n\n') - for kind in confkeys: - self.file.write('# Name "%s - Win32 %s"\n' % (name,kind)) - self.file.write('\n') - first = 0 - for kind in confkeys: - if first == 0: - self.file.write('!IF "$(CFG)" == "%s - Win32 %s"\n\n' % (name,kind)) - first = 1 - else: - self.file.write('!ELSEIF "$(CFG)" == "%s - Win32 %s"\n\n' % (name,kind)) - self.file.write('!ENDIF\n\n') - self.PrintSourceFiles() - self.file.write('# End Target\n' - '# End Project\n') - - if self.nokeep == 0: - # now we pickle some data and add it to the file -- MSDEV will ignore it. - pdata = pickle.dumps(self.configs,PICKLE_PROTOCOL) - pdata = base64.b64encode(pdata).decode() - self.file.write(pdata + '\n') - pdata = pickle.dumps(self.sources,PICKLE_PROTOCOL) - pdata = base64.b64encode(pdata).decode() - self.file.write(pdata + '\n') - - def PrintSourceFiles(self): - categories = {'Source Files': 'cpp|c|cxx|l|y|def|odl|idl|hpj|bat', - 'Header Files': 'h|hpp|hxx|hm|inl', - 'Local Headers': 'h|hpp|hxx|hm|inl', - 'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe', - 'Other Files': ''} - - for kind in sorted(categories.keys(), key=lambda a: a.lower()): - if not self.sources[kind]: - continue # skip empty groups - - self.file.write('# Begin Group "' + kind + '"\n\n') - typelist = categories[kind].replace('|', ';') - self.file.write('# PROP Default_Filter "' + typelist + '"\n') - - for file in self.sources[kind]: - file = os.path.normpath(file) - self.file.write('# Begin Source File\n\n' - 'SOURCE="' + file + '"\n' - '# End Source File\n') - self.file.write('# End Group\n') - - # add the SConscript file outside of the groups - self.file.write('# Begin Source File\n\n' - 'SOURCE="' + str(self.sconscript) + '"\n' - '# End Source File\n') - - def Parse(self): - try: - dspfile = open(self.dspabs,'r') - except IOError: - return # doesn't exist yet, so can't add anything to configs. - - line = dspfile.readline() - # skip until marker - while line: - if "# End Project" in line: - break - line = dspfile.readline() - - # read to get configs - line = dspfile.readline() - datas = line - while line and line != '\n': - line = dspfile.readline() - datas = datas + line - - # OK, we've found our little pickled cache of data. - try: - datas = base64.decodestring(datas) - data = pickle.loads(datas) - except KeyboardInterrupt: - raise - except: - return # unable to unpickle any data for some reason - - self.configs.update(data) - - # keep reading to get sources - data = None - line = dspfile.readline() - datas = line - while line and line != '\n': - line = dspfile.readline() - datas = datas + line - dspfile.close() - - # OK, we've found our little pickled cache of data. - # it has a "# " in front of it, so we strip that. - try: - datas = base64.decodestring(datas) - data = pickle.loads(datas) - except KeyboardInterrupt: - raise - except: - return # unable to unpickle any data for some reason - - self.sources.update(data) - - def Build(self): - try: - self.file = open(self.dspabs,'w') - except IOError as detail: - raise SCons.Errors.InternalError('Unable to open "' + self.dspabs + '" for writing:' + str(detail)) - else: - self.PrintHeader() - self.PrintProject() - self.file.close() - -V7DSPHeader = """\ - - -""" - -V7DSPConfiguration = """\ -\t\t -\t\t\t -\t\t -""" - -V8DSPHeader = """\ - - -""" - -V8DSPConfiguration = """\ -\t\t -\t\t\t -\t\t -""" -class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): - """Generates a Project file for MSVS .NET""" - - def __init__(self, dspfile, source, env): - _DSPGenerator.__init__(self, dspfile, source, env) - self.version = env['MSVS_VERSION'] - self.version_num, self.suite = msvs_parse_version(self.version) - if self.version_num >= 9.0: - self.versionstr = '9.00' - self.dspheader = V8DSPHeader - self.dspconfiguration = V8DSPConfiguration - elif self.version_num >= 8.0: - self.versionstr = '8.00' - self.dspheader = V8DSPHeader - self.dspconfiguration = V8DSPConfiguration - else: - if self.version_num >= 7.1: - self.versionstr = '7.10' - else: - self.versionstr = '7.00' - self.dspheader = V7DSPHeader - self.dspconfiguration = V7DSPConfiguration - self.file = None - - _GenerateV7User.__init__(self, dspfile, source, env) - - def PrintHeader(self): - env = self.env - versionstr = self.versionstr - name = self.name - encoding = self.env.subst('$MSVSENCODING') - scc_provider = env.get('MSVS_SCC_PROVIDER', '') - scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '') - scc_aux_path = env.get('MSVS_SCC_AUX_PATH', '') - # MSVS_SCC_LOCAL_PATH is kept for backwards compatibility purpose and should - # be deprecated as soon as possible. - scc_local_path_legacy = env.get('MSVS_SCC_LOCAL_PATH', '') - scc_connection_root = env.get('MSVS_SCC_CONNECTION_ROOT', os.curdir) - scc_local_path = os.path.relpath(scc_connection_root, os.path.dirname(self.dspabs)) - project_guid = env.get('MSVS_PROJECT_GUID', '') - if not project_guid: - project_guid = _generateGUID(self.dspfile, '') - if scc_provider != '': - scc_attrs = '\tSccProjectName="%s"\n' % scc_project_name - if scc_aux_path != '': - scc_attrs += '\tSccAuxPath="%s"\n' % scc_aux_path - scc_attrs += ('\tSccLocalPath="%s"\n' - '\tSccProvider="%s"' % (scc_local_path, scc_provider)) - elif scc_local_path_legacy != '': - # This case is kept for backwards compatibility purpose and should - # be deprecated as soon as possible. - scc_attrs = ('\tSccProjectName="%s"\n' - '\tSccLocalPath="%s"' % (scc_project_name, scc_local_path_legacy)) - else: - self.dspheader = self.dspheader.replace('%(scc_attrs)s\n', '') - - self.file.write(self.dspheader % locals()) - - self.file.write('\t\n') - for platform in self.platforms: - self.file.write( - '\t\t\n' % platform) - self.file.write('\t\n') - - if self.version_num >= 8.0: - self.file.write('\t\n' - '\t\n') - - def PrintProject(self): - self.file.write('\t\n') - - confkeys = sorted(self.configs.keys()) - for kind in confkeys: - variant = self.configs[kind].variant - platform = self.configs[kind].platform - outdir = self.configs[kind].outdir - buildtarget = self.configs[kind].buildtarget - runfile = self.configs[kind].runfile - cmdargs = self.configs[kind].cmdargs - cpppaths = self.configs[kind].cpppaths - cppdefines = self.configs[kind].cppdefines - - env_has_buildtarget = 'MSVSBUILDTARGET' in self.env - if not env_has_buildtarget: - self.env['MSVSBUILDTARGET'] = buildtarget - - starting = 'echo Starting SCons && ' - if cmdargs: - cmdargs = ' ' + cmdargs - else: - cmdargs = '' - buildcmd = xmlify(starting + self.env.subst('$MSVSBUILDCOM', 1) + cmdargs) - rebuildcmd = xmlify(starting + self.env.subst('$MSVSREBUILDCOM', 1) + cmdargs) - cleancmd = xmlify(starting + self.env.subst('$MSVSCLEANCOM', 1) + cmdargs) - - # This isn't perfect; CPPDEFINES and CPPPATH can contain $TARGET and $SOURCE, - # so they could vary depending on the command being generated. This code - # assumes they don't. - preprocdefs = xmlify(';'.join(processDefines(cppdefines))) - includepath = xmlify(';'.join(processIncludes(cpppaths, self.env, None, None))) - - if not env_has_buildtarget: - del self.env['MSVSBUILDTARGET'] - - self.file.write(self.dspconfiguration % locals()) - - self.file.write('\t\n') - - if self.version_num >= 7.1: - self.file.write('\t\n' - '\t\n') - - self.PrintSourceFiles() - - self.file.write('\n') - - if self.nokeep == 0: - # now we pickle some data and add it to the file -- MSDEV will ignore it. - pdata = pickle.dumps(self.configs,PICKLE_PROTOCOL) - pdata = base64.b64encode(pdata).decode() - self.file.write('\n') - - def printSources(self, hierarchy, commonprefix): - sorteditems = sorted(hierarchy.items(), key=lambda a: a[0].lower()) - - # First folders, then files - for key, value in sorteditems: - if SCons.Util.is_Dict(value): - self.file.write('\t\t\t\n' % key) - self.printSources(value, commonprefix) - self.file.write('\t\t\t\n') - - for key, value in sorteditems: - if SCons.Util.is_String(value): - file = value - if commonprefix: - file = os.path.join(commonprefix, value) - file = os.path.normpath(file) - self.file.write('\t\t\t\n' - '\t\t\t\n' % file) - - def PrintSourceFiles(self): - categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', - 'Header Files': 'h;hpp;hxx;hm;inl', - 'Local Headers': 'h;hpp;hxx;hm;inl', - 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', - 'Other Files': ''} - - self.file.write('\t\n') - - cats = sorted([k for k in categories.keys() if self.sources[k]], - key=lambda a: a.lower()) - for kind in cats: - if len(cats) > 1: - self.file.write('\t\t\n' % (kind, categories[kind])) - - sources = self.sources[kind] - - # First remove any common prefix - commonprefix = None - s = list(map(os.path.normpath, sources)) - # take the dirname because the prefix may include parts - # of the filenames (e.g. if you have 'dir\abcd' and - # 'dir\acde' then the cp will be 'dir\a' ) - cp = os.path.dirname( os.path.commonprefix(s) ) - if cp and s[0][len(cp)] == os.sep: - # +1 because the filename starts after the separator - sources = [s[len(cp)+1:] for s in sources] - commonprefix = cp - - hierarchy = makeHierarchy(sources) - self.printSources(hierarchy, commonprefix=commonprefix) - - if len(cats)>1: - self.file.write('\t\t\n') - - # add the SConscript file outside of the groups - self.file.write('\t\t\n' - '\t\t\n' % str(self.sconscript)) - - self.file.write('\t\n' - '\t\n' - '\t\n') - - def Parse(self): - try: - dspfile = open(self.dspabs,'r') - except IOError: - return # doesn't exist yet, so can't add anything to configs. - - line = dspfile.readline() - # skip until marker - while line: - if '\n') - - def printFilters(self, hierarchy, name): - sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) - - for key, value in sorteditems: - if SCons.Util.is_Dict(value): - filter_name = name + '\\' + key - self.filters_file.write('\t\t\n' - '\t\t\t%s\n' - '\t\t\n' % (filter_name, _generateGUID(self.dspabs, filter_name))) - self.printFilters(value, filter_name) - - def printSources(self, hierarchy, kind, commonprefix, filter_name): - keywords = {'Source Files': 'ClCompile', - 'Header Files': 'ClInclude', - 'Local Headers': 'ClInclude', - 'Resource Files': 'None', - 'Other Files': 'None'} - - sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) - - # First folders, then files - for key, value in sorteditems: - if SCons.Util.is_Dict(value): - self.printSources(value, kind, commonprefix, filter_name + '\\' + key) - - for key, value in sorteditems: - if SCons.Util.is_String(value): - file = value - if commonprefix: - file = os.path.join(commonprefix, value) - file = os.path.normpath(file) - - self.file.write('\t\t<%s Include="%s" />\n' % (keywords[kind], file)) - self.filters_file.write('\t\t<%s Include="%s">\n' - '\t\t\t%s\n' - '\t\t\n' % (keywords[kind], file, filter_name, keywords[kind])) - - def PrintSourceFiles(self): - categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', - 'Header Files': 'h;hpp;hxx;hm;inl', - 'Local Headers': 'h;hpp;hxx;hm;inl', - 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', - 'Other Files': ''} - - cats = sorted([k for k in categories.keys() if self.sources[k]], - key = lambda a: a.lower()) - - # print vcxproj.filters file first - self.filters_file.write('\t\n') - for kind in cats: - self.filters_file.write('\t\t\n' - '\t\t\t{7b42d31d-d53c-4868-8b92-ca2bc9fc052f}\n' - '\t\t\t%s\n' - '\t\t\n' % (kind, categories[kind])) - - # First remove any common prefix - sources = self.sources[kind] - commonprefix = None - s = list(map(os.path.normpath, sources)) - # take the dirname because the prefix may include parts - # of the filenames (e.g. if you have 'dir\abcd' and - # 'dir\acde' then the cp will be 'dir\a' ) - cp = os.path.dirname( os.path.commonprefix(s) ) - if cp and s[0][len(cp)] == os.sep: - # +1 because the filename starts after the separator - sources = [s[len(cp)+1:] for s in sources] - commonprefix = cp - - hierarchy = makeHierarchy(sources) - self.printFilters(hierarchy, kind) - - self.filters_file.write('\t\n') - - # then print files and filters - for kind in cats: - self.file.write('\t\n') - self.filters_file.write('\t\n') - - # First remove any common prefix - sources = self.sources[kind] - commonprefix = None - s = list(map(os.path.normpath, sources)) - # take the dirname because the prefix may include parts - # of the filenames (e.g. if you have 'dir\abcd' and - # 'dir\acde' then the cp will be 'dir\a' ) - cp = os.path.dirname( os.path.commonprefix(s) ) - if cp and s[0][len(cp)] == os.sep: - # +1 because the filename starts after the separator - sources = [s[len(cp)+1:] for s in sources] - commonprefix = cp - - hierarchy = makeHierarchy(sources) - self.printSources(hierarchy, kind, commonprefix, kind) - - self.file.write('\t\n') - self.filters_file.write('\t\n') - - # add the SConscript file outside of the groups - self.file.write('\t\n' - '\t\t\n' - #'\t\t\n' - '\t\n' % str(self.sconscript)) - - def Parse(self): - # DEBUG - # print("_GenerateV10DSP.Parse()") - pass - - def Build(self): - try: - self.file = open(self.dspabs, 'w') - except IOError as detail: - raise SCons.Errors.InternalError('Unable to open "' + self.dspabs + '" for writing:' + str(detail)) - else: - self.PrintHeader() - self.PrintProject() - self.file.close() - - _GenerateV10User.Build(self) - -class _DSWGenerator: - """ Base class for DSW generators """ - def __init__(self, dswfile, source, env): - self.dswfile = os.path.normpath(str(dswfile)) - self.dsw_folder_path = os.path.dirname(os.path.abspath(self.dswfile)) - self.env = env - - if 'projects' not in env: - raise SCons.Errors.UserError("You must specify a 'projects' argument to create an MSVSSolution.") - projects = env['projects'] - if not SCons.Util.is_List(projects): - raise SCons.Errors.InternalError("The 'projects' argument must be a list of nodes.") - projects = SCons.Util.flatten(projects) - if len(projects) < 1: - raise SCons.Errors.UserError("You must specify at least one project to create an MSVSSolution.") - self.dspfiles = list(map(str, projects)) - - if 'name' in self.env: - self.name = self.env['name'] - else: - self.name = os.path.basename(SCons.Util.splitext(self.dswfile)[0]) - self.name = self.env.subst(self.name) - - def Build(self): - pass - -class _GenerateV7DSW(_DSWGenerator): - """Generates a Solution file for MSVS .NET""" - def __init__(self, dswfile, source, env): - _DSWGenerator.__init__(self, dswfile, source, env) - - self.file = None - self.version = self.env['MSVS_VERSION'] - self.version_num, self.suite = msvs_parse_version(self.version) - self.versionstr = '7.00' - if self.version_num >= 11.0: - self.versionstr = '12.00' - elif self.version_num >= 10.0: - self.versionstr = '11.00' - elif self.version_num >= 9.0: - self.versionstr = '10.00' - elif self.version_num >= 8.0: - self.versionstr = '9.00' - elif self.version_num >= 7.1: - self.versionstr = '8.00' - - if 'slnguid' in env and env['slnguid']: - self.slnguid = env['slnguid'] - else: - self.slnguid = _generateGUID(dswfile, self.name) - - self.configs = {} - - self.nokeep = 0 - if 'nokeep' in env and env['variant'] != 0: - self.nokeep = 1 - - if self.nokeep == 0 and os.path.exists(self.dswfile): - self.Parse() - - def AddConfig(self, variant, dswfile=dswfile): - config = Config() - - match = re.match(r'(.*)\|(.*)', variant) - if match: - config.variant = match.group(1) - config.platform = match.group(2) - else: - config.variant = variant - config.platform = 'Win32' - - self.configs[variant] = config - # DEBUG - # print("Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dswfile) + "'") - - if 'variant' not in env: - raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\ - "'Release') to create an MSVS Solution File.") - elif SCons.Util.is_String(env['variant']): - AddConfig(self, env['variant']) - elif SCons.Util.is_List(env['variant']): - for variant in env['variant']: - AddConfig(self, variant) - - seen = set() - self.platforms = [p.platform for p in self.configs.values() - if not (p.platform in seen or seen.add(p.platform))] - - def GenerateProjectFilesInfo(self): - for dspfile in self.dspfiles: - dsp_folder_path, name = os.path.split(dspfile) - dsp_folder_path = os.path.abspath(dsp_folder_path) - if SCons.Util.splitext(name)[1] == '.filters': - # Ignore .filters project files - continue - dsp_relative_folder_path = os.path.relpath(dsp_folder_path, self.dsw_folder_path) - if dsp_relative_folder_path == os.curdir: - dsp_relative_file_path = name - else: - dsp_relative_file_path = os.path.join(dsp_relative_folder_path, name) - dspfile_info = {'NAME': name, - 'GUID': _generateGUID(dspfile, ''), - 'FOLDER_PATH': dsp_folder_path, - 'FILE_PATH': dspfile, - 'SLN_RELATIVE_FOLDER_PATH': dsp_relative_folder_path, - 'SLN_RELATIVE_FILE_PATH': dsp_relative_file_path} - self.dspfiles_info.append(dspfile_info) - - self.dspfiles_info = [] - GenerateProjectFilesInfo(self) - - def Parse(self): - try: - dswfile = open(self.dswfile,'r') - except IOError: - return # doesn't exist yet, so can't add anything to configs. - - line = dswfile.readline() - while line: - if line[:9] == "EndGlobal": - break - line = dswfile.readline() - - line = dswfile.readline() - datas = line - while line: - line = dswfile.readline() - datas = datas + line - dswfile.close() - - # OK, we've found our little pickled cache of data. - try: - datas = base64.decodestring(datas) - data = pickle.loads(datas) - except KeyboardInterrupt: - raise - except: - return # unable to unpickle any data for some reason - - self.configs.update(data) - - def PrintSolution(self): - """Writes a solution file""" - self.file.write('Microsoft Visual Studio Solution File, Format Version %s\n' % self.versionstr) - if self.version_num >= 14.2: - # Visual Studio 2019 is considered to be version 16. - self.file.write('# Visual Studio 16\n') - elif self.version_num > 14.0: - # Visual Studio 2015 and 2017 are both considered to be version 15. - self.file.write('# Visual Studio 15\n') - elif self.version_num >= 12.0: - self.file.write('# Visual Studio 14\n') - elif self.version_num >= 11.0: - self.file.write('# Visual Studio 11\n') - elif self.version_num >= 10.0: - self.file.write('# Visual Studio 2010\n') - elif self.version_num >= 9.0: - self.file.write('# Visual Studio 2008\n') - elif self.version_num >= 8.0: - self.file.write('# Visual Studio 2005\n') - - for dspinfo in self.dspfiles_info: - name = dspinfo['NAME'] - base, suffix = SCons.Util.splitext(name) - if suffix == '.vcproj': - name = base - self.file.write('Project("%s") = "%s", "%s", "%s"\n' - % (external_makefile_guid, name, dspinfo['SLN_RELATIVE_FILE_PATH'], dspinfo['GUID'])) - if 7.1 <= self.version_num < 8.0: - self.file.write('\tProjectSection(ProjectDependencies) = postProject\n' - '\tEndProjectSection\n') - self.file.write('EndProject\n') - - self.file.write('Global\n') - - env = self.env - if 'MSVS_SCC_PROVIDER' in env: - scc_number_of_projects = len(self.dspfiles) + 1 - slnguid = self.slnguid - scc_provider = env.get('MSVS_SCC_PROVIDER', '').replace(' ', r'\u0020') - scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '').replace(' ', r'\u0020') - scc_connection_root = env.get('MSVS_SCC_CONNECTION_ROOT', os.curdir) - scc_local_path = os.path.relpath(scc_connection_root, self.dsw_folder_path).replace('\\', '\\\\') - self.file.write('\tGlobalSection(SourceCodeControl) = preSolution\n' - '\t\tSccNumberOfProjects = %(scc_number_of_projects)d\n' - '\t\tSccProjectName0 = %(scc_project_name)s\n' - '\t\tSccLocalPath0 = %(scc_local_path)s\n' - '\t\tSccProvider0 = %(scc_provider)s\n' - '\t\tCanCheckoutShared = true\n' % locals()) - sln_relative_path_from_scc = os.path.relpath(self.dsw_folder_path, scc_connection_root) - if sln_relative_path_from_scc != os.curdir: - self.file.write('\t\tSccProjectFilePathRelativizedFromConnection0 = %s\\\\\n' - % sln_relative_path_from_scc.replace('\\', '\\\\')) - if self.version_num < 8.0: - # When present, SolutionUniqueID is automatically removed by VS 2005 - # TODO: check for Visual Studio versions newer than 2005 - self.file.write('\t\tSolutionUniqueID = %s\n' % slnguid) - for dspinfo in self.dspfiles_info: - i = self.dspfiles_info.index(dspinfo) + 1 - dsp_relative_file_path = dspinfo['SLN_RELATIVE_FILE_PATH'].replace('\\', '\\\\') - dsp_scc_relative_folder_path = os.path.relpath(dspinfo['FOLDER_PATH'], scc_connection_root).replace('\\', '\\\\') - self.file.write('\t\tSccProjectUniqueName%(i)s = %(dsp_relative_file_path)s\n' - '\t\tSccLocalPath%(i)d = %(scc_local_path)s\n' - '\t\tCanCheckoutShared = true\n' - '\t\tSccProjectFilePathRelativizedFromConnection%(i)s = %(dsp_scc_relative_folder_path)s\\\\\n' - % locals()) - self.file.write('\tEndGlobalSection\n') - if self.version_num >= 8.0: - self.file.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n') - else: - self.file.write('\tGlobalSection(SolutionConfiguration) = preSolution\n') - - confkeys = sorted(self.configs.keys()) - cnt = 0 - for name in confkeys: - variant = self.configs[name].variant - platform = self.configs[name].platform - if self.version_num >= 8.0: - self.file.write('\t\t%s|%s = %s|%s\n' % (variant, platform, variant, platform)) - else: - self.file.write('\t\tConfigName.%d = %s\n' % (cnt, variant)) - cnt = cnt + 1 - self.file.write('\tEndGlobalSection\n') - if self.version_num <= 7.1: - self.file.write('\tGlobalSection(ProjectDependencies) = postSolution\n' - '\tEndGlobalSection\n') - if self.version_num >= 8.0: - self.file.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n') - else: - self.file.write('\tGlobalSection(ProjectConfiguration) = postSolution\n') - - for name in confkeys: - variant = self.configs[name].variant - platform = self.configs[name].platform - if self.version_num >= 8.0: - for dspinfo in self.dspfiles_info: - guid = dspinfo['GUID'] - self.file.write('\t\t%s.%s|%s.ActiveCfg = %s|%s\n' - '\t\t%s.%s|%s.Build.0 = %s|%s\n' % (guid,variant,platform,variant,platform,guid,variant,platform,variant,platform)) - else: - for dspinfo in self.dspfiles_info: - guid = dspinfo['GUID'] - self.file.write('\t\t%s.%s.ActiveCfg = %s|%s\n' - '\t\t%s.%s.Build.0 = %s|%s\n' %(guid,variant,variant,platform,guid,variant,variant,platform)) - - self.file.write('\tEndGlobalSection\n') - - if self.version_num >= 8.0: - self.file.write('\tGlobalSection(SolutionProperties) = preSolution\n' - '\t\tHideSolutionNode = FALSE\n' - '\tEndGlobalSection\n') - else: - self.file.write('\tGlobalSection(ExtensibilityGlobals) = postSolution\n' - '\tEndGlobalSection\n' - '\tGlobalSection(ExtensibilityAddIns) = postSolution\n' - '\tEndGlobalSection\n') - self.file.write('EndGlobal\n') - if self.nokeep == 0: - pdata = pickle.dumps(self.configs,PICKLE_PROTOCOL) - pdata = base64.b64encode(pdata).decode() - self.file.write(pdata) - self.file.write('\n') - - def Build(self): - try: - self.file = open(self.dswfile,'w') - except IOError as detail: - raise SCons.Errors.InternalError('Unable to open "' + self.dswfile + '" for writing:' + str(detail)) - else: - self.PrintSolution() - self.file.close() - -V6DSWHeader = """\ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "%(name)s"="%(dspfile)s" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### -""" - -class _GenerateV6DSW(_DSWGenerator): - """Generates a Workspace file for MSVS 6.0""" - - def PrintWorkspace(self): - """ writes a DSW file """ - name = self.name - dspfile = os.path.relpath(self.dspfiles[0], self.dsw_folder_path) - self.file.write(V6DSWHeader % locals()) - - def Build(self): - try: - self.file = open(self.dswfile,'w') - except IOError as detail: - raise SCons.Errors.InternalError('Unable to open "' + self.dswfile + '" for writing:' + str(detail)) - else: - self.PrintWorkspace() - self.file.close() - - -def GenerateDSP(dspfile, source, env): - """Generates a Project file based on the version of MSVS that is being used""" - - version_num = 6.0 - if 'MSVS_VERSION' in env: - version_num, suite = msvs_parse_version(env['MSVS_VERSION']) - if version_num >= 10.0: - g = _GenerateV10DSP(dspfile, source, env) - g.Build() - elif version_num >= 7.0: - g = _GenerateV7DSP(dspfile, source, env) - g.Build() - else: - g = _GenerateV6DSP(dspfile, source, env) - g.Build() - -def GenerateDSW(dswfile, source, env): - """Generates a Solution/Workspace file based on the version of MSVS that is being used""" - - version_num = 6.0 - if 'MSVS_VERSION' in env: - version_num, suite = msvs_parse_version(env['MSVS_VERSION']) - if version_num >= 7.0: - g = _GenerateV7DSW(dswfile, source, env) - g.Build() - else: - g = _GenerateV6DSW(dswfile, source, env) - g.Build() - - -############################################################################## -# Above here are the classes and functions for generation of -# DSP/DSW/SLN/VCPROJ files. -############################################################################## - -def GetMSVSProjectSuffix(target, source, env, for_signature): - return env['MSVS']['PROJECTSUFFIX'] - -def GetMSVSSolutionSuffix(target, source, env, for_signature): - return env['MSVS']['SOLUTIONSUFFIX'] - -def GenerateProject(target, source, env): - # generate the dsp file, according to the version of MSVS. - builddspfile = target[0] - dspfile = builddspfile.srcnode() - - # this detects whether or not we're using a VariantDir - if dspfile is not builddspfile: - try: - bdsp = open(str(builddspfile), "w+") - except IOError as detail: - print('Unable to open "' + str(dspfile) + '" for writing:',detail,'\n') - raise - - bdsp.write("This is just a placeholder file.\nThe real project file is here:\n%s\n" % dspfile.get_abspath()) - bdsp.close() - - GenerateDSP(dspfile, source, env) - - if env.get('auto_build_solution', 1): - builddswfile = target[1] - dswfile = builddswfile.srcnode() - - if dswfile is not builddswfile: - - try: - bdsw = open(str(builddswfile), "w+") - except IOError as detail: - print('Unable to open "' + str(dspfile) + '" for writing:',detail,'\n') - raise - - bdsw.write("This is just a placeholder file.\nThe real workspace file is here:\n%s\n" % dswfile.get_abspath()) - bdsw.close() - - GenerateDSW(dswfile, source, env) - -def GenerateSolution(target, source, env): - GenerateDSW(target[0], source, env) - -def projectEmitter(target, source, env): - """Sets up the DSP dependencies.""" - - # todo: Not sure what sets source to what user has passed as target, - # but this is what happens. When that is fixed, we also won't have - # to make the user always append env['MSVSPROJECTSUFFIX'] to target. - if source[0] == target[0]: - source = [] - - # make sure the suffix is correct for the version of MSVS we're running. - (base, suff) = SCons.Util.splitext(str(target[0])) - suff = env.subst('$MSVSPROJECTSUFFIX') - target[0] = base + suff - - if not source: - source = 'prj_inputs:' - source = source + env.subst('$MSVSSCONSCOM', 1) - source = source + env.subst('$MSVSENCODING', 1) - - # Project file depends on CPPDEFINES and CPPPATH - preprocdefs = xmlify(';'.join(processDefines(env.get('CPPDEFINES', [])))) - includepath = xmlify(';'.join(processIncludes(env.get('CPPPATH', []), env, None, None))) - source = source + "; ppdefs:%s incpath:%s"%(preprocdefs, includepath) - - if 'buildtarget' in env and env['buildtarget'] is not None: - if SCons.Util.is_String(env['buildtarget']): - source = source + ' "%s"' % env['buildtarget'] - elif SCons.Util.is_List(env['buildtarget']): - for bt in env['buildtarget']: - if SCons.Util.is_String(bt): - source = source + ' "%s"' % bt - else: - try: source = source + ' "%s"' % bt.get_abspath() - except AttributeError: raise SCons.Errors.InternalError("buildtarget can be a string, a node, a list of strings or nodes, or None") - else: - try: source = source + ' "%s"' % env['buildtarget'].get_abspath() - except AttributeError: raise SCons.Errors.InternalError("buildtarget can be a string, a node, a list of strings or nodes, or None") - - if 'outdir' in env and env['outdir'] is not None: - if SCons.Util.is_String(env['outdir']): - source = source + ' "%s"' % env['outdir'] - elif SCons.Util.is_List(env['outdir']): - for s in env['outdir']: - if SCons.Util.is_String(s): - source = source + ' "%s"' % s - else: - try: source = source + ' "%s"' % s.get_abspath() - except AttributeError: raise SCons.Errors.InternalError("outdir can be a string, a node, a list of strings or nodes, or None") - else: - try: source = source + ' "%s"' % env['outdir'].get_abspath() - except AttributeError: raise SCons.Errors.InternalError("outdir can be a string, a node, a list of strings or nodes, or None") - - if 'name' in env: - if SCons.Util.is_String(env['name']): - source = source + ' "%s"' % env['name'] - else: - raise SCons.Errors.InternalError("name must be a string") - - if 'variant' in env: - if SCons.Util.is_String(env['variant']): - source = source + ' "%s"' % env['variant'] - elif SCons.Util.is_List(env['variant']): - for variant in env['variant']: - if SCons.Util.is_String(variant): - source = source + ' "%s"' % variant - else: - raise SCons.Errors.InternalError("name must be a string or a list of strings") - else: - raise SCons.Errors.InternalError("variant must be a string or a list of strings") - else: - raise SCons.Errors.InternalError("variant must be specified") - - for s in _DSPGenerator.srcargs: - if s in env: - if SCons.Util.is_String(env[s]): - source = source + ' "%s' % env[s] - elif SCons.Util.is_List(env[s]): - for t in env[s]: - if SCons.Util.is_String(t): - source = source + ' "%s"' % t - else: - raise SCons.Errors.InternalError(s + " must be a string or a list of strings") - else: - raise SCons.Errors.InternalError(s + " must be a string or a list of strings") - - source = source + ' "%s"' % str(target[0]) - source = [SCons.Node.Python.Value(source)] - - targetlist = [target[0]] - sourcelist = source - - if env.get('auto_build_solution', 1): - env['projects'] = [env.File(t).srcnode() for t in targetlist] - t, s = solutionEmitter(target, target, env) - targetlist = targetlist + t - - # Beginning with Visual Studio 2010 for each project file (.vcxproj) we have additional file (.vcxproj.filters) - version_num = 6.0 - if 'MSVS_VERSION' in env: - version_num, suite = msvs_parse_version(env['MSVS_VERSION']) - if version_num >= 10.0: - targetlist.append(targetlist[0] + '.filters') - - return (targetlist, sourcelist) - -def solutionEmitter(target, source, env): - """Sets up the DSW dependencies.""" - - # todo: Not sure what sets source to what user has passed as target, - # but this is what happens. When that is fixed, we also won't have - # to make the user always append env['MSVSSOLUTIONSUFFIX'] to target. - if source[0] == target[0]: - source = [] - - # make sure the suffix is correct for the version of MSVS we're running. - (base, suff) = SCons.Util.splitext(str(target[0])) - suff = env.subst('$MSVSSOLUTIONSUFFIX') - target[0] = base + suff - - if not source: - source = 'sln_inputs:' - - if 'name' in env: - if SCons.Util.is_String(env['name']): - source = source + ' "%s"' % env['name'] - else: - raise SCons.Errors.InternalError("name must be a string") - - if 'variant' in env: - if SCons.Util.is_String(env['variant']): - source = source + ' "%s"' % env['variant'] - elif SCons.Util.is_List(env['variant']): - for variant in env['variant']: - if SCons.Util.is_String(variant): - source = source + ' "%s"' % variant - else: - raise SCons.Errors.InternalError("name must be a string or a list of strings") - else: - raise SCons.Errors.InternalError("variant must be a string or a list of strings") - else: - raise SCons.Errors.InternalError("variant must be specified") - - if 'slnguid' in env: - if SCons.Util.is_String(env['slnguid']): - source = source + ' "%s"' % env['slnguid'] - else: - raise SCons.Errors.InternalError("slnguid must be a string") - - if 'projects' in env: - if SCons.Util.is_String(env['projects']): - source = source + ' "%s"' % env['projects'] - elif SCons.Util.is_List(env['projects']): - for t in env['projects']: - if SCons.Util.is_String(t): - source = source + ' "%s"' % t - - source = source + ' "%s"' % str(target[0]) - source = [SCons.Node.Python.Value(source)] - - return ([target[0]], source) - -projectAction = SCons.Action.Action(GenerateProject, None) - -solutionAction = SCons.Action.Action(GenerateSolution, None) - -projectBuilder = SCons.Builder.Builder(action = '$MSVSPROJECTCOM', - suffix = '$MSVSPROJECTSUFFIX', - emitter = projectEmitter) - -solutionBuilder = SCons.Builder.Builder(action = '$MSVSSOLUTIONCOM', - suffix = '$MSVSSOLUTIONSUFFIX', - emitter = solutionEmitter) - -default_MSVS_SConscript = None - -def generate(env): - """Add Builders and construction variables for Microsoft Visual - Studio project files to an Environment.""" - try: - env['BUILDERS']['MSVSProject'] - except KeyError: - env['BUILDERS']['MSVSProject'] = projectBuilder - - try: - env['BUILDERS']['MSVSSolution'] - except KeyError: - env['BUILDERS']['MSVSSolution'] = solutionBuilder - - env['MSVSPROJECTCOM'] = projectAction - env['MSVSSOLUTIONCOM'] = solutionAction - - if SCons.Script.call_stack: - # XXX Need to find a way to abstract this; the build engine - # shouldn't depend on anything in SCons.Script. - env['MSVSSCONSCRIPT'] = SCons.Script.call_stack[0].sconscript - else: - global default_MSVS_SConscript - if default_MSVS_SConscript is None: - default_MSVS_SConscript = env.File('SConstruct') - env['MSVSSCONSCRIPT'] = default_MSVS_SConscript - - # Allow consumers to provide their own versions of MSVSSCONS and - # MSVSSCONSFLAGS. This helps support consumers who use wrapper scripts to - # invoke scons. - if 'MSVSSCONS' not in env: - env['MSVSSCONS'] = '"%s" -c "%s"' % (python_executable, getExecScriptMain(env)) - if 'MSVSSCONSFLAGS' not in env: - env['MSVSSCONSFLAGS'] = '-C "${MSVSSCONSCRIPT.dir.get_abspath()}" -f ${MSVSSCONSCRIPT.name}' - - env['MSVSSCONSCOM'] = '$MSVSSCONS $MSVSSCONSFLAGS' - env['MSVSBUILDCOM'] = '$MSVSSCONSCOM "$MSVSBUILDTARGET"' - env['MSVSREBUILDCOM'] = '$MSVSSCONSCOM "$MSVSBUILDTARGET"' - env['MSVSCLEANCOM'] = '$MSVSSCONSCOM -c "$MSVSBUILDTARGET"' - - # Set-up ms tools paths for default version - msvc_setup_env_once(env) - - if 'MSVS_VERSION' in env: - version_num, suite = msvs_parse_version(env['MSVS_VERSION']) - else: - (version_num, suite) = (7.0, None) # guess at a default - if 'MSVS' not in env: - env['MSVS'] = {} - if version_num < 7.0: - env['MSVS']['PROJECTSUFFIX'] = '.dsp' - env['MSVS']['SOLUTIONSUFFIX'] = '.dsw' - elif version_num < 10.0: - env['MSVS']['PROJECTSUFFIX'] = '.vcproj' - env['MSVS']['SOLUTIONSUFFIX'] = '.sln' - else: - env['MSVS']['PROJECTSUFFIX'] = '.vcxproj' - env['MSVS']['SOLUTIONSUFFIX'] = '.sln' - - if version_num >= 10.0: - env['MSVSENCODING'] = 'utf-8' - else: - env['MSVSENCODING'] = 'Windows-1252' - - env['GET_MSVSPROJECTSUFFIX'] = GetMSVSProjectSuffix - env['GET_MSVSSOLUTIONSUFFIX'] = GetMSVSSolutionSuffix - env['MSVSPROJECTSUFFIX'] = '${GET_MSVSPROJECTSUFFIX}' - env['MSVSSOLUTIONSUFFIX'] = '${GET_MSVSSOLUTIONSUFFIX}' - env['SCONS_HOME'] = os.environ.get('SCONS_HOME') - -def exists(env): - return msvc_exists(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/mwcc.py b/scons/scons-local-4.1.0/SCons/Tool/mwcc.py deleted file mode 100644 index 8f1201a02..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/mwcc.py +++ /dev/null @@ -1,207 +0,0 @@ -"""SCons.Tool.mwcc - -Tool-specific initialization for the Metrowerks CodeWarrior 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import os.path - -import SCons.Util - -def set_vars(env): - """Set MWCW_VERSION, MWCW_VERSIONS, and some codewarrior environment vars - - MWCW_VERSIONS is set to a list of objects representing installed versions - - MWCW_VERSION is set to the version object that will be used for building. - MWCW_VERSION can be set to a string during Environment - construction to influence which version is chosen, otherwise - the latest one from MWCW_VERSIONS is used. - - Returns true if at least one version is found, false otherwise - """ - desired = env.get('MWCW_VERSION', '') - - # return right away if the variables are already set - if isinstance(desired, MWVersion): - return 1 - elif desired is None: - return 0 - - versions = find_versions() - version = None - - if desired: - for v in versions: - if str(v) == desired: - version = v - elif versions: - version = versions[-1] - - env['MWCW_VERSIONS'] = versions - env['MWCW_VERSION'] = version - - if version is None: - return 0 - - env.PrependENVPath('PATH', version.clpath) - env.PrependENVPath('PATH', version.dllpath) - ENV = env['ENV'] - ENV['CWFolder'] = version.path - ENV['LM_LICENSE_FILE'] = version.license - plus = lambda x: '+%s' % x - ENV['MWCIncludes'] = os.pathsep.join(map(plus, version.includes)) - ENV['MWLibraries'] = os.pathsep.join(map(plus, version.libs)) - return 1 - - -def find_versions(): - """Return a list of MWVersion objects representing installed versions""" - versions = [] - - ### This function finds CodeWarrior by reading from the registry on - ### Windows. Some other method needs to be implemented for other - ### platforms, maybe something that calls env.WhereIs('mwcc') - - if SCons.Util.can_read_reg: - try: - HLM = SCons.Util.HKEY_LOCAL_MACHINE - product = 'SOFTWARE\\Metrowerks\\CodeWarrior\\Product Versions' - product_key = SCons.Util.RegOpenKeyEx(HLM, product) - - i = 0 - while True: - name = product + '\\' + SCons.Util.RegEnumKey(product_key, i) - name_key = SCons.Util.RegOpenKeyEx(HLM, name) - - try: - version = SCons.Util.RegQueryValueEx(name_key, 'VERSION') - path = SCons.Util.RegQueryValueEx(name_key, 'PATH') - mwv = MWVersion(version[0], path[0], 'Win32-X86') - versions.append(mwv) - except SCons.Util.RegError: - pass - - i = i + 1 - - except SCons.Util.RegError: - pass - - return versions - - -class MWVersion: - def __init__(self, version, path, platform): - self.version = version - self.path = path - self.platform = platform - self.clpath = os.path.join(path, 'Other Metrowerks Tools', - 'Command Line Tools') - self.dllpath = os.path.join(path, 'Bin') - - # The Metrowerks tools don't store any configuration data so they - # are totally dumb when it comes to locating standard headers, - # libraries, and other files, expecting all the information - # to be handed to them in environment variables. The members set - # below control what information scons injects into the environment - - ### The paths below give a normal build environment in CodeWarrior for - ### Windows, other versions of CodeWarrior might need different paths. - - msl = os.path.join(path, 'MSL') - support = os.path.join(path, '%s Support' % platform) - - self.license = os.path.join(path, 'license.dat') - self.includes = [msl, support] - self.libs = [msl, support] - - def __str__(self): - return self.version - - -CSuffixes = ['.c', '.C'] -CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] - - -def generate(env): - """Add Builders and construction variables for the mwcc to an Environment.""" - import SCons.Defaults - import SCons.Tool - - set_vars(env) - - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in CSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCAction) - - for suffix in CXXSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CXXAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) - - env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -nolink -o $TARGET $SOURCES' - - env['CC'] = 'mwcc' - env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS' - - env['CXX'] = 'mwcc' - env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS' - - env['SHCC'] = '$CC' - env['SHCCFLAGS'] = '$CCFLAGS' - env['SHCFLAGS'] = '$CFLAGS' - env['SHCCCOM'] = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS' - - env['SHCXX'] = '$CXX' - env['SHCXXFLAGS'] = '$CXXFLAGS' - env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS' - - env['CFILESUFFIX'] = '.c' - env['CXXFILESUFFIX'] = '.cpp' - env['CPPDEFPREFIX'] = '-D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '-I' - env['INCSUFFIX'] = '' - - #env['PCH'] = ? - #env['PCHSTOP'] = ? - - -def exists(env): - return set_vars(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/mwld.py b/scons/scons-local-4.1.0/SCons/Tool/mwld.py deleted file mode 100644 index 20676606e..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/mwld.py +++ /dev/null @@ -1,108 +0,0 @@ -"""SCons.Tool.mwld - -Tool-specific initialization for the Metrowerks CodeWarrior linker. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Tool - - -def generate(env): - """Add Builders and construction variables for lib to an Environment.""" - SCons.Tool.createStaticLibBuilder(env) - SCons.Tool.createSharedLibBuilder(env) - SCons.Tool.createProgBuilder(env) - - env['AR'] = 'mwld' - env['ARCOM'] = '$AR $ARFLAGS -library -o $TARGET $SOURCES' - - env['LIBDIRPREFIX'] = '-L' - env['LIBDIRSUFFIX'] = '' - env['LIBLINKPREFIX'] = '-l' - env['LIBLINKSUFFIX'] = '.lib' - - env['LINK'] = 'mwld' - env['LINKCOM'] = '$LINK $LINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - - env['SHLINK'] = '$LINK' - env['SHLINKFLAGS'] = '$LINKFLAGS' - env['SHLINKCOM'] = shlib_action - env['SHLIBEMITTER']= shlib_emitter - env['LDMODULEEMITTER']= shlib_emitter - - -def exists(env): - import SCons.Tool.mwcc - return SCons.Tool.mwcc.set_vars(env) - - -def shlib_generator(target, source, env, for_signature): - cmd = ['$SHLINK', '$SHLINKFLAGS', '-shared'] - - no_import_lib = env.get('no_import_lib', 0) - if no_import_lib: cmd.extend('-noimplib') - - dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') - if dll: cmd.extend(['-o', dll]) - - implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') - if implib: cmd.extend(['-implib', implib.get_string(for_signature)]) - - cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS']) - - return [cmd] - - -def shlib_emitter(target, source, env): - dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') - no_import_lib = env.get('no_import_lib', 0) - - if not dll: - raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX")) - - 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')) - - return target, source - - -shlib_action = SCons.Action.Action(shlib_generator, generator=1) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/nasm.py b/scons/scons-local-4.1.0/SCons/Tool/nasm.py deleted file mode 100644 index ff0bc612f..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/nasm.py +++ /dev/null @@ -1,72 +0,0 @@ -"""SCons.Tool.nasm - -Tool-specific initialization for nasm, the famous Netwide Assembler. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util - -ASSuffixes = ['.s', '.asm', '.ASM'] -ASPPSuffixes = ['.spp', '.SPP', '.sx'] -if SCons.Util.case_sensitive_suffixes('.s', '.S'): - ASPPSuffixes.extend(['.S']) -else: - ASSuffixes.extend(['.S']) - -def generate(env): - """Add Builders and construction variables for nasm to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in ASSuffixes: - static_obj.add_action(suffix, SCons.Defaults.ASAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - - for suffix in ASPPSuffixes: - static_obj.add_action(suffix, SCons.Defaults.ASPPAction) - static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) - - env['AS'] = 'nasm' - env['ASFLAGS'] = SCons.Util.CLVar('') - env['ASPPFLAGS'] = '$ASFLAGS' - env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES' - env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' - -def exists(env): - return env.Detect('nasm') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/__init__.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/__init__.py deleted file mode 100644 index c378909a3..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/__init__.py +++ /dev/null @@ -1,328 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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.Tool.Packaging - -SCons Packaging Tool. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import importlib -from inspect import getfullargspec - -import SCons.Defaults -import SCons.Environment -from SCons.Errors import UserError, SConsEnvironmentError -from SCons.Script import AddOption, GetOption -from SCons.Util import is_List, make_path_relative -from SCons.Variables import EnumVariable -from SCons.Warnings import warn, SConsWarning - - -__all__ = [ - 'src_targz', 'src_tarbz2', 'src_tarxz', 'src_zip', - 'targz', 'tarbz2', 'tarxz', 'zip', - 'rpm', 'msi', 'ipk', -] - -# -# Utility and Builder function -# -def Tag(env, target, source, *more_tags, **kw_tags): - """ Tag a file with the given arguments. - - Just sets the accordingly named attribute on the file object. - - TODO: FIXME - """ - if not target: - target = source - first_tag = None - else: - first_tag = source - - if first_tag: - kw_tags[first_tag[0]] = '' - - if not kw_tags and not more_tags: - raise UserError("No tags given.") - - # XXX: sanity checks - for x in more_tags: - kw_tags[x] = '' - - if not SCons.Util.is_List(target): - target = [target] - else: - # hmm, sometimes the target list is a list of a list - # make sure it is flattened prior to processing. - # TODO: perhaps some bug ?!? - target = env.Flatten(target) - - for t in target: - for k, v in kw_tags.items(): - # all file tags have to start with PACKAGING_, so we can later - # differentiate between "normal" object attributes and the - # packaging attributes. As the user should not be bothered with - # that, the prefix will be added here if missing. - if not k.startswith('PACKAGING_'): - k = 'PACKAGING_' + k - t.Tag(k, v) - -def Package(env, target=None, source=None, **kw): - """ Entry point for the package tool. - """ - # check if we need to find the source files ourselves - if not source: - source = env.FindInstalledFiles() - - if not source: - raise UserError("No source for Package() given") - - # decide which types of packages shall be built. Can be defined through - # four mechanisms: command line argument, keyword argument, - # environment argument and default selection (zip or tar.gz) in that - # order. - try: - kw['PACKAGETYPE'] = env['PACKAGETYPE'] - except KeyError: - pass - - if not kw.get('PACKAGETYPE'): - kw['PACKAGETYPE'] = GetOption('package_type') - - if kw['PACKAGETYPE'] is None: - if 'Tar' in env['BUILDERS']: - kw['PACKAGETYPE'] = 'targz' - elif 'Zip' in env['BUILDERS']: - kw['PACKAGETYPE'] = 'zip' - else: - raise UserError("No type for Package() given") - - packagetype = kw['PACKAGETYPE'] - if not is_List(packagetype): - packagetype = packagetype.split(',') - - # load the needed packagers. - def load_packager(pkgtype): - try: - # the specific packager is a relative import - return importlib.import_module("." + pkgtype, __name__) - except ImportError as e: - raise SConsEnvironmentError("packager %s not available: %s" - % (pkgtype, str(e))) - - packagers = [load_packager(p) for p in packagetype] - - # set up targets and the PACKAGEROOT - try: - # fill up the target list with a default target name until the - # PACKAGETYPE list is of the same size as the target list. - if not target: - target = [] - - size_diff = len(packagetype) - len(target) - default_name = "%(NAME)s-%(VERSION)s" - - if size_diff > 0: - default_target = default_name % kw - target.extend([default_target] * size_diff) - - if 'PACKAGEROOT' not in kw: - kw['PACKAGEROOT'] = default_name % kw - - except KeyError as e: - raise UserError("Missing Packagetag '%s'" % e.args[0]) - - # setup the source files - source = env.arg2nodes(source, env.fs.Entry) - - # call the packager to setup the dependencies. - targets = [] - try: - for packager in packagers: - t = [target.pop(0)] - t = packager.package(env, t, source, **kw) - targets.extend(t) - - assert len(target) == 0 - - except KeyError as e: - raise UserError("Missing Packagetag '%s' for %s packager" - % (e.args[0], packager.__name__)) - except TypeError: - # this exception means that a needed argument for the packager is - # missing. As our packagers get their "tags" as named function - # arguments we need to find out which one is missing. - argspec = getfullargspec(packager.package) - args = argspec.args - if argspec.defaults: - # throw away arguments with default values - args = args[:-len(argspec.defaults)] - args.remove('env') - args.remove('target') - args.remove('source') - # now remove any args for which we have a value in kw. - args = [x for x in args if x not in kw] - - if not args: - raise # must be a different error, so re-raise - elif len(args) == 1: - raise UserError("Missing Packagetag '%s' for %s packager" - % (args[0], packager.__name__)) - raise UserError("Missing Packagetags '%s' for %s packager" - % (", ".join(args), packager.__name__)) - - target = env.arg2nodes(target, env.fs.Entry) - #XXX: target set above unused... what was the intent? - targets.extend(env.Alias('package', targets)) - return targets - -# -# SCons tool initialization functions -# -added = False - -def generate(env): - global added - if not added: - added = True - AddOption('--package-type', - dest='package_type', - default=None, - type="string", - action="store", - help='The type of package to create.') - - try: - env['BUILDERS']['Package'] - env['BUILDERS']['Tag'] - except KeyError: - env['BUILDERS']['Package'] = Package - env['BUILDERS']['Tag'] = Tag - -def exists(env): - return 1 - -# XXX -def options(opts): - opts.AddVariables( - EnumVariable('PACKAGETYPE', - 'the type of package to create.', - None, allowed_values=list(map( str, __all__ )), - ignorecase=2 - ) - ) - -# -# Internal utility functions -# - -def copy_attr(f1, f2): - """ Copies the special packaging file attributes from f1 to f2. - """ - if f1._tags: - pattrs = [ - tag - for tag in f1._tags - if not hasattr(f2, tag) and tag.startswith('PACKAGING_') - ] - for attr in pattrs: - f2.Tag(attr, f1.GetTag(attr)) - -def putintopackageroot(target, source, env, pkgroot, honor_install_location=1): - """ Copies all source files to the directory given in pkgroot. - - If honor_install_location is set and the copied source file has an - PACKAGING_INSTALL_LOCATION attribute, the PACKAGING_INSTALL_LOCATION is - used as the new name of the source file under pkgroot. - - The source file will not be copied if it is already under the the pkgroot - directory. - - All attributes of the source file will be copied to the new file. - - Note: - Uses CopyAs builder. - """ - # make sure the packageroot is a Dir object. - if SCons.Util.is_String(pkgroot): - pkgroot = env.Dir(pkgroot) - if not SCons.Util.is_List(source): - source = [source] - - new_source = [] - for file in source: - if SCons.Util.is_String(file): - file = env.File(file) - - if file.is_under(pkgroot): - new_source.append(file) - else: - if file.GetTag('PACKAGING_INSTALL_LOCATION') and \ - honor_install_location: - new_name = make_path_relative(file.GetTag('PACKAGING_INSTALL_LOCATION')) - else: - new_name = make_path_relative(file.get_path()) - - new_file = pkgroot.File(new_name) - new_file = env.CopyAs(new_file, file)[0] - copy_attr(file, new_file) - new_source.append(new_file) - - return target, new_source - - -def stripinstallbuilder(target, source, env): - """ Strips the install builder action from the source list and stores - the final installation location as the "PACKAGING_INSTALL_LOCATION" of - the source of the source file. This effectively removes the final installed - files from the source list while remembering the installation location. - - It also warns about files which have no install builder attached. - """ - def has_no_install_location(file): - return not (file.has_builder() and hasattr(file.builder, 'name') - and file.builder.name in ["InstallBuilder", "InstallAsBuilder"]) - - if len([src for src in source if has_no_install_location(src)]): - warn(SConsWarning, "there are files to package which have no\ - InstallBuilder attached, this might lead to irreproducible packages") - - n_source = [] - for s in source: - if has_no_install_location(s): - n_source.append(s) - else: - for ss in s.sources: - n_source.append(ss) - copy_attr(s, ss) - ss.Tag('PACKAGING_INSTALL_LOCATION', s.get_path()) - - return target, n_source - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/ipk.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/ipk.py deleted file mode 100644 index ac8b992bb..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/ipk.py +++ /dev/null @@ -1,189 +0,0 @@ -"""SCons.Tool.Packaging.ipk -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os - -import SCons.Builder -import SCons.Node.FS -import SCons.Util - -from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot - -def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION, - SUMMARY, X_IPK_PRIORITY, X_IPK_SECTION, SOURCE_URL, - X_IPK_MAINTAINER, X_IPK_DEPENDS, **kw): - """ This function prepares the packageroot directory for packaging with the - ipkg builder. - """ - SCons.Tool.Tool('ipkg').generate(env) - - # setup the Ipkg builder - bld = env['BUILDERS']['Ipkg'] - target, source = stripinstallbuilder(target, source, env) - target, source = putintopackageroot(target, source, env, PACKAGEROOT) - - # This should be overrideable from the construction environment, - # which it is by using ARCHITECTURE=. - # Guessing based on what os.uname() returns at least allows it - # to work for both i386 and x86_64 Linux systems. - archmap = { - 'i686' : 'i386', - 'i586' : 'i386', - 'i486' : 'i386', - } - - buildarchitecture = os.uname()[4] - buildarchitecture = archmap.get(buildarchitecture, buildarchitecture) - - if 'ARCHITECTURE' in kw: - buildarchitecture = kw['ARCHITECTURE'] - - # setup the kw to contain the mandatory arguments to this function. - # do this before calling any builder or setup function - loc=locals() - del loc['kw'] - kw.update(loc) - del kw['source'], kw['target'], kw['env'] - - # generate the specfile - specfile = gen_ipk_dir(PACKAGEROOT, source, env, kw) - - # override the default target. - if str(target[0])=="%s-%s"%(NAME, VERSION): - target=[ "%s_%s_%s.ipk"%(NAME, VERSION, buildarchitecture) ] - - # now apply the Ipkg builder - return bld(env, target, specfile, **kw) - -def gen_ipk_dir(proot, source, env, kw): - # make sure the packageroot is a Dir object. - if SCons.Util.is_String(proot): proot=env.Dir(proot) - - # create the specfile builder - s_bld=SCons.Builder.Builder( - action = build_specfiles, - ) - - # create the specfile targets - spec_target=[] - control=proot.Dir('CONTROL') - spec_target.append(control.File('control')) - spec_target.append(control.File('conffiles')) - spec_target.append(control.File('postrm')) - spec_target.append(control.File('prerm')) - spec_target.append(control.File('postinst')) - spec_target.append(control.File('preinst')) - - # apply the builder to the specfile targets - s_bld(env, spec_target, source, **kw) - - # the packageroot directory does now contain the specfiles. - return proot - -def build_specfiles(source, target, env): - """ Filter the targets for the needed files and use the variables in env - to create the specfile. - """ - # - # At first we care for the CONTROL/control file, which is the main file for ipk. - # - # For this we need to open multiple files in random order, so we store into - # a dict so they can be easily accessed. - # - # - opened_files={} - def open_file(needle, haystack=None): - try: - return opened_files[needle] - except KeyError: - files = filter(lambda x: x.get_path().rfind(needle) != -1, haystack) - # Py3: filter returns an iterable, not a list - file = list(files)[0] - opened_files[needle] = open(file.get_abspath(), 'w') - return opened_files[needle] - - control_file = open_file('control', target) - - if 'X_IPK_DESCRIPTION' not in env: - env['X_IPK_DESCRIPTION']="%s\n %s"%(env['SUMMARY'], - env['DESCRIPTION'].replace('\n', '\n ')) - - - content = """ -Package: $NAME -Version: $VERSION -Priority: $X_IPK_PRIORITY -Section: $X_IPK_SECTION -Source: $SOURCE_URL -Architecture: $ARCHITECTURE -Maintainer: $X_IPK_MAINTAINER -Depends: $X_IPK_DEPENDS -Description: $X_IPK_DESCRIPTION -""" - - control_file.write(env.subst(content)) - - # - # now handle the various other files, which purpose it is to set post-, - # pre-scripts and mark files as config files. - # - # We do so by filtering the source files for files which are marked with - # the "config" tag and afterwards we do the same for x_ipk_postrm, - # x_ipk_prerm, x_ipk_postinst and x_ipk_preinst tags. - # - # The first one will write the name of the file into the file - # CONTROL/configfiles, the latter add the content of the x_ipk_* variable - # into the same named file. - # - for f in [x for x in source if 'PACKAGING_CONFIG' in dir(x)]: - config = open_file('conffiles') - config.write(f.PACKAGING_INSTALL_LOCATION) - config.write('\n') - - for str in 'POSTRM PRERM POSTINST PREINST'.split(): - name="PACKAGING_X_IPK_%s"%str - for f in [x for x in source if name in dir(x)]: - file = open_file(name) - file.write(env[str]) - - # - # close all opened files - for f in opened_files.values(): - f.close() - - # call a user specified function - if 'CHANGE_SPECFILE' in env: - content += env['CHANGE_SPECFILE'](target) - - return 0 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/msi.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/msi.py deleted file mode 100644 index 458e81f83..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/msi.py +++ /dev/null @@ -1,525 +0,0 @@ -"""SCons.Tool.packaging.msi - -The msi packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import SCons -from SCons.Action import Action -from SCons.Builder import Builder - -from xml.dom.minidom import Document -from xml.sax.saxutils import escape - -from SCons.Tool.packaging import stripinstallbuilder - -# -# Utility functions -# -def convert_to_id(s, id_set): - """ Some parts of .wxs need an Id attribute (for example: The File and - Directory directives. The charset is limited to A-Z, a-z, digits, - underscores, periods. Each Id must begin with a letter or with a - underscore. Google for "CNDL0015" for information about this. - - Requirements: - * the string created must only contain chars from the target charset. - * the string created must have a minimal editing distance from the - original string. - * the string created must be unique for the whole .wxs file. - - Observation: - * There are 62 chars in the charset. - - Idea: - * filter out forbidden characters. Check for a collision with the help - of the id_set. Add the number of the number of the collision at the - end of the created string. Furthermore care for a correct start of - the string. - """ - charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz0123456789_.' - if s[0] in '0123456789.': - s = '_' + s - id = ''.join([c for c in s if c in charset]) - - # did we already generate an id for this file? - try: - return id_set[id][s] - except KeyError: - # no we did not, so initialize with the id - if id not in id_set: id_set[id] = { s : id } - # there is a collision, generate an id which is unique by appending - # the collision number - else: id_set[id][s] = id + str(len(id_set[id])) - - return id_set[id][s] - -def is_dos_short_file_name(file): - """ Examine if the given file is in the 8.3 form. - """ - fname, ext = os.path.splitext(file) - proper_ext = len(ext) == 0 or (2 <= len(ext) <= 4) # the ext contains the dot - proper_fname = file.isupper() and len(fname) <= 8 - - return proper_ext and proper_fname - -def gen_dos_short_file_name(file, filename_set): - """ See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q142982 - - These are no complete 8.3 dos short names. The ~ char is missing and - replaced with one character from the filename. WiX warns about such - filenames, since a collision might occur. Google for "CNDL1014" for - more information. - """ - # guard this to not confuse the generation - if is_dos_short_file_name(file): - return file - - fname, ext = os.path.splitext(file) # ext contains the dot - - # first try if it suffices to convert to upper - file = file.upper() - if is_dos_short_file_name(file): - return file - - # strip forbidden characters. - forbidden = '."/[]:;=, ' - fname = ''.join([c for c in fname if c not in forbidden]) - - # check if we already generated a filename with the same number: - # thisis1.txt, thisis2.txt etc. - duplicate, num = not None, 1 - while duplicate: - shortname = "%s%s" % (fname[:8-len(str(num))].upper(), str(num)) - if len(ext) >= 2: - shortname = "%s%s" % (shortname, ext[:4].upper()) - - duplicate, num = shortname in filename_set, num+1 - - assert( is_dos_short_file_name(shortname) ), 'shortname is %s, longname is %s' % (shortname, file) - filename_set.append(shortname) - return shortname - -def create_feature_dict(files): - """ X_MSI_FEATURE and doc FileTag's can be used to collect files in a - hierarchy. This function collects the files into this hierarchy. - """ - dict = {} - - def add_to_dict( feature, file ): - if not SCons.Util.is_List( feature ): - feature = [ feature ] - - for f in feature: - if f not in dict: - dict[ f ] = [ file ] - else: - dict[ f ].append( file ) - - for file in files: - if hasattr( file, 'PACKAGING_X_MSI_FEATURE' ): - add_to_dict(file.PACKAGING_X_MSI_FEATURE, file) - elif hasattr( file, 'PACKAGING_DOC' ): - add_to_dict( 'PACKAGING_DOC', file ) - else: - add_to_dict( 'default', file ) - - return dict - -def generate_guids(root): - """ generates globally unique identifiers for parts of the xml which need - them. - - Component tags have a special requirement. Their UUID is only allowed to - change if the list of their contained resources has changed. This allows - for clean removal and proper updates. - - To handle this requirement, the uuid is generated with an md5 hashing the - whole subtree of a xml node. - """ - import uuid - - # specify which tags need a guid and in which attribute this should be stored. - needs_id = { 'Product' : 'Id', - 'Package' : 'Id', - 'Component' : 'Guid', - } - - # find all XMl nodes matching the key, retrieve their attribute, hash their - # subtree, convert hash to string and add as a attribute to the xml node. - for (key,value) in needs_id.items(): - node_list = root.getElementsByTagName(key) - attribute = value - for node in node_list: - hash = uuid.uuid5(uuid.NAMESPACE_URL, node.toxml()) - node.attributes[attribute] = str(hash) - - -def string_wxsfile(target, source, env): - return "building WiX file %s" % target[0].path - -def build_wxsfile(target, source, env): - """ Compiles a .wxs file from the keywords given in env['msi_spec'] and - by analyzing the tree of source nodes and their tags. - """ - f = open(target[0].get_abspath(), 'w') - - try: - # Create a document with the Wix root tag - doc = Document() - root = doc.createElement( 'Wix' ) - root.attributes['xmlns']='http://schemas.microsoft.com/wix/2003/01/wi' - doc.appendChild( root ) - - filename_set = [] # this is to circumvent duplicates in the shortnames - id_set = {} # this is to circumvent duplicates in the ids - - # Create the content - build_wxsfile_header_section(root, env) - build_wxsfile_file_section(root, source, env['NAME'], env['VERSION'], env['VENDOR'], filename_set, id_set) - generate_guids(root) - build_wxsfile_features_section(root, source, env['NAME'], env['VERSION'], env['SUMMARY'], id_set) - build_wxsfile_default_gui(root) - build_license_file(target[0].get_dir(), env) - - # write the xml to a file - f.write( doc.toprettyxml() ) - - # call a user specified function - if 'CHANGE_SPECFILE' in env: - env['CHANGE_SPECFILE'](target, source) - - except KeyError as e: - raise SCons.Errors.UserError( '"%s" package field for MSI is missing.' % e.args[0] ) - finally: - f.close() - -# -# setup function -# -def create_default_directory_layout(root, NAME, VERSION, VENDOR, filename_set): - r""" Create the wix default target directory layout and return the innermost - directory. - - We assume that the XML tree delivered in the root argument already contains - the Product tag. - - Everything is put under the PFiles directory property defined by WiX. - After that a directory with the 'VENDOR' tag is placed and then a - directory with the name of the project and its VERSION. This leads to the - following TARGET Directory Layout: - C:\\\\ - Example: C:\Programme\Company\Product-1.2\ - """ - doc = Document() - d1 = doc.createElement( 'Directory' ) - d1.attributes['Id'] = 'TARGETDIR' - d1.attributes['Name'] = 'SourceDir' - - d2 = doc.createElement( 'Directory' ) - d2.attributes['Id'] = 'ProgramFilesFolder' - d2.attributes['Name'] = 'PFiles' - - d3 = doc.createElement( 'Directory' ) - d3.attributes['Id'] = 'VENDOR_folder' - d3.attributes['Name'] = escape( gen_dos_short_file_name( VENDOR, filename_set ) ) - d3.attributes['LongName'] = escape( VENDOR ) - - d4 = doc.createElement( 'Directory' ) - project_folder = "%s-%s" % ( NAME, VERSION ) - d4.attributes['Id'] = 'MY_DEFAULT_FOLDER' - d4.attributes['Name'] = escape( gen_dos_short_file_name( project_folder, filename_set ) ) - d4.attributes['LongName'] = escape( project_folder ) - - d1.childNodes.append( d2 ) - d2.childNodes.append( d3 ) - d3.childNodes.append( d4 ) - - root.getElementsByTagName('Product')[0].childNodes.append( d1 ) - - return d4 - -# -# mandatory and optional file tags -# -def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, id_set): - """ Builds the Component sections of the wxs file with their included files. - - Files need to be specified in 8.3 format and in the long name format, long - filenames will be converted automatically. - - Features are specficied with the 'X_MSI_FEATURE' or 'DOC' FileTag. - """ - root = create_default_directory_layout( root, NAME, VERSION, VENDOR, filename_set ) - components = create_feature_dict( files ) - factory = Document() - - def get_directory( node, dir ): - """ Returns the node under the given node representing the directory. - - Returns the component node if dir is None or empty. - """ - if dir == '' or not dir: - return node - - Directory = node - dir_parts = dir.split(os.path.sep) - - # to make sure that our directory ids are unique, the parent folders are - # consecutively added to upper_dir - upper_dir = '' - - # walk down the xml tree finding parts of the directory - dir_parts = [d for d in dir_parts if d != ''] - for d in dir_parts[:]: - already_created = [c for c in Directory.childNodes - if c.nodeName == 'Directory' - and c.attributes['LongName'].value == escape(d)] - - if already_created: - Directory = already_created[0] - dir_parts.remove(d) - upper_dir += d - else: - break - - for d in dir_parts: - nDirectory = factory.createElement( 'Directory' ) - nDirectory.attributes['LongName'] = escape( d ) - nDirectory.attributes['Name'] = escape( gen_dos_short_file_name( d, filename_set ) ) - upper_dir += d - nDirectory.attributes['Id'] = convert_to_id( upper_dir, id_set ) - - Directory.childNodes.append( nDirectory ) - Directory = nDirectory - - return Directory - - for file in files: - drive, path = os.path.splitdrive( file.PACKAGING_INSTALL_LOCATION ) - filename = os.path.basename( path ) - dirname = os.path.dirname( path ) - - h = { - # tagname : default value - 'PACKAGING_X_MSI_VITAL' : 'yes', - 'PACKAGING_X_MSI_FILEID' : convert_to_id(filename, id_set), - 'PACKAGING_X_MSI_LONGNAME' : filename, - 'PACKAGING_X_MSI_SHORTNAME' : gen_dos_short_file_name(filename, filename_set), - 'PACKAGING_X_MSI_SOURCE' : file.get_path(), - } - - # fill in the default tags given above. - for k,v in [ (k, v) for (k,v) in h.items() if not hasattr(file, k) ]: - setattr( file, k, v ) - - File = factory.createElement( 'File' ) - File.attributes['LongName'] = escape( file.PACKAGING_X_MSI_LONGNAME ) - File.attributes['Name'] = escape( file.PACKAGING_X_MSI_SHORTNAME ) - File.attributes['Source'] = escape( file.PACKAGING_X_MSI_SOURCE ) - File.attributes['Id'] = escape( file.PACKAGING_X_MSI_FILEID ) - File.attributes['Vital'] = escape( file.PACKAGING_X_MSI_VITAL ) - - # create the Tag under which this file should appear - Component = factory.createElement('Component') - Component.attributes['DiskId'] = '1' - Component.attributes['Id'] = convert_to_id( filename, id_set ) - - # hang the component node under the root node and the file node - # under the component node. - Directory = get_directory( root, dirname ) - Directory.childNodes.append( Component ) - Component.childNodes.append( File ) - -# -# additional functions -# -def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): - """ This function creates the tag based on the supplied xml tree. - - This is achieved by finding all s and adding them to a default target. - - It should be called after the tree has been built completly. We assume - that a MY_DEFAULT_FOLDER Property is defined in the wxs file tree. - - Furthermore a top-level with the name and VERSION of the software will be created. - - An PACKAGING_X_MSI_FEATURE can either be a string, where the feature - DESCRIPTION will be the same as its title or a Tuple, where the first - part will be its title and the second its DESCRIPTION. - """ - factory = Document() - Feature = factory.createElement('Feature') - Feature.attributes['Id'] = 'complete' - Feature.attributes['ConfigurableDirectory'] = 'MY_DEFAULT_FOLDER' - Feature.attributes['Level'] = '1' - Feature.attributes['Title'] = escape( '%s %s' % (NAME, VERSION) ) - Feature.attributes['Description'] = escape( SUMMARY ) - Feature.attributes['Display'] = 'expand' - - for (feature, files) in create_feature_dict(files).items(): - SubFeature = factory.createElement('Feature') - SubFeature.attributes['Level'] = '1' - - if SCons.Util.is_Tuple(feature): - SubFeature.attributes['Id'] = convert_to_id( feature[0], id_set ) - SubFeature.attributes['Title'] = escape(feature[0]) - SubFeature.attributes['Description'] = escape(feature[1]) - else: - SubFeature.attributes['Id'] = convert_to_id( feature, id_set ) - if feature=='default': - SubFeature.attributes['Description'] = 'Main Part' - SubFeature.attributes['Title'] = 'Main Part' - elif feature=='PACKAGING_DOC': - SubFeature.attributes['Description'] = 'Documentation' - SubFeature.attributes['Title'] = 'Documentation' - else: - SubFeature.attributes['Description'] = escape(feature) - SubFeature.attributes['Title'] = escape(feature) - - # build the componentrefs. As one of the design decision is that every - # file is also a component we walk the list of files and create a - # reference. - for f in files: - ComponentRef = factory.createElement('ComponentRef') - ComponentRef.attributes['Id'] = convert_to_id( os.path.basename(f.get_path()), id_set ) - SubFeature.childNodes.append(ComponentRef) - - Feature.childNodes.append(SubFeature) - - root.getElementsByTagName('Product')[0].childNodes.append(Feature) - -def build_wxsfile_default_gui(root): - """ This function adds a default GUI to the wxs file - """ - factory = Document() - Product = root.getElementsByTagName('Product')[0] - - UIRef = factory.createElement('UIRef') - UIRef.attributes['Id'] = 'WixUI_Mondo' - Product.childNodes.append(UIRef) - - UIRef = factory.createElement('UIRef') - UIRef.attributes['Id'] = 'WixUI_ErrorProgressText' - Product.childNodes.append(UIRef) - -def build_license_file(directory, spec): - """ Creates a License.rtf file with the content of "X_MSI_LICENSE_TEXT" - in the given directory - """ - name, text = '', '' - - try: - name = spec['LICENSE'] - text = spec['X_MSI_LICENSE_TEXT'] - except KeyError: - pass # ignore this as X_MSI_LICENSE_TEXT is optional - - if name!='' or text!='': - with open(os.path.join(directory.get_path(), 'License.rtf'), 'w') as f: - f.write('{\\rtf') - if text!='': - f.write(text.replace('\n', '\\par ')) - else: - f.write(name+'\\par\\par') - f.write('}') - -# -# mandatory and optional package tags -# -def build_wxsfile_header_section(root, spec): - """ Adds the xml file node which define the package meta-data. - """ - # Create the needed DOM nodes and add them at the correct position in the tree. - factory = Document() - Product = factory.createElement( 'Product' ) - Package = factory.createElement( 'Package' ) - - root.childNodes.append( Product ) - Product.childNodes.append( Package ) - - # set "mandatory" default values - if 'X_MSI_LANGUAGE' not in spec: - spec['X_MSI_LANGUAGE'] = '1033' # select english - - # mandatory sections, will throw a KeyError if the tag is not available - Product.attributes['Name'] = escape( spec['NAME'] ) - Product.attributes['Version'] = escape( spec['VERSION'] ) - Product.attributes['Manufacturer'] = escape( spec['VENDOR'] ) - Product.attributes['Language'] = escape( spec['X_MSI_LANGUAGE'] ) - Package.attributes['Description'] = escape( spec['SUMMARY'] ) - - # now the optional tags, for which we avoid the KeyErrror exception - if 'DESCRIPTION' in spec: - Package.attributes['Comments'] = escape( spec['DESCRIPTION'] ) - - if 'X_MSI_UPGRADE_CODE' in spec: - Package.attributes['X_MSI_UPGRADE_CODE'] = escape( spec['X_MSI_UPGRADE_CODE'] ) - - # We hardcode the media tag as our current model cannot handle it. - Media = factory.createElement('Media') - Media.attributes['Id'] = '1' - Media.attributes['Cabinet'] = 'default.cab' - Media.attributes['EmbedCab'] = 'yes' - root.getElementsByTagName('Product')[0].childNodes.append(Media) - -# this builder is the entry-point for .wxs file compiler. -wxs_builder = Builder( - action = Action( build_wxsfile, string_wxsfile ), - ensure_suffix = '.wxs' ) - -def package(env, target, source, PACKAGEROOT, NAME, VERSION, - DESCRIPTION, SUMMARY, VENDOR, X_MSI_LANGUAGE, **kw): - # make sure that the Wix Builder is in the environment - SCons.Tool.Tool('wix').generate(env) - - # get put the keywords for the specfile compiler. These are the arguments - # given to the package function and all optional ones stored in kw, minus - # the the source, target and env one. - loc = locals() - del loc['kw'] - kw.update(loc) - del kw['source'], kw['target'], kw['env'] - - # strip the install builder from the source files - target, source = stripinstallbuilder(target, source, env) - - # put the arguments into the env and call the specfile builder. - env['msi_spec'] = kw - specfile = wxs_builder(* [env, target, source], **kw) - - # now call the WiX Tool with the built specfile added as a source. - msifile = env.WiX(target, specfile) - - # return the target and source tuple. - return (msifile, source+[specfile]) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/rpm.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/rpm.py deleted file mode 100644 index cdeabcf62..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/rpm.py +++ /dev/null @@ -1,364 +0,0 @@ -"""SCons.Tool.Packaging.rpm - -The rpm packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -import SCons.Builder -import SCons.Tool.rpmutils - -from SCons.Environment import OverrideEnvironment -from SCons.Tool.packaging import stripinstallbuilder, src_targz -from SCons.Errors import UserError - -def package(env, target, source, PACKAGEROOT, NAME, VERSION, - PACKAGEVERSION, DESCRIPTION, SUMMARY, X_RPM_GROUP, LICENSE, - **kw): - # initialize the rpm tool - SCons.Tool.Tool('rpm').generate(env) - - bld = env['BUILDERS']['Rpm'] - - # Generate a UserError whenever the target name has been set explicitly, - # since rpm does not allow for controlling it. This is detected by - # checking if the target has been set to the default by the Package() - # Environment function. - if str(target[0])!="%s-%s"%(NAME, VERSION): - raise UserError( "Setting target is not supported for rpm." ) - else: - # Deduce the build architecture, but allow it to be overridden - # by setting ARCHITECTURE in the construction env. - buildarchitecture = SCons.Tool.rpmutils.defaultMachine() - if 'ARCHITECTURE' in kw: - buildarchitecture = kw['ARCHITECTURE'] - - fmt = '%s-%s-%s.%s.rpm' - srcrpm = fmt % (NAME, VERSION, PACKAGEVERSION, 'src') - binrpm = fmt % (NAME, VERSION, PACKAGEVERSION, buildarchitecture) - - target = [ srcrpm, binrpm ] - - # get the correct arguments into the kw hash - loc=locals() - del loc['kw'] - kw.update(loc) - del kw['source'], kw['target'], kw['env'] - - # if no "SOURCE_URL" tag is given add a default one. - if 'SOURCE_URL' not in kw: - kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '') - - # mangle the source and target list for the rpmbuild - env = OverrideEnvironment(env, kw) - target, source = stripinstallbuilder(target, source, env) - target, source = addspecfile(target, source, env) - target, source = collectintargz(target, source, env) - - # now call the rpm builder to actually build the packet. - return bld(env, target, source, **kw) - -def collectintargz(target, source, env): - """ Puts all source files into a tar.gz file. """ - # the rpm tool depends on a source package, until this is changed - # this hack needs to be here that tries to pack all sources in. - sources = env.FindSourceFiles() - - # filter out the target we are building the source list for. - sources = [s for s in sources if s not in target] - - # find the .spec file for rpm and add it since it is not necessarily found - # by the FindSourceFiles function. - sources.extend( [s for s in source if str(s).rfind('.spec')!=-1] ) - # sort to keep sources from changing order across builds - sources.sort() - - # as the source contains the url of the source package this rpm package - # is built from, we extract the target name - tarball = (str(target[0])+".tar.gz").replace('.rpm', '') - try: - tarball = env['SOURCE_URL'].split('/')[-1] - except KeyError as e: - raise SCons.Errors.UserError( "Missing PackageTag '%s' for RPM packager" % e.args[0] ) - - tarball = src_targz.package(env, source=sources, target=tarball, - PACKAGEROOT=env['PACKAGEROOT'], ) - - return (target, tarball) - -def addspecfile(target, source, env): - specfile = "%s-%s" % (env['NAME'], env['VERSION']) - - bld = SCons.Builder.Builder(action = build_specfile, - suffix = '.spec', - target_factory = SCons.Node.FS.File) - - source.extend(bld(env, specfile, source)) - - return (target,source) - -def build_specfile(target, source, env): - """ Builds a RPM specfile from a dictionary with string metadata and - by analyzing a tree of nodes. - """ - with open(target[0].get_abspath(), 'w') as ofp: - try: - ofp.write(build_specfile_header(env)) - ofp.write(build_specfile_sections(env)) - ofp.write(build_specfile_filesection(env, source)) - - # call a user specified function - if 'CHANGE_SPECFILE' in env: - env['CHANGE_SPECFILE'](target, source) - - except KeyError as e: - raise SCons.Errors.UserError('"%s" package field for RPM is missing.' % e.args[0]) - - -# -# mandatory and optional package tag section -# -def build_specfile_sections(spec): - """ Builds the sections of a rpm specfile. - """ - str = "" - - mandatory_sections = { - 'DESCRIPTION' : '\n%%description\n%s\n\n', } - - str = str + SimpleTagCompiler(mandatory_sections).compile( spec ) - - optional_sections = { - 'DESCRIPTION_' : '%%description -l %s\n%s\n\n', - 'CHANGELOG' : '%%changelog\n%s\n\n', - 'X_RPM_PREINSTALL' : '%%pre\n%s\n\n', - 'X_RPM_POSTINSTALL' : '%%post\n%s\n\n', - 'X_RPM_PREUNINSTALL' : '%%preun\n%s\n\n', - 'X_RPM_POSTUNINSTALL' : '%%postun\n%s\n\n', - 'X_RPM_VERIFY' : '%%verify\n%s\n\n', - - # These are for internal use but could possibly be overridden - 'X_RPM_PREP' : '%%prep\n%s\n\n', - 'X_RPM_BUILD' : '%%build\n%s\n\n', - 'X_RPM_INSTALL' : '%%install\n%s\n\n', - 'X_RPM_CLEAN' : '%%clean\n%s\n\n', - } - - # Default prep, build, install and clean rules - # TODO: optimize those build steps, to not compile the project a second time - if 'X_RPM_PREP' not in spec: - spec['X_RPM_PREP'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' + '\n%setup -q' - - if 'X_RPM_BUILD' not in spec: - spec['X_RPM_BUILD'] = '[ ! -e "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && mkdir "$RPM_BUILD_ROOT"' - - if 'X_RPM_INSTALL' not in spec: - spec['X_RPM_INSTALL'] = 'scons --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"' - - if 'X_RPM_CLEAN' not in spec: - spec['X_RPM_CLEAN'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' - - str = str + SimpleTagCompiler(optional_sections, mandatory=0).compile( spec ) - - return str - -def build_specfile_header(spec): - """ Builds all sections but the %file of a rpm specfile - """ - str = "" - - # first the mandatory sections - mandatory_header_fields = { - 'NAME' : '%%define name %s\nName: %%{name}\n', - 'VERSION' : '%%define version %s\nVersion: %%{version}\n', - 'PACKAGEVERSION' : '%%define release %s\nRelease: %%{release}\n', - 'X_RPM_GROUP' : 'Group: %s\n', - 'SUMMARY' : 'Summary: %s\n', - 'LICENSE' : 'License: %s\n', - } - - str = str + SimpleTagCompiler(mandatory_header_fields).compile( spec ) - - # now the optional tags - optional_header_fields = { - 'VENDOR' : 'Vendor: %s\n', - 'X_RPM_URL' : 'Url: %s\n', - 'SOURCE_URL' : 'Source: %s\n', - 'SUMMARY_' : 'Summary(%s): %s\n', - 'ARCHITECTURE' : 'BuildArch: %s\n', - 'X_RPM_DISTRIBUTION' : 'Distribution: %s\n', - 'X_RPM_ICON' : 'Icon: %s\n', - 'X_RPM_PACKAGER' : 'Packager: %s\n', - 'X_RPM_GROUP_' : 'Group(%s): %s\n', - - 'X_RPM_REQUIRES' : 'Requires: %s\n', - 'X_RPM_PROVIDES' : 'Provides: %s\n', - 'X_RPM_CONFLICTS' : 'Conflicts: %s\n', - 'X_RPM_BUILDREQUIRES' : 'BuildRequires: %s\n', - - 'X_RPM_SERIAL' : 'Serial: %s\n', - 'X_RPM_EPOCH' : 'Epoch: %s\n', - 'X_RPM_AUTOREQPROV' : 'AutoReqProv: %s\n', - 'X_RPM_EXCLUDEARCH' : 'ExcludeArch: %s\n', - 'X_RPM_EXCLUSIVEARCH' : 'ExclusiveArch: %s\n', - 'X_RPM_PREFIX' : 'Prefix: %s\n', - - # internal use - 'X_RPM_BUILDROOT' : 'BuildRoot: %s\n', - } - - # fill in default values: - # Adding a BuildRequires renders the .rpm unbuildable under systems which - # are not managed by rpm, since the database to resolve this dependency is - # missing (take Gentoo as an example) - #if 'X_RPM_BUILDREQUIRES' not in spec: - # spec['X_RPM_BUILDREQUIRES'] = 'scons' - - if 'X_RPM_BUILDROOT' not in spec: - spec['X_RPM_BUILDROOT'] = '%{_tmppath}/%{name}-%{version}-%{release}' - - str = str + SimpleTagCompiler(optional_header_fields, mandatory=0).compile( spec ) - - # Add any extra specfile definitions the user may have supplied. - # These flags get no processing, they are just added. - # github #3164: if we don't turn off debug package generation - # the tests which build packages all fail. If there are no - # extra flags, default to adding this one. If the user wants - # to turn this back on, supply the flag set to None. - - if 'X_RPM_EXTRADEFS' not in spec: - spec['X_RPM_EXTRADEFS'] = ['%global debug_package %{nil}'] - for extra in spec['X_RPM_EXTRADEFS']: - str += extra + '\n' - - return str - -# -# mandatory and optional file tags -# -def build_specfile_filesection(spec, files): - """ builds the %file section of the specfile - """ - str = '%files\n' - - if 'X_RPM_DEFATTR' not in spec: - spec['X_RPM_DEFATTR'] = '(-,root,root)' - - str = str + '%%defattr %s\n' % spec['X_RPM_DEFATTR'] - - supported_tags = { - 'PACKAGING_CONFIG' : '%%config %s', - 'PACKAGING_CONFIG_NOREPLACE' : '%%config(noreplace) %s', - 'PACKAGING_DOC' : '%%doc %s', - 'PACKAGING_UNIX_ATTR' : '%%attr %s', - 'PACKAGING_LANG_' : '%%lang(%s) %s', - 'PACKAGING_X_RPM_VERIFY' : '%%verify %s', - 'PACKAGING_X_RPM_DIR' : '%%dir %s', - 'PACKAGING_X_RPM_DOCDIR' : '%%docdir %s', - 'PACKAGING_X_RPM_GHOST' : '%%ghost %s', } - - for file in files: - # build the tagset - tags = {} - for k in supported_tags.keys(): - try: - v = file.GetTag(k) - if v: - tags[k] = v - except AttributeError: - pass - - # compile the tagset - str = str + SimpleTagCompiler(supported_tags, mandatory=0).compile( tags ) - - str = str + ' ' - str = str + file.GetTag('PACKAGING_INSTALL_LOCATION') - str = str + '\n\n' - - return str - -class SimpleTagCompiler: - """ Compile RPM tags by doing simple string substitution. - - The replacement specfication is stored in the *tagset* dictionary, - something like:: - - {"abc" : "cdef %s ", "abc_": "cdef %s %s"} - - The :func:`compile` function gets a value dictionary, which may look like:: - - {"abc": "ghij", "abc_gh": "ij"} - - The resulting string will be:: - - "cdef ghij cdef gh ij" - - """ - def __init__(self, tagset, mandatory=1): - self.tagset = tagset - self.mandatory = mandatory - - def compile(self, values): - """ Compiles the tagset and returns a str containing the result - """ - def is_international(tag): - return tag.endswith('_') - - def get_country_code(tag): - return tag[-2:] - - def strip_country_code(tag): - return tag[:-2] - - replacements = list(self.tagset.items()) - - str = "" - domestic = [t for t in replacements if not is_international(t[0])] - for key, replacement in domestic: - try: - str = str + replacement % values[key] - except KeyError as e: - if self.mandatory: - raise e - - international = [t for t in replacements if is_international(t[0])] - for key, replacement in international: - try: - x = [t for t in values.items() if strip_country_code(t[0]) == key] - int_values_for_key = [(get_country_code(t[0]),t[1]) for t in x] - for v in int_values_for_key: - str = str + replacement % v - except KeyError as e: - if self.mandatory: - raise e - - return str - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarbz2.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarbz2.py deleted file mode 100644 index d13229121..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarbz2.py +++ /dev/null @@ -1,43 +0,0 @@ -"""SCons.Tool.Packaging.src_tarbz2 - -The tarbz2 SRC packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Tar'] - bld.set_suffix('.tar.bz2') - target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0) - return bld(env, target, source, TARFLAGS='-jc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_targz.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/src_targz.py deleted file mode 100644 index 7b759dc71..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_targz.py +++ /dev/null @@ -1,43 +0,0 @@ -"""SCons.Tool.Packaging.src_targz - -The targz SRC packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Tar'] - bld.set_suffix('.tar.gz') - target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0) - return bld(env, target, source, TARFLAGS='-zc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarxz.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarxz.py deleted file mode 100644 index 5889b8a8f..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_tarxz.py +++ /dev/null @@ -1,43 +0,0 @@ -"""SCons.Tool.Packaging.src_tarxz - -The tarxz SRC packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Tar'] - bld.set_suffix('.tar.xz') - target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0) - return bld(env, target, source, TARFLAGS='-Jc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_zip.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/src_zip.py deleted file mode 100644 index 3df73970b..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/src_zip.py +++ /dev/null @@ -1,43 +0,0 @@ -"""SCons.Tool.Packaging.zip - -The zip SRC packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Zip'] - bld.set_suffix('.zip') - target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0) - return bld(env, target, source) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/tarbz2.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/tarbz2.py deleted file mode 100644 index 392bf956d..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/tarbz2.py +++ /dev/null @@ -1,44 +0,0 @@ -"""SCons.Tool.Packaging.tarbz2 - -The tarbz2 packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Tar'] - bld.set_suffix('.tar.bz2') - target, source = putintopackageroot(target, source, env, PACKAGEROOT) - target, source = stripinstallbuilder(target, source, env) - return bld(env, target, source, TARFLAGS='-jc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/targz.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/targz.py deleted file mode 100644 index 4130f32f2..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/targz.py +++ /dev/null @@ -1,44 +0,0 @@ -"""SCons.Tool.Packaging.targz - -The targz packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Tar'] - bld.set_suffix('.tar.gz') - target, source = stripinstallbuilder(target, source, env) - target, source = putintopackageroot(target, source, env, PACKAGEROOT) - return bld(env, target, source, TARFLAGS='-zc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/tarxz.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/tarxz.py deleted file mode 100644 index 747296b38..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/tarxz.py +++ /dev/null @@ -1,44 +0,0 @@ -"""SCons.Tool.Packaging.tarxz - -The tarxz packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Tar'] - bld.set_suffix('.tar.xz') - target, source = putintopackageroot(target, source, env, PACKAGEROOT) - target, source = stripinstallbuilder(target, source, env) - return bld(env, target, source, TARFLAGS='-Jc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/packaging/zip.py b/scons/scons-local-4.1.0/SCons/Tool/packaging/zip.py deleted file mode 100644 index 1f76f1609..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/packaging/zip.py +++ /dev/null @@ -1,44 +0,0 @@ -"""SCons.Tool.Packaging.zip - -The zip SRC packager. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot - -def package(env, target, source, PACKAGEROOT, **kw): - bld = env['BUILDERS']['Zip'] - bld.set_suffix('.zip') - target, source = stripinstallbuilder(target, source, env) - target, source = putintopackageroot(target, source, env, PACKAGEROOT) - return bld(env, target, source) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/pdf.py b/scons/scons-local-4.1.0/SCons/Tool/pdf.py deleted file mode 100644 index 050f1a572..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/pdf.py +++ /dev/null @@ -1,78 +0,0 @@ -"""SCons.Tool.pdf - -Common PDF Builder definition for various other Tool modules that use it. -Add an explicit action to run epstopdf to convert .eps files to .pdf - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Builder -import SCons.Tool - -PDFBuilder = None - -EpsPdfAction = SCons.Action.Action('$EPSTOPDFCOM', '$EPSTOPDFCOMSTR') - -def generate(env): - try: - env['BUILDERS']['PDF'] - except KeyError: - global PDFBuilder - if PDFBuilder is None: - PDFBuilder = SCons.Builder.Builder(action = {}, - source_scanner = SCons.Tool.PDFLaTeXScanner, - prefix = '$PDFPREFIX', - suffix = '$PDFSUFFIX', - emitter = {}, - source_ext_match = None, - single_source=True) - env['BUILDERS']['PDF'] = PDFBuilder - - env['PDFPREFIX'] = '' - env['PDFSUFFIX'] = '.pdf' - -# put the epstopdf builder in this routine so we can add it after -# the pdftex builder so that one is the default for no source suffix -def generate2(env): - bld = env['BUILDERS']['PDF'] - #bld.add_action('.ps', EpsPdfAction) # this is covered by direct Ghostcript action in gs.py - bld.add_action('.eps', EpsPdfAction) - - env['EPSTOPDF'] = 'epstopdf' - env['EPSTOPDFFLAGS'] = SCons.Util.CLVar('') - env['EPSTOPDFCOM'] = '$EPSTOPDF $EPSTOPDFFLAGS ${SOURCE} --outfile=${TARGET}' - -def exists(env): - # This only puts a skeleton Builder in place, so if someone - # references this Tool directly, it's always "available." - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/pdflatex.py b/scons/scons-local-4.1.0/SCons/Tool/pdflatex.py deleted file mode 100644 index fbffb2395..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/pdflatex.py +++ /dev/null @@ -1,84 +0,0 @@ -"""SCons.Tool.pdflatex - -Tool-specific initialization for pdflatex. -Generates .pdf files from .latex or .ltx files - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Action -import SCons.Util -import SCons.Tool.pdf -import SCons.Tool.tex - -PDFLaTeXAction = None - -def PDFLaTeXAuxFunction(target = None, source= None, env=None): - result = SCons.Tool.tex.InternalLaTeXAuxAction( PDFLaTeXAction, target, source, env ) - if result != 0: - SCons.Tool.tex.check_file_error_message(env['PDFLATEX']) - return result - -PDFLaTeXAuxAction = None - -def generate(env): - """Add Builders and construction variables for pdflatex to an Environment.""" - global PDFLaTeXAction - if PDFLaTeXAction is None: - PDFLaTeXAction = SCons.Action.Action('$PDFLATEXCOM', '$PDFLATEXCOMSTR') - - global PDFLaTeXAuxAction - if PDFLaTeXAuxAction is None: - PDFLaTeXAuxAction = SCons.Action.Action(PDFLaTeXAuxFunction, - strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) - - env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) - - from . import pdf - pdf.generate(env) - - bld = env['BUILDERS']['PDF'] - bld.add_action('.ltx', PDFLaTeXAuxAction) - bld.add_action('.latex', PDFLaTeXAuxAction) - bld.add_emitter('.ltx', SCons.Tool.tex.tex_pdf_emitter) - bld.add_emitter('.latex', SCons.Tool.tex.tex_pdf_emitter) - - SCons.Tool.tex.generate_common(env) - -def exists(env): - SCons.Tool.tex.generate_darwin(env) - return env.Detect('pdflatex') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/pdftex.py b/scons/scons-local-4.1.0/SCons/Tool/pdftex.py deleted file mode 100644 index e9a0bda03..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/pdftex.py +++ /dev/null @@ -1,109 +0,0 @@ -"""SCons.Tool.pdftex - -Tool-specific initialization for pdftex. -Generates .pdf files from .tex files - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import SCons.Action -import SCons.Util -import SCons.Tool.tex - -PDFTeXAction = None - -# This action might be needed more than once if we are dealing with -# labels and bibtex. -PDFLaTeXAction = None - -def PDFLaTeXAuxAction(target = None, source= None, env=None): - result = SCons.Tool.tex.InternalLaTeXAuxAction( PDFLaTeXAction, target, source, env ) - return result - -def PDFTeXLaTeXFunction(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.""" - basedir = os.path.split(str(source[0]))[0] - abspath = os.path.abspath(basedir) - - if SCons.Tool.tex.is_LaTeX(source,env,abspath): - result = PDFLaTeXAuxAction(target,source,env) - if result != 0: - SCons.Tool.tex.check_file_error_message(env['PDFLATEX']) - else: - result = PDFTeXAction(target,source,env) - if result != 0: - SCons.Tool.tex.check_file_error_message(env['PDFTEX']) - return result - -PDFTeXLaTeXAction = None - -def generate(env): - """Add Builders and construction variables for pdftex to an Environment.""" - global PDFTeXAction - if PDFTeXAction is None: - PDFTeXAction = SCons.Action.Action('$PDFTEXCOM', '$PDFTEXCOMSTR') - - global PDFLaTeXAction - if PDFLaTeXAction is None: - PDFLaTeXAction = SCons.Action.Action("$PDFLATEXCOM", "$PDFLATEXCOMSTR") - - global PDFTeXLaTeXAction - if PDFTeXLaTeXAction is None: - PDFTeXLaTeXAction = SCons.Action.Action(PDFTeXLaTeXFunction, - strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) - - env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) - - from . import pdf - pdf.generate(env) - - bld = env['BUILDERS']['PDF'] - bld.add_action('.tex', PDFTeXLaTeXAction) - bld.add_emitter('.tex', SCons.Tool.tex.tex_pdf_emitter) - - # Add the epstopdf builder after the pdftex builder - # so pdftex is the default for no source suffix - pdf.generate2(env) - - SCons.Tool.tex.generate_common(env) - -def exists(env): - SCons.Tool.tex.generate_darwin(env) - return env.Detect('pdftex') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/python.py b/scons/scons-local-4.1.0/SCons/Tool/python.py deleted file mode 100644 index c61fc8d72..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/python.py +++ /dev/null @@ -1,49 +0,0 @@ -"""SCons.Tool.python - -Registers the Python scanner for the supported Python source file suffixes. - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Tool -from SCons.Scanner.Python import PythonScanner, PythonSuffixes - - -def generate(env): - """Hook the python builder and scanner into the environment.""" - for suffix in PythonSuffixes: - SCons.Tool.SourceFileScanner.add_scanner(suffix, PythonScanner) - - -def exists(env): - return True - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/qt.py b/scons/scons-local-4.1.0/SCons/Tool/qt.py deleted file mode 100644 index d8a51b23e..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/qt.py +++ /dev/null @@ -1,371 +0,0 @@ - -"""SCons.Tool.qt - -Tool-specific initialization for Qt. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path -import re - -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Scanner -import SCons.Tool -import SCons.Util -import SCons.Tool.cxx -cplusplus = SCons.Tool.cxx - -class ToolQtWarning(SCons.Warnings.SConsWarning): - pass - -class GeneratedMocFileNotIncluded(ToolQtWarning): - pass - -class QtdirNotFound(ToolQtWarning): - pass - -SCons.Warnings.enableWarningClass(ToolQtWarning) - -header_extensions = [".h", ".hxx", ".hpp", ".hh"] -if SCons.Util.case_sensitive_suffixes('.h', '.H'): - header_extensions.append('.H') - -cxx_suffixes = cplusplus.CXXSuffixes - - -def find_platform_specific_qt_paths(): - """ - find non-standard QT paths - - If the platform does not put QT tools in standard search paths, - the path is expected to be set using QTDIR. SCons violates - the normal rule of not pulling from the user's environment - in this case. However, some test cases try to validate what - happens when QTDIR is unset, so we need to try to make a guess. - - :return: a guess at a path - """ - - # qt_bin_dirs = [] - qt_bin_dir = None - if os.path.isfile('/etc/redhat-release'): - with open('/etc/redhat-release','r') as rr: - lines = rr.readlines() - distro = lines[0].split()[0] - if distro == 'CentOS': - # Centos installs QT under /usr/{lib,lib64}/qt{4,5,-3.3}/bin - # so we need to handle this differently - # qt_bin_dirs = glob.glob('/usr/lib64/qt*/bin') - # TODO: all current Fedoras do the same, need to look deeper here. - qt_bin_dir = '/usr/lib64/qt-3.3/bin' - - return qt_bin_dir - - -QT_BIN_DIR = find_platform_specific_qt_paths() - -def checkMocIncluded(target, source, env): - moc = target[0] - cpp = source[0] - # looks like cpp.includes is cleared before the build stage :-( - # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/ - path = SCons.Defaults.CScan.path(env, moc.cwd) - includes = SCons.Defaults.CScan(cpp, env, path) - if moc not in includes: - SCons.Warnings.warn( - GeneratedMocFileNotIncluded, - "Generated moc file '%s' is not included by '%s'" % - (str(moc), str(cpp))) - -def find_file(filename, paths, node_factory): - for dir in paths: - node = node_factory(filename, dir) - if node.rexists(): - return node - return None - -class _Automoc: - """ - Callable class, which works as an emitter for Programs, SharedLibraries and - StaticLibraries. - """ - - def __init__(self, objBuilderName): - self.objBuilderName = objBuilderName - - def __call__(self, target, source, env): - """ - Smart autoscan function. Gets the list of objects for the Program - or Lib. Adds objects and builders for the special qt files. - """ - try: - if int(env.subst('$QT_AUTOSCAN')) == 0: - return target, source - except ValueError: - pass - try: - debug = int(env.subst('$QT_DEBUG')) - except ValueError: - debug = 0 - - # some shortcuts used in the scanner - splitext = SCons.Util.splitext - objBuilder = getattr(env, self.objBuilderName) - - # some regular expressions: - # Q_OBJECT detection - q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') - # cxx and c comment 'eater' - #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)') - # CW: something must be wrong with the regexp. See also bug #998222 - # CURRENTLY THERE IS NO TEST CASE FOR THAT - - # The following is kind of hacky to get builders working properly (FIXME) - objBuilderEnv = objBuilder.env - objBuilder.env = env - mocBuilderEnv = env.Moc.env - env.Moc.env = env - - # make a deep copy for the result; MocH objects will be appended - out_sources = source[:] - - for obj in source: - if not obj.has_builder(): - # binary obj file provided - if debug: - print("scons: qt: '%s' seems to be a binary. Discarded." % str(obj)) - continue - cpp = obj.sources[0] - if not splitext(str(cpp))[1] in cxx_suffixes: - if debug: - print("scons: qt: '%s' is no cxx file. Discarded." % str(cpp)) - # c or fortran source - continue - #cpp_contents = comment.sub('', cpp.get_text_contents()) - if debug: - print("scons: qt: Getting contents of %s" % cpp) - cpp_contents = cpp.get_text_contents() - h=None - for h_ext in header_extensions: - # try to find the header file in the corresponding source - # directory - hname = splitext(cpp.name)[0] + h_ext - h = find_file(hname, (cpp.get_dir(),), env.File) - if h: - if debug: - print("scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))) - #h_contents = comment.sub('', h.get_text_contents()) - h_contents = h.get_text_contents() - break - if not h and debug: - print("scons: qt: no header for '%s'." % (str(cpp))) - if h and q_object_search.search(h_contents): - # h file with the Q_OBJECT macro found -> add moc_cpp - moc_cpp = env.Moc(h) - moc_o = objBuilder(moc_cpp) - out_sources.append(moc_o) - #moc_cpp.target_scanner = SCons.Defaults.CScan - if debug: - print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp))) - if cpp and q_object_search.search(cpp_contents): - # cpp file with Q_OBJECT macro found -> add moc - # (to be included in cpp) - moc = env.Moc(cpp) - env.Ignore(moc, moc) - if debug: - print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc))) - #moc.source_scanner = SCons.Defaults.CScan - # restore the original env attributes (FIXME) - objBuilder.env = objBuilderEnv - env.Moc.env = mocBuilderEnv - - return (target, out_sources) - -AutomocShared = _Automoc('SharedObject') -AutomocStatic = _Automoc('StaticObject') - -def _detect(env): - """Not really safe, but fast method to detect the QT library""" - - QTDIR = env.get('QTDIR',None) - if not QTDIR: - QTDIR = os.environ.get('QTDIR',None) - if not QTDIR: - moc = env.WhereIs('moc') or env.WhereIs('moc',QT_BIN_DIR) - if moc: - QTDIR = os.path.dirname(os.path.dirname(moc)) - SCons.Warnings.warn( - QtdirNotFound, - "Could not detect qt, using moc executable as a hint (QTDIR=%s)" % QTDIR) - else: - QTDIR = None - SCons.Warnings.warn( - QtdirNotFound, - "Could not detect qt, using empty QTDIR") - return QTDIR - -def uicEmitter(target, source, env): - adjustixes = SCons.Util.adjustixes - bs = SCons.Util.splitext(str(source[0].name))[0] - bs = os.path.join(str(target[0].get_dir()),bs) - # first target (header) is automatically added by builder - if len(target) < 2: - # second target is implementation - target.append(adjustixes(bs, - env.subst('$QT_UICIMPLPREFIX'), - env.subst('$QT_UICIMPLSUFFIX'))) - if len(target) < 3: - # third target is moc file - target.append(adjustixes(bs, - env.subst('$QT_MOCHPREFIX'), - env.subst('$QT_MOCHSUFFIX'))) - return target, source - -def uicScannerFunc(node, env, path): - lookout = [] - lookout.extend(env['CPPPATH']) - lookout.append(str(node.rfile().dir)) - includes = re.findall("(.*?)", node.get_text_contents()) - result = [] - for incFile in includes: - dep = env.FindFile(incFile,lookout) - if dep: - result.append(dep) - return result - -uicScanner = SCons.Scanner.Base(uicScannerFunc, - name = "UicScanner", - node_class = SCons.Node.FS.File, - node_factory = SCons.Node.FS.File, - recursive = 0) - -def generate(env): - """Add Builders and construction variables for qt to an Environment.""" - CLVar = SCons.Util.CLVar - Action = SCons.Action.Action - Builder = SCons.Builder.Builder - - env.SetDefault(QTDIR = _detect(env), - QT_BINPATH = os.path.join('$QTDIR', 'bin'), - QT_CPPPATH = os.path.join('$QTDIR', 'include'), - QT_LIBPATH = os.path.join('$QTDIR', 'lib'), - QT_MOC = os.path.join('$QT_BINPATH','moc'), - QT_UIC = os.path.join('$QT_BINPATH','uic'), - QT_LIB = 'qt', # may be set to qt-mt - - QT_AUTOSCAN = 1, # scan for moc'able sources - - # Some QT specific flags. I don't expect someone wants to - # manipulate those ... - QT_UICIMPLFLAGS = CLVar(''), - QT_UICDECLFLAGS = CLVar(''), - QT_MOCFROMHFLAGS = CLVar(''), - QT_MOCFROMCXXFLAGS = CLVar('-i'), - - # suffixes/prefixes for the headers / sources to generate - QT_UICDECLPREFIX = '', - QT_UICDECLSUFFIX = '.h', - QT_UICIMPLPREFIX = 'uic_', - QT_UICIMPLSUFFIX = '$CXXFILESUFFIX', - QT_MOCHPREFIX = 'moc_', - QT_MOCHSUFFIX = '$CXXFILESUFFIX', - QT_MOCCXXPREFIX = '', - QT_MOCCXXSUFFIX = '.moc', - QT_UISUFFIX = '.ui', - - # Commands for the qt support ... - # command to generate header, implementation and moc-file - # from a .ui file - QT_UICCOM = [ - CLVar('$QT_UIC $QT_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'), - CLVar('$QT_UIC $QT_UICIMPLFLAGS -impl ${TARGETS[0].file} ' - '-o ${TARGETS[1]} $SOURCE'), - CLVar('$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[2]} ${TARGETS[0]}')], - # command to generate meta object information for a class - # declarated in a header - QT_MOCFROMHCOM = ( - '$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE'), - # command to generate meta object information for a class - # declarated in a cpp file - QT_MOCFROMCXXCOM = [ - CLVar('$QT_MOC $QT_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'), - Action(checkMocIncluded,None)]) - - # ... and the corresponding builders - uicBld = Builder(action=SCons.Action.Action('$QT_UICCOM', '$QT_UICCOMSTR'), - emitter=uicEmitter, - src_suffix='$QT_UISUFFIX', - suffix='$QT_UICDECLSUFFIX', - prefix='$QT_UICDECLPREFIX', - source_scanner=uicScanner) - mocBld = Builder(action={}, prefix={}, suffix={}) - for h in header_extensions: - act = SCons.Action.Action('$QT_MOCFROMHCOM', '$QT_MOCFROMHCOMSTR') - mocBld.add_action(h, act) - mocBld.prefix[h] = '$QT_MOCHPREFIX' - mocBld.suffix[h] = '$QT_MOCHSUFFIX' - for cxx in cxx_suffixes: - act = SCons.Action.Action('$QT_MOCFROMCXXCOM', '$QT_MOCFROMCXXCOMSTR') - mocBld.add_action(cxx, act) - mocBld.prefix[cxx] = '$QT_MOCCXXPREFIX' - mocBld.suffix[cxx] = '$QT_MOCCXXSUFFIX' - - # register the builders - env['BUILDERS']['Uic'] = uicBld - env['BUILDERS']['Moc'] = mocBld - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - static_obj.add_src_builder('Uic') - shared_obj.add_src_builder('Uic') - - # We use the emitters of Program / StaticLibrary / SharedLibrary - # to scan for moc'able files - # We can't refer to the builders directly, we have to fetch them - # as Environment attributes because that sets them up to be called - # correctly later by our emitter. - env.AppendUnique(PROGEMITTER =[AutomocStatic], - SHLIBEMITTER=[AutomocShared], - LDMODULEEMITTER=[AutomocShared], - LIBEMITTER =[AutomocStatic], - # Of course, we need to link against the qt libraries - CPPPATH=["$QT_CPPPATH"], - LIBPATH=["$QT_LIBPATH"], - LIBS=['$QT_LIB']) - -def exists(env): - return _detect(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/rmic.py b/scons/scons-local-4.1.0/SCons/Tool/rmic.py deleted file mode 100644 index 5c7a04066..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/rmic.py +++ /dev/null @@ -1,139 +0,0 @@ -"""SCons.Tool.rmic - -Tool-specific initialization for rmic. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path - -import SCons.Action -import SCons.Builder -import SCons.Node.FS -import SCons.Util - -from SCons.Tool.JavaCommon import get_java_install_dirs - - -def emit_rmic_classes(target, source, env): - """Create and return lists of Java RMI stub and skeleton - class files to be created from a set of class files. - """ - class_suffix = env.get('JAVACLASSSUFFIX', '.class') - classdir = env.get('JAVACLASSDIR') - - if not classdir: - try: - s = source[0] - except IndexError: - classdir = '.' - else: - try: - classdir = s.attributes.java_classdir - except AttributeError: - classdir = '.' - classdir = env.Dir(classdir).rdir() - if str(classdir) == '.': - c_ = None - else: - c_ = str(classdir) + os.sep - - slist = [] - for src in source: - try: - classname = src.attributes.java_classname - except AttributeError: - classname = str(src) - if c_ and classname[:len(c_)] == c_: - classname = classname[len(c_):] - if class_suffix and classname[:-len(class_suffix)] == class_suffix: - classname = classname[-len(class_suffix):] - s = src.rfile() - s.attributes.java_classdir = classdir - s.attributes.java_classname = classname - slist.append(s) - - stub_suffixes = ['_Stub'] - if env.get('JAVAVERSION') == '1.4': - stub_suffixes.append('_Skel') - - tlist = [] - for s in source: - for suff in stub_suffixes: - fname = s.attributes.java_classname.replace('.', os.sep) + \ - suff + class_suffix - t = target[0].File(fname) - t.attributes.java_lookupdir = target[0] - tlist.append(t) - - return tlist, source - -RMICAction = SCons.Action.Action('$RMICCOM', '$RMICCOMSTR') - -RMICBuilder = SCons.Builder.Builder(action = RMICAction, - emitter = emit_rmic_classes, - src_suffix = '$JAVACLASSSUFFIX', - target_factory = SCons.Node.FS.Dir, - source_factory = SCons.Node.FS.File) - -def generate(env): - """Add Builders and construction variables for rmic to an Environment.""" - env['BUILDERS']['RMIC'] = RMICBuilder - - if env['PLATFORM'] == 'win32': - version = env.get('JAVAVERSION', None) - # Ensure that we have a proper path for rmic - paths = get_java_install_dirs('win32', version=version) - rmic = SCons.Tool.find_program_path(env, 'rmic', default_paths=paths) - # print("RMIC: %s"%rmic) - if rmic: - rmic_bin_dir = os.path.dirname(rmic) - env.AppendENVPath('PATH', rmic_bin_dir) - - env['RMIC'] = 'rmic' - env['RMICFLAGS'] = SCons.Util.CLVar('') - env['RMICCOM'] = '$RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} -classpath ${SOURCE.attributes.java_classdir} ${SOURCES.attributes.java_classname}' - env['JAVACLASSSUFFIX'] = '.class' - -def exists(env): - # As reported by Jan Nijtmans in issue #2730, the simple - # return env.Detect('rmic') - # doesn't always work during initialization. For now, we - # stop trying to detect an executable (analogous to the - # javac Builder). - # TODO: Come up with a proper detect() routine...and enable it. - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/rpcgen.py b/scons/scons-local-4.1.0/SCons/Tool/rpcgen.py deleted file mode 100644 index 5ed565862..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/rpcgen.py +++ /dev/null @@ -1,70 +0,0 @@ -"""SCons.Tool.rpcgen - -Tool-specific initialization for RPCGEN tools. - -Three 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from SCons.Builder import Builder -import SCons.Util - -cmd = "cd ${SOURCE.dir} && $RPCGEN -%s $RPCGENFLAGS %s -o ${TARGET.abspath} ${SOURCE.file}" - -rpcgen_client = cmd % ('l', '$RPCGENCLIENTFLAGS') -rpcgen_header = cmd % ('h', '$RPCGENHEADERFLAGS') -rpcgen_service = cmd % ('m', '$RPCGENSERVICEFLAGS') -rpcgen_xdr = cmd % ('c', '$RPCGENXDRFLAGS') - -def generate(env): - """Add RPCGEN Builders and construction variables for an Environment.""" - - client = Builder(action=rpcgen_client, suffix='_clnt.c', src_suffix='.x') - header = Builder(action=rpcgen_header, suffix='.h', src_suffix='.x') - service = Builder(action=rpcgen_service, suffix='_svc.c', src_suffix='.x') - xdr = Builder(action=rpcgen_xdr, suffix='_xdr.c', src_suffix='.x') - env.Append(BUILDERS={'RPCGenClient' : client, - 'RPCGenHeader' : header, - 'RPCGenService' : service, - 'RPCGenXDR' : xdr}) - env['RPCGEN'] = 'rpcgen' - env['RPCGENFLAGS'] = SCons.Util.CLVar('') - env['RPCGENCLIENTFLAGS'] = SCons.Util.CLVar('') - env['RPCGENHEADERFLAGS'] = SCons.Util.CLVar('') - env['RPCGENSERVICEFLAGS'] = SCons.Util.CLVar('') - env['RPCGENXDRFLAGS'] = SCons.Util.CLVar('') - -def exists(env): - return env.Detect('rpcgen') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/rpm.py b/scons/scons-local-4.1.0/SCons/Tool/rpm.py deleted file mode 100644 index 2fd802a67..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/rpm.py +++ /dev/null @@ -1,133 +0,0 @@ -"""SCons.Tool.rpm - -Tool-specific initialization for rpm. - -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. - -The rpm tool calls the rpmbuild command. The first and only argument should a -tar.gz consisting of the source file and a specfile. -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import re -import shutil -import subprocess - -import SCons.Builder -import SCons.Node.FS -import SCons.Util -import SCons.Action -import SCons.Defaults - -def get_cmd(source, env): - tar_file_with_included_specfile = source - if SCons.Util.is_List(source): - tar_file_with_included_specfile = source[0] - return "%s %s %s"%(env['RPM'], env['RPMFLAGS'], - tar_file_with_included_specfile.get_abspath()) - -def build_rpm(target, source, env): - # create a temporary rpm build root. - tmpdir = os.path.join(os.path.dirname(target[0].get_abspath()), 'rpmtemp') - if os.path.exists(tmpdir): - shutil.rmtree(tmpdir) - - # now create the mandatory rpm directory structure. - for d in ['RPMS', 'SRPMS', 'SPECS', 'BUILD']: - os.makedirs(os.path.join(tmpdir, d)) - - # set the topdir as an rpmflag. - env.Prepend(RPMFLAGS = '--define \'_topdir %s\'' % tmpdir) - - # now call rpmbuild to create the rpm package. - handle = subprocess.Popen(get_cmd(source, env), - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - shell=True) - with handle.stdout: - output = SCons.Util.to_str(handle.stdout.read()) - status = handle.wait() - - if status: - raise SCons.Errors.BuildError(node=target[0], - errstr=output, - filename=str(target[0])) - else: - # XXX: assume that LC_ALL=C is set while running rpmbuild - output_files = re.compile('Wrote: (.*)').findall(output) - - for output, input in zip(output_files, target): - rpm_output = os.path.basename(output) - expected = os.path.basename(input.get_path()) - - assert expected == rpm_output, "got %s but expected %s" % (rpm_output, expected) - shutil.copy(output, input.get_abspath()) - - - # cleanup before leaving. - shutil.rmtree(tmpdir) - - return status - -def string_rpm(target, source, env): - try: - return env['RPMCOMSTR'] - except KeyError: - return get_cmd(source, env) - -rpmAction = SCons.Action.Action(build_rpm, string_rpm) - -RpmBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$RPMCOM', '$RPMCOMSTR'), - source_scanner = SCons.Defaults.DirScanner, - suffix = '$RPMSUFFIX') - - - -def generate(env): - """Add Builders and construction variables for rpm to an Environment.""" - try: - bld = env['BUILDERS']['Rpm'] - except KeyError: - bld = RpmBuilder - env['BUILDERS']['Rpm'] = bld - - env.SetDefault(RPM = 'LC_ALL=C rpmbuild') - env.SetDefault(RPMFLAGS = SCons.Util.CLVar('-ta')) - env.SetDefault(RPMCOM = rpmAction) - env.SetDefault(RPMSUFFIX = '.rpm') - -def exists(env): - return env.Detect('rpmbuild') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/rpmutils.py b/scons/scons-local-4.1.0/SCons/Tool/rpmutils.py deleted file mode 100644 index 2c4fb3220..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/rpmutils.py +++ /dev/null @@ -1,546 +0,0 @@ -"""SCons.Tool.rpmutils.py - -RPM specific helper routines for general usage in the test framework -and SCons core modules. - -Since we check for the RPM package target name in several places, -we have to know which machine/system name RPM will use for the current -hardware setup. The following dictionaries and functions try to -mimic the exact naming rules of the RPM source code. -They were directly derived from the file "rpmrc.in" of the version -rpm-4.9.1.3. For updating to a more recent version of RPM, this Python -script can be used standalone. The usage() function below shows the -exact syntax. - -""" - -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -import platform -import subprocess - -import SCons.Util - -# Start of rpmrc dictionaries (Marker, don't change or remove!) -os_canon = { - 'AIX' : ['AIX','5'], - 'AmigaOS' : ['AmigaOS','5'], - 'BSD_OS' : ['bsdi','12'], - 'CYGWIN32_95' : ['cygwin32','15'], - 'CYGWIN32_NT' : ['cygwin32','14'], - 'Darwin' : ['darwin','21'], - 'FreeBSD' : ['FreeBSD','8'], - 'HP-UX' : ['hpux10','6'], - 'IRIX' : ['Irix','2'], - 'IRIX64' : ['Irix64','10'], - 'Linux' : ['Linux','1'], - 'Linux/390' : ['OS/390','20'], - 'Linux/ESA' : ['VM/ESA','20'], - 'MacOSX' : ['macosx','21'], - 'MiNT' : ['FreeMiNT','17'], - 'NEXTSTEP' : ['NextStep','11'], - 'OS/390' : ['OS/390','18'], - 'OSF1' : ['osf1','7'], - 'SCO_SV' : ['SCO_SV3.2v5.0.2','9'], - 'SunOS4' : ['SunOS','4'], - 'SunOS5' : ['solaris','3'], - 'UNIX_SV' : ['MP_RAS','16'], - 'VM/ESA' : ['VM/ESA','19'], - 'machten' : ['machten','13'], - 'osf3.2' : ['osf1','7'], - 'osf4.0' : ['osf1','7'], -} - -buildarch_compat = { - 'alpha' : ['noarch'], - 'alphaev5' : ['alpha'], - 'alphaev56' : ['alphaev5'], - 'alphaev6' : ['alphapca56'], - 'alphaev67' : ['alphaev6'], - 'alphapca56' : ['alphaev56'], - 'amd64' : ['x86_64'], - 'armv3l' : ['noarch'], - 'armv4b' : ['noarch'], - 'armv4l' : ['armv3l'], - 'armv4tl' : ['armv4l'], - 'armv5tejl' : ['armv5tel'], - 'armv5tel' : ['armv4tl'], - 'armv6l' : ['armv5tejl'], - 'armv7l' : ['armv6l'], - 'atariclone' : ['m68kmint','noarch'], - 'atarist' : ['m68kmint','noarch'], - 'atariste' : ['m68kmint','noarch'], - 'ataritt' : ['m68kmint','noarch'], - 'athlon' : ['i686'], - 'falcon' : ['m68kmint','noarch'], - 'geode' : ['i586'], - 'hades' : ['m68kmint','noarch'], - 'hppa1.0' : ['parisc'], - 'hppa1.1' : ['hppa1.0'], - 'hppa1.2' : ['hppa1.1'], - 'hppa2.0' : ['hppa1.2'], - 'i386' : ['noarch','fat'], - 'i486' : ['i386'], - 'i586' : ['i486'], - 'i686' : ['i586'], - 'ia32e' : ['x86_64'], - 'ia64' : ['noarch'], - 'm68k' : ['noarch'], - 'milan' : ['m68kmint','noarch'], - 'mips' : ['noarch'], - 'mipsel' : ['noarch'], - 'parisc' : ['noarch'], - 'pentium3' : ['i686'], - 'pentium4' : ['pentium3'], - 'ppc' : ['noarch','fat'], - 'ppc32dy4' : ['noarch'], - 'ppc64' : ['noarch','fat'], - 'ppc64iseries' : ['ppc64'], - 'ppc64pseries' : ['ppc64'], - 'ppc8260' : ['noarch'], - 'ppc8560' : ['noarch'], - 'ppciseries' : ['noarch'], - 'ppcpseries' : ['noarch'], - 's390' : ['noarch'], - 's390x' : ['noarch'], - 'sh3' : ['noarch'], - 'sh4' : ['noarch'], - 'sh4a' : ['sh4'], - 'sparc' : ['noarch'], - 'sparc64' : ['sparcv9v'], - 'sparc64v' : ['sparc64'], - 'sparcv8' : ['sparc'], - 'sparcv9' : ['sparcv8'], - 'sparcv9v' : ['sparcv9'], - 'sun4c' : ['noarch'], - 'sun4d' : ['noarch'], - 'sun4m' : ['noarch'], - 'sun4u' : ['noarch'], - 'x86_64' : ['noarch'], -} - -os_compat = { - 'BSD_OS' : ['bsdi'], - 'Darwin' : ['MacOSX'], - 'FreeMiNT' : ['mint','MiNT','TOS'], - 'IRIX64' : ['IRIX'], - 'MiNT' : ['FreeMiNT','mint','TOS'], - 'TOS' : ['FreeMiNT','MiNT','mint'], - 'bsdi4.0' : ['bsdi'], - 'hpux10.00' : ['hpux9.07'], - 'hpux10.01' : ['hpux10.00'], - 'hpux10.10' : ['hpux10.01'], - 'hpux10.20' : ['hpux10.10'], - 'hpux10.30' : ['hpux10.20'], - 'hpux11.00' : ['hpux10.30'], - 'hpux9.05' : ['hpux9.04'], - 'hpux9.07' : ['hpux9.05'], - 'mint' : ['FreeMiNT','MiNT','TOS'], - 'ncr-sysv4.3' : ['ncr-sysv4.2'], - 'osf4.0' : ['osf3.2','osf1'], - 'solaris2.4' : ['solaris2.3'], - 'solaris2.5' : ['solaris2.3','solaris2.4'], - 'solaris2.6' : ['solaris2.3','solaris2.4','solaris2.5'], - 'solaris2.7' : ['solaris2.3','solaris2.4','solaris2.5','solaris2.6'], -} - -arch_compat = { - 'alpha' : ['axp','noarch'], - 'alphaev5' : ['alpha'], - 'alphaev56' : ['alphaev5'], - 'alphaev6' : ['alphapca56'], - 'alphaev67' : ['alphaev6'], - 'alphapca56' : ['alphaev56'], - 'amd64' : ['x86_64','athlon','noarch'], - 'armv3l' : ['noarch'], - 'armv4b' : ['noarch'], - 'armv4l' : ['armv3l'], - 'armv4tl' : ['armv4l'], - 'armv5tejl' : ['armv5tel'], - 'armv5tel' : ['armv4tl'], - 'armv6l' : ['armv5tejl'], - 'armv7l' : ['armv6l'], - 'atariclone' : ['m68kmint','noarch'], - 'atarist' : ['m68kmint','noarch'], - 'atariste' : ['m68kmint','noarch'], - 'ataritt' : ['m68kmint','noarch'], - 'athlon' : ['i686'], - 'falcon' : ['m68kmint','noarch'], - 'geode' : ['i586'], - 'hades' : ['m68kmint','noarch'], - 'hppa1.0' : ['parisc'], - 'hppa1.1' : ['hppa1.0'], - 'hppa1.2' : ['hppa1.1'], - 'hppa2.0' : ['hppa1.2'], - 'i370' : ['noarch'], - 'i386' : ['noarch','fat'], - 'i486' : ['i386'], - 'i586' : ['i486'], - 'i686' : ['i586'], - 'ia32e' : ['x86_64','athlon','noarch'], - 'ia64' : ['noarch'], - 'milan' : ['m68kmint','noarch'], - 'mips' : ['noarch'], - 'mipsel' : ['noarch'], - 'osfmach3_i386' : ['i486'], - 'osfmach3_i486' : ['i486','osfmach3_i386'], - 'osfmach3_i586' : ['i586','osfmach3_i486'], - 'osfmach3_i686' : ['i686','osfmach3_i586'], - 'osfmach3_ppc' : ['ppc'], - 'parisc' : ['noarch'], - 'pentium3' : ['i686'], - 'pentium4' : ['pentium3'], - 'powerpc' : ['ppc'], - 'powerppc' : ['ppc'], - 'ppc' : ['rs6000'], - 'ppc32dy4' : ['ppc'], - 'ppc64' : ['ppc'], - 'ppc64iseries' : ['ppc64'], - 'ppc64pseries' : ['ppc64'], - 'ppc8260' : ['ppc'], - 'ppc8560' : ['ppc'], - 'ppciseries' : ['ppc'], - 'ppcpseries' : ['ppc'], - 'rs6000' : ['noarch','fat'], - 's390' : ['noarch'], - 's390x' : ['s390','noarch'], - 'sh3' : ['noarch'], - 'sh4' : ['noarch'], - 'sh4a' : ['sh4'], - 'sparc' : ['noarch'], - 'sparc64' : ['sparcv9'], - 'sparc64v' : ['sparc64'], - 'sparcv8' : ['sparc'], - 'sparcv9' : ['sparcv8'], - 'sparcv9v' : ['sparcv9'], - 'sun4c' : ['sparc'], - 'sun4d' : ['sparc'], - 'sun4m' : ['sparc'], - 'sun4u' : ['sparc64'], - 'x86_64' : ['amd64','athlon','noarch'], -} - -buildarchtranslate = { - 'alphaev5' : ['alpha'], - 'alphaev56' : ['alpha'], - 'alphaev6' : ['alpha'], - 'alphaev67' : ['alpha'], - 'alphapca56' : ['alpha'], - 'amd64' : ['x86_64'], - 'armv3l' : ['armv3l'], - 'armv4b' : ['armv4b'], - 'armv4l' : ['armv4l'], - 'armv4tl' : ['armv4tl'], - 'armv5tejl' : ['armv5tejl'], - 'armv5tel' : ['armv5tel'], - 'armv6l' : ['armv6l'], - 'armv7l' : ['armv7l'], - 'atariclone' : ['m68kmint'], - 'atarist' : ['m68kmint'], - 'atariste' : ['m68kmint'], - 'ataritt' : ['m68kmint'], - 'athlon' : ['i386'], - 'falcon' : ['m68kmint'], - 'geode' : ['i386'], - 'hades' : ['m68kmint'], - 'i386' : ['i386'], - 'i486' : ['i386'], - 'i586' : ['i386'], - 'i686' : ['i386'], - 'ia32e' : ['x86_64'], - 'ia64' : ['ia64'], - 'milan' : ['m68kmint'], - 'osfmach3_i386' : ['i386'], - 'osfmach3_i486' : ['i386'], - 'osfmach3_i586' : ['i386'], - 'osfmach3_i686' : ['i386'], - 'osfmach3_ppc' : ['ppc'], - 'pentium3' : ['i386'], - 'pentium4' : ['i386'], - 'powerpc' : ['ppc'], - 'powerppc' : ['ppc'], - 'ppc32dy4' : ['ppc'], - 'ppc64iseries' : ['ppc64'], - 'ppc64pseries' : ['ppc64'], - 'ppc8260' : ['ppc'], - 'ppc8560' : ['ppc'], - 'ppciseries' : ['ppc'], - 'ppcpseries' : ['ppc'], - 's390' : ['s390'], - 's390x' : ['s390x'], - 'sh3' : ['sh3'], - 'sh4' : ['sh4'], - 'sh4a' : ['sh4'], - 'sparc64v' : ['sparc64'], - 'sparcv8' : ['sparc'], - 'sparcv9' : ['sparc'], - 'sparcv9v' : ['sparc'], - 'sun4c' : ['sparc'], - 'sun4d' : ['sparc'], - 'sun4m' : ['sparc'], - 'sun4u' : ['sparc64'], - 'x86_64' : ['x86_64'], -} - -optflags = { - 'alpha' : ['-O2','-g','-mieee'], - 'alphaev5' : ['-O2','-g','-mieee','-mtune=ev5'], - 'alphaev56' : ['-O2','-g','-mieee','-mtune=ev56'], - 'alphaev6' : ['-O2','-g','-mieee','-mtune=ev6'], - 'alphaev67' : ['-O2','-g','-mieee','-mtune=ev67'], - 'alphapca56' : ['-O2','-g','-mieee','-mtune=pca56'], - 'amd64' : ['-O2','-g'], - 'armv3l' : ['-O2','-g','-march=armv3'], - 'armv4b' : ['-O2','-g','-march=armv4'], - 'armv4l' : ['-O2','-g','-march=armv4'], - 'armv4tl' : ['-O2','-g','-march=armv4t'], - 'armv5tejl' : ['-O2','-g','-march=armv5te'], - 'armv5tel' : ['-O2','-g','-march=armv5te'], - 'armv6l' : ['-O2','-g','-march=armv6'], - 'armv7l' : ['-O2','-g','-march=armv7'], - 'atariclone' : ['-O2','-g','-fomit-frame-pointer'], - 'atarist' : ['-O2','-g','-fomit-frame-pointer'], - 'atariste' : ['-O2','-g','-fomit-frame-pointer'], - 'ataritt' : ['-O2','-g','-fomit-frame-pointer'], - 'athlon' : ['-O2','-g','-march=athlon'], - 'falcon' : ['-O2','-g','-fomit-frame-pointer'], - 'fat' : ['-O2','-g','-arch','i386','-arch','ppc'], - 'geode' : ['-Os','-g','-m32','-march=geode'], - 'hades' : ['-O2','-g','-fomit-frame-pointer'], - 'hppa1.0' : ['-O2','-g','-mpa-risc-1-0'], - 'hppa1.1' : ['-O2','-g','-mpa-risc-1-0'], - 'hppa1.2' : ['-O2','-g','-mpa-risc-1-0'], - 'hppa2.0' : ['-O2','-g','-mpa-risc-1-0'], - 'i386' : ['-O2','-g','-march=i386','-mtune=i686'], - 'i486' : ['-O2','-g','-march=i486'], - 'i586' : ['-O2','-g','-march=i586'], - 'i686' : ['-O2','-g','-march=i686'], - 'ia32e' : ['-O2','-g'], - 'ia64' : ['-O2','-g'], - 'm68k' : ['-O2','-g','-fomit-frame-pointer'], - 'milan' : ['-O2','-g','-fomit-frame-pointer'], - 'mips' : ['-O2','-g'], - 'mipsel' : ['-O2','-g'], - 'parisc' : ['-O2','-g','-mpa-risc-1-0'], - 'pentium3' : ['-O2','-g','-march=pentium3'], - 'pentium4' : ['-O2','-g','-march=pentium4'], - 'ppc' : ['-O2','-g','-fsigned-char'], - 'ppc32dy4' : ['-O2','-g','-fsigned-char'], - 'ppc64' : ['-O2','-g','-fsigned-char'], - 'ppc8260' : ['-O2','-g','-fsigned-char'], - 'ppc8560' : ['-O2','-g','-fsigned-char'], - 'ppciseries' : ['-O2','-g','-fsigned-char'], - 'ppcpseries' : ['-O2','-g','-fsigned-char'], - 's390' : ['-O2','-g'], - 's390x' : ['-O2','-g'], - 'sh3' : ['-O2','-g'], - 'sh4' : ['-O2','-g','-mieee'], - 'sh4a' : ['-O2','-g','-mieee'], - 'sparc' : ['-O2','-g','-m32','-mtune=ultrasparc'], - 'sparc64' : ['-O2','-g','-m64','-mtune=ultrasparc'], - 'sparc64v' : ['-O2','-g','-m64','-mtune=niagara'], - 'sparcv8' : ['-O2','-g','-m32','-mtune=ultrasparc','-mv8'], - 'sparcv9' : ['-O2','-g','-m32','-mtune=ultrasparc'], - 'sparcv9v' : ['-O2','-g','-m32','-mtune=niagara'], - 'x86_64' : ['-O2','-g'], -} - -arch_canon = { - 'IP' : ['sgi','7'], - 'alpha' : ['alpha','2'], - 'alphaev5' : ['alphaev5','2'], - 'alphaev56' : ['alphaev56','2'], - 'alphaev6' : ['alphaev6','2'], - 'alphaev67' : ['alphaev67','2'], - 'alphapca56' : ['alphapca56','2'], - 'amd64' : ['amd64','1'], - 'armv3l' : ['armv3l','12'], - 'armv4b' : ['armv4b','12'], - 'armv4l' : ['armv4l','12'], - 'armv5tejl' : ['armv5tejl','12'], - 'armv5tel' : ['armv5tel','12'], - 'armv6l' : ['armv6l','12'], - 'armv7l' : ['armv7l','12'], - 'atariclone' : ['m68kmint','13'], - 'atarist' : ['m68kmint','13'], - 'atariste' : ['m68kmint','13'], - 'ataritt' : ['m68kmint','13'], - 'athlon' : ['athlon','1'], - 'falcon' : ['m68kmint','13'], - 'geode' : ['geode','1'], - 'hades' : ['m68kmint','13'], - 'i370' : ['i370','14'], - 'i386' : ['i386','1'], - 'i486' : ['i486','1'], - 'i586' : ['i586','1'], - 'i686' : ['i686','1'], - 'ia32e' : ['ia32e','1'], - 'ia64' : ['ia64','9'], - 'm68k' : ['m68k','6'], - 'm68kmint' : ['m68kmint','13'], - 'milan' : ['m68kmint','13'], - 'mips' : ['mips','4'], - 'mipsel' : ['mipsel','11'], - 'pentium3' : ['pentium3','1'], - 'pentium4' : ['pentium4','1'], - 'ppc' : ['ppc','5'], - 'ppc32dy4' : ['ppc32dy4','5'], - 'ppc64' : ['ppc64','16'], - 'ppc64iseries' : ['ppc64iseries','16'], - 'ppc64pseries' : ['ppc64pseries','16'], - 'ppc8260' : ['ppc8260','5'], - 'ppc8560' : ['ppc8560','5'], - 'ppciseries' : ['ppciseries','5'], - 'ppcpseries' : ['ppcpseries','5'], - 'rs6000' : ['rs6000','8'], - 's390' : ['s390','14'], - 's390x' : ['s390x','15'], - 'sh' : ['sh','17'], - 'sh3' : ['sh3','17'], - 'sh4' : ['sh4','17'], - 'sh4a' : ['sh4a','17'], - 'sparc' : ['sparc','3'], - 'sparc64' : ['sparc64','2'], - 'sparc64v' : ['sparc64v','2'], - 'sparcv8' : ['sparcv8','3'], - 'sparcv9' : ['sparcv9','3'], - 'sparcv9v' : ['sparcv9v','3'], - 'sun4' : ['sparc','3'], - 'sun4c' : ['sparc','3'], - 'sun4d' : ['sparc','3'], - 'sun4m' : ['sparc','3'], - 'sun4u' : ['sparc64','2'], - 'x86_64' : ['x86_64','1'], - 'xtensa' : ['xtensa','18'], -} - -# End of rpmrc dictionaries (Marker, don't change or remove!) - -def defaultMachine(use_rpm_default=True): - """ Return the canonicalized machine name. """ - - if use_rpm_default: - try: - # This should be the most reliable way to get the default arch - rmachine = subprocess.check_output(['rpm', '--eval=%_target_cpu'], shell=False).rstrip() - rmachine = SCons.Util.to_str(rmachine) - except Exception as e: - # Something went wrong, try again by looking up platform.machine() - return defaultMachine(False) - else: - rmachine = platform.machine() - - # Try to lookup the string in the canon table - if rmachine in arch_canon: - rmachine = arch_canon[rmachine][0] - - return rmachine - -def defaultSystem(): - """ Return the canonicalized system name. """ - rsystem = platform.system() - - # Try to lookup the string in the canon tables - if rsystem in os_canon: - rsystem = os_canon[rsystem][0] - - return rsystem - -def defaultNames(): - """ Return the canonicalized machine and system name. """ - return defaultMachine(), defaultSystem() - -def updateRpmDicts(rpmrc, pyfile): - """ Read the given rpmrc file with RPM definitions and update the - info dictionaries in the file pyfile with it. - The arguments will usually be 'rpmrc.in' from a recent RPM source - tree, and 'rpmutils.py' referring to this script itself. - See also usage() below. - """ - try: - # Read old rpmutils.py file - with open(pyfile,"r") as f: - oldpy = f.readlines() - # Read current rpmrc.in file - with open(rpmrc,"r") as f: - rpm = f.readlines() - # Parse for data - data = {} - # Allowed section names that get parsed - sections = ['optflags', - 'arch_canon', - 'os_canon', - 'buildarchtranslate', - 'arch_compat', - 'os_compat', - 'buildarch_compat'] - for l in rpm: - l = l.rstrip('\n').replace(':',' ') - # Skip comments - if l.lstrip().startswith('#'): - continue - tokens = l.strip().split() - if len(tokens): - key = tokens[0] - if key in sections: - # Have we met this section before? - if tokens[0] not in data: - # No, so insert it - data[key] = {} - # Insert data - data[key][tokens[1]] = tokens[2:] - # Write new rpmutils.py file - with open(pyfile,"w") as out: - pm = 0 - for l in oldpy: - if pm: - if l.startswith('# End of rpmrc dictionaries'): - pm = 0 - out.write(l) - else: - out.write(l) - if l.startswith('# Start of rpmrc dictionaries'): - pm = 1 - # Write data sections to single dictionaries - for key, entries in data.items(): - out.write("%s = {\n" % key) - for arch in sorted(entries.keys()): - out.write(" '%s' : ['%s'],\n" % (arch, "','".join(entries[arch]))) - out.write("}\n\n") - except: - pass - -def usage(): - print("rpmutils.py rpmrc.in rpmutils.py") - -def main(): - import sys - - if len(sys.argv) < 3: - usage() - sys.exit(0) - updateRpmDicts(sys.argv[1], sys.argv[2]) - -if __name__ == "__main__": - main() diff --git a/scons/scons-local-4.1.0/SCons/Tool/sgiar.py b/scons/scons-local-4.1.0/SCons/Tool/sgiar.py deleted file mode 100644 index 54f8b7b67..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sgiar.py +++ /dev/null @@ -1,68 +0,0 @@ -"""SCons.Tool.sgiar - -Tool-specific initialization for SGI ar (library archive). If CC -exists, static libraries should be built with it, so the prelinker has -a chance to resolve C++ template instantiations. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util - -def generate(env): - """Add Builders and construction variables for ar to an Environment.""" - SCons.Tool.createStaticLibBuilder(env) - - if env.Detect('CC'): - env['AR'] = 'CC' - env['ARFLAGS'] = SCons.Util.CLVar('-ar') - env['ARCOM'] = '$AR $ARFLAGS -o $TARGET $SOURCES' - else: - env['AR'] = 'ar' - env['ARFLAGS'] = SCons.Util.CLVar('r') - env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES' - - env['SHLINK'] = '$LINK' - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') - env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - env['LIBPREFIX'] = 'lib' - env['LIBSUFFIX'] = '.a' - -def exists(env): - return env.Detect('CC') or env.Detect('ar') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sgic++.py b/scons/scons-local-4.1.0/SCons/Tool/sgic++.py deleted file mode 100644 index 63c66e26e..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sgic++.py +++ /dev/null @@ -1,43 +0,0 @@ -"""SCons.Tool.sgic++ - -Tool-specific initialization for MIPSpro C++ on SGI. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -#forward proxy to the preffered cxx version -from SCons.Tool.sgicxx import * - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sgicc.py b/scons/scons-local-4.1.0/SCons/Tool/sgicc.py deleted file mode 100644 index 94a049769..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sgicc.py +++ /dev/null @@ -1,53 +0,0 @@ -"""SCons.Tool.sgicc - -Tool-specific initialization for MIPSPro cc on SGI. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -from . import cc - -def generate(env): - """Add Builders and construction variables for gcc to an Environment.""" - cc.generate(env) - - env['CXX'] = 'CC' - env['SHOBJSUFFIX'] = '.o' - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 - -def exists(env): - return env.Detect('cc') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sgicxx.py b/scons/scons-local-4.1.0/SCons/Tool/sgicxx.py deleted file mode 100644 index 48b04ea92..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sgicxx.py +++ /dev/null @@ -1,61 +0,0 @@ -"""SCons.Tool.sgic++ - -Tool-specific initialization for MIPSpro C++ on SGI. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Util - -import SCons.Tool.cxx -cplusplus = SCons.Tool.cxx -#cplusplus = __import__('cxx', globals(), locals(), []) - - -def generate(env): - """Add Builders and construction variables for SGI MIPS C++ to an Environment.""" - - cplusplus.generate(env) - - env['CXX'] = 'CC' - env['CXXFLAGS'] = SCons.Util.CLVar('-LANG:std') - env['SHCXX'] = '$CXX' - env['SHOBJSUFFIX'] = '.o' - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 - -def exists(env): - return env.Detect('CC') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sgilink.py b/scons/scons-local-4.1.0/SCons/Tool/sgilink.py deleted file mode 100644 index e92c7b991..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sgilink.py +++ /dev/null @@ -1,59 +0,0 @@ -"""SCons.Tool.sgilink - -Tool-specific initialization for the SGI MIPSPro linker on SGI. - -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. - -""" - -# -# 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. -# - - -import SCons.Util - -from . import link - -linkers = ['CC', 'cc'] - -def generate(env): - """Add Builders and construction variables for MIPSPro to an Environment.""" - link.generate(env) - - env['LINK'] = env.Detect(linkers) or 'cc' - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') - - # __RPATH is set to $_RPATH in the platform specification if that - # platform supports it. - env['RPATHPREFIX'] = '-rpath ' - env['RPATHSUFFIX'] = '' - env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' - -def exists(env): - return env.Detect(linkers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sunar.py b/scons/scons-local-4.1.0/SCons/Tool/sunar.py deleted file mode 100644 index 266e91493..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sunar.py +++ /dev/null @@ -1,64 +0,0 @@ -"""SCons.Tool.sunar - -Tool-specific initialization for Solaris (Forte) ar (library archive). If CC -exists, static libraries should be built with it, so that template -instantiations can be resolved. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Defaults -import SCons.Tool -import SCons.Util - -def generate(env): - """Add Builders and construction variables for ar to an Environment.""" - SCons.Tool.createStaticLibBuilder(env) - - if env.Detect('CC'): - env['AR'] = 'CC' - env['ARFLAGS'] = SCons.Util.CLVar('-xar') - env['ARCOM'] = '$AR $ARFLAGS -o $TARGET $SOURCES' - else: - env['AR'] = 'ar' - env['ARFLAGS'] = SCons.Util.CLVar('r') - env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES' - - env['LIBPREFIX'] = 'lib' - env['LIBSUFFIX'] = '.a' - -def exists(env): - return env.Detect('CC') or env.Detect('ar') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sunc++.py b/scons/scons-local-4.1.0/SCons/Tool/sunc++.py deleted file mode 100644 index 3304f8061..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sunc++.py +++ /dev/null @@ -1,45 +0,0 @@ -"""SCons.Tool.sunc++ - -Tool-specific initialization for C++ on SunOS / Solaris. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - - -#forward proxy to the preffered cxx version -from SCons.Tool.suncxx import * - - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/suncc.py b/scons/scons-local-4.1.0/SCons/Tool/suncc.py deleted file mode 100644 index 4651219bd..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/suncc.py +++ /dev/null @@ -1,58 +0,0 @@ -"""SCons.Tool.suncc - -Tool-specific initialization for Sun Solaris (Forte) CC and cc. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Util - -from . import cc - -def generate(env): - """ - Add Builders and construction variables for Forte C and C++ compilers - to an Environment. - """ - cc.generate(env) - - env['CXX'] = 'CC' - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -KPIC') - env['SHOBJPREFIX'] = 'so_' - env['SHOBJSUFFIX'] = '.o' - -def exists(env): - return env.Detect('CC') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/suncxx.py b/scons/scons-local-4.1.0/SCons/Tool/suncxx.py deleted file mode 100644 index 7c4b0941d..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/suncxx.py +++ /dev/null @@ -1,153 +0,0 @@ -"""SCons.Tool.sunc++ - -Tool-specific initialization for C++ on SunOS / Solaris. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons - -import os -import re -import subprocess - -import SCons.Tool.cxx -cplusplus = SCons.Tool.cxx -# cplusplus = __import__('c++', globals(), locals(), []) - -package_info = {} - - -def get_package_info(package_name, pkginfo, pkgchk): - try: - return package_info[package_name] - except KeyError: - version = None - pathname = None - from subprocess import DEVNULL - - try: - with open('/var/sadm/install/contents', 'r', encoding='UTF-8') as f: - sadm_contents = f.read() - except EnvironmentError: - pass - else: - sadm_re = re.compile(r'^(\S*/bin/CC)(=\S*)? %s$' % package_name, re.M) - sadm_match = sadm_re.search(sadm_contents) - if sadm_match: - pathname = os.path.dirname(sadm_match.group(1)) - - try: - p = subprocess.Popen([pkginfo, '-l', package_name], - universal_newlines=True, - stdout=subprocess.PIPE, - stderr=DEVNULL) - except EnvironmentError: - pass - else: - pkginfo_contents = p.communicate()[0] - version_re = re.compile(r'^ *VERSION:\s*(.*)$', re.M) - version_match = version_re.search(pkginfo_contents) - if version_match: - version = version_match.group(1) - - if pathname is None: - try: - p = subprocess.Popen([pkgchk, '-l', package_name], - universal_newlines=True, - stdout=subprocess.PIPE, - stderr=DEVNULL) - except EnvironmentError: - pass - else: - pkgchk_contents = p.communicate()[0] - pathname_re = re.compile(r'^Pathname:\s*(.*/bin/CC)$', re.M) - pathname_match = pathname_re.search(pkgchk_contents) - if pathname_match: - pathname = os.path.dirname(pathname_match.group(1)) - - package_info[package_name] = (pathname, version) - return package_info[package_name] - - -# use the package installer tool "pkg" to figure out where cppc and what -# version of it is installed -def get_cppc(env): - cxx = env.subst('$CXX') - if cxx: - cppcPath = os.path.dirname(cxx) - else: - cppcPath = None - - cppcVersion = None - - pkginfo = env.subst('$PKGINFO') - pkgchk = env.subst('$PKGCHK') - - for package in ['SPROcpl']: - path, version = get_package_info(package, pkginfo, pkgchk) - if path and version: - cppcPath, cppcVersion = path, version - break - - return (cppcPath, 'CC', 'CC', cppcVersion) - - -def generate(env): - """Add Builders and construction variables for SunPRO C++.""" - path, cxx, shcxx, version = get_cppc(env) - if path: - cxx = os.path.join(path, cxx) - shcxx = os.path.join(path, shcxx) - - cplusplus.generate(env) - - env['CXX'] = cxx - env['SHCXX'] = shcxx - env['CXXVERSION'] = version - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -KPIC') - env['SHOBJPREFIX'] = 'so_' - env['SHOBJSUFFIX'] = '.o' - - -def exists(env): - path, cxx, shcxx, version = get_cppc(env) - if path and cxx: - cppc = os.path.join(path, cxx) - if os.path.exists(cppc): - return cppc - return None - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sunf77.py b/scons/scons-local-4.1.0/SCons/Tool/sunf77.py deleted file mode 100644 index 20d18938f..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sunf77.py +++ /dev/null @@ -1,63 +0,0 @@ -"""SCons.Tool.sunf77 - -Tool-specific initialization for sunf77, the Sun Studio F77 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Util - -from .FortranCommon import add_all_to_env - -compilers = ['sunf77', 'f77'] - -def generate(env): - """Add Builders and construction variables for sunf77 to an Environment.""" - add_all_to_env(env) - - fcomp = env.Detect(compilers) or 'f77' - env['FORTRAN'] = fcomp - env['F77'] = fcomp - - env['SHFORTRAN'] = '$FORTRAN' - env['SHF77'] = '$F77' - - env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -KPIC') - env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS -KPIC') - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sunf90.py b/scons/scons-local-4.1.0/SCons/Tool/sunf90.py deleted file mode 100644 index ce1697c34..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sunf90.py +++ /dev/null @@ -1,64 +0,0 @@ -"""SCons.Tool.sunf90 - -Tool-specific initialization for sunf90, the Sun Studio F90 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Util - -from .FortranCommon import add_all_to_env - -compilers = ['sunf90', 'f90'] - -def generate(env): - """Add Builders and construction variables for sun f90 compiler to an - Environment.""" - add_all_to_env(env) - - fcomp = env.Detect(compilers) or 'f90' - env['FORTRAN'] = fcomp - env['F90'] = fcomp - - env['SHFORTRAN'] = '$FORTRAN' - env['SHF90'] = '$F90' - - env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -KPIC') - env['SHF90FLAGS'] = SCons.Util.CLVar('$F90FLAGS -KPIC') - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sunf95.py b/scons/scons-local-4.1.0/SCons/Tool/sunf95.py deleted file mode 100644 index 218569c0b..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sunf95.py +++ /dev/null @@ -1,64 +0,0 @@ -"""SCons.Tool.sunf95 - -Tool-specific initialization for sunf95, the Sun Studio F95 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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Util - -from .FortranCommon import add_all_to_env - -compilers = ['sunf95', 'f95'] - -def generate(env): - """Add Builders and construction variables for sunf95 to an - Environment.""" - add_all_to_env(env) - - fcomp = env.Detect(compilers) or 'f95' - env['FORTRAN'] = fcomp - env['F95'] = fcomp - - env['SHFORTRAN'] = '$FORTRAN' - env['SHF95'] = '$F95' - - env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -KPIC') - env['SHF95FLAGS'] = SCons.Util.CLVar('$F95FLAGS -KPIC') - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/sunlink.py b/scons/scons-local-4.1.0/SCons/Tool/sunlink.py deleted file mode 100644 index b0c9816e6..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/sunlink.py +++ /dev/null @@ -1,79 +0,0 @@ -"""SCons.Tool.sunlink - -Tool-specific initialization for the Sun Solaris (Forte) linker. - -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. -""" - -# -# MIT License -# -# Copyright 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. -# - -import os.path - -import SCons.Util -from . import link - -ccLinker = None - -# search for the acc compiler and linker front end - -try: - dirs = os.listdir('/opt') -except (IOError, OSError): - # Not being able to read the directory because it doesn't exist - # (IOError) or isn't readable (OSError) is okay. - dirs = [] - -for d in dirs: - linker = '/opt/' + d + '/bin/CC' - if os.path.exists(linker): - ccLinker = linker - break - - -def generate(env): - """Add Builders and construction variables for Forte to an Environment.""" - link.generate(env) - - env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -G') - - env['RPATHPREFIX'] = '-R' - env['RPATHSUFFIX'] = '' - env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' - - env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLIBSONAME' - env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -h $_LDMODULESONAME' - - -def exists(env): - return ccLinker - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/swig.py b/scons/scons-local-4.1.0/SCons/Tool/swig.py deleted file mode 100644 index 48d65d4a7..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/swig.py +++ /dev/null @@ -1,217 +0,0 @@ -"""SCons.Tool.swig - -Tool-specific initialization for swig. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path -import sys -import re -import subprocess - -import SCons.Action -import SCons.Defaults -import SCons.Tool -import SCons.Util -import SCons.Node - -verbose = False - -swigs = [ 'swig', 'swig3.0', 'swig2.0' ] - -SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR') - -def swigSuffixEmitter(env, source): - if '-c++' in SCons.Util.CLVar(env.subst("$SWIGFLAGS", source=source)): - return '$SWIGCXXFILESUFFIX' - else: - return '$SWIGCFILESUFFIX' - -# Match '%module test', as well as '%module(directors="1") test' -# Also allow for test to be quoted (SWIG permits double quotes, but not single) -# Also allow for the line to have spaces after test if not quoted -_reModule = re.compile(r'%module(\s*\(.*\))?\s+("?)(\S+)\2') - -def _find_modules(src): - """Find all modules referenced by %module lines in `src`, a SWIG .i file. - Returns a list of all modules, and a flag set if SWIG directors have - been requested (SWIG will generate an additional header file in this - case.)""" - directors = 0 - mnames = [] - try: - with open(src) as f: - data = f.read() - matches = _reModule.findall(data) - except IOError: - # If the file's not yet generated, guess the module name from the file stem - matches = [] - mnames.append(os.path.splitext(os.path.basename(src))[0]) - - for m in matches: - mnames.append(m[2]) - directors = directors or 'directors' in m[0] - return mnames, directors - -def _add_director_header_targets(target, env): - # Directors only work with C++ code, not C - suffix = env.subst(env['SWIGCXXFILESUFFIX']) - # For each file ending in SWIGCXXFILESUFFIX, add a new target director - # header by replacing the ending with SWIGDIRECTORSUFFIX. - for x in target[:]: - n = x.name - d = x.dir - if n[-len(suffix):] == suffix: - target.append(d.File(n[:-len(suffix)] + env['SWIGDIRECTORSUFFIX'])) - -def _swigEmitter(target, source, env): - swigflags = env.subst("$SWIGFLAGS", target=target, source=source) - flags = SCons.Util.CLVar(swigflags) - for src in source: - src = str(src.rfile()) - mnames = None - if "-python" in flags and "-noproxy" not in flags: - if mnames is None: - mnames, directors = _find_modules(src) - if directors: - _add_director_header_targets(target, env) - python_files = [m + ".py" for m in mnames] - outdir = env.subst('$SWIGOUTDIR', target=target, source=source) - # .py files should be generated in SWIGOUTDIR if specified, - # otherwise in the same directory as the target - if outdir: - python_files = [env.fs.File(os.path.join(outdir, j)) for j in python_files] - else: - python_files = [target[0].dir.File(m) for m in python_files] - target.extend(python_files) - if "-java" in flags: - if mnames is None: - mnames, directors = _find_modules(src) - if directors: - _add_director_header_targets(target, env) - java_files = [[m + ".java", m + "JNI.java"] for m in mnames] - java_files = SCons.Util.flatten(java_files) - outdir = env.subst('$SWIGOUTDIR', target=target, source=source) - if outdir: - java_files = [os.path.join(outdir, j) for j in java_files] - java_files = list(map(env.fs.File, java_files)) - def t_from_s(t, p, s, x): - return t.dir - tsm = SCons.Node._target_from_source_map - tkey = len(tsm) - tsm[tkey] = t_from_s - for jf in java_files: - jf._func_target_from_source = tkey - target.extend(java_files) - return (target, source) - -def _get_swig_version(env, swig): - """Run the SWIG command line tool to get and return the version number""" - version = None - swig = env.subst(swig) - if not swig: - return version - pipe = SCons.Action._subproc(env, SCons.Util.CLVar(swig) + ['-version'], - stdin = 'devnull', - stderr = 'devnull', - stdout = subprocess.PIPE) - if pipe.wait() != 0: - return version - - # MAYBE: out = SCons.Util.to_str (pipe.stdout.read()) - with pipe.stdout: - out = SCons.Util.to_str(pipe.stdout.read()) - - match = re.search(r'SWIG Version\s+(\S+).*', out, re.MULTILINE) - if match: - version = match.group(1) - if verbose: - print("Version is: %s" % version) - else: - if verbose: - print("Unable to detect version: [%s]" % out) - - return version - -def generate(env): - """Add Builders and construction variables for swig to an Environment.""" - c_file, cxx_file = SCons.Tool.createCFileBuilders(env) - - c_file.suffix['.i'] = swigSuffixEmitter - cxx_file.suffix['.i'] = swigSuffixEmitter - - c_file.add_action('.i', SwigAction) - c_file.add_emitter('.i', _swigEmitter) - cxx_file.add_action('.i', SwigAction) - cxx_file.add_emitter('.i', _swigEmitter) - - java_file = SCons.Tool.CreateJavaFileBuilder(env) - - java_file.suffix['.i'] = swigSuffixEmitter - - java_file.add_action('.i', SwigAction) - java_file.add_emitter('.i', _swigEmitter) - - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - from SCons.Platform.win32 import CHOCO_DEFAULT_PATH - - if sys.platform == 'win32': - swig = SCons.Tool.find_program_path(env, 'swig', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + CHOCO_DEFAULT_PATH) - if swig: - swig_bin_dir = os.path.dirname(swig) - env.AppendENVPath('PATH', swig_bin_dir) - else: - SCons.Warnings.SConsWarning('swig tool requested, but binary not found in ENV PATH') - - if 'SWIG' not in env: - env['SWIG'] = env.Detect(swigs) or swigs[0] - env['SWIGVERSION'] = _get_swig_version(env, env['SWIG']) - env['SWIGFLAGS'] = SCons.Util.CLVar('') - env['SWIGDIRECTORSUFFIX'] = '_wrap.h' - env['SWIGCFILESUFFIX'] = '_wrap$CFILESUFFIX' - env['SWIGCXXFILESUFFIX'] = '_wrap$CXXFILESUFFIX' - env['_SWIGOUTDIR'] = r'${"-outdir \"%s\"" % SWIGOUTDIR}' - env['SWIGPATH'] = [] - env['SWIGINCPREFIX'] = '-I' - env['SWIGINCSUFFIX'] = '' - env['_SWIGINCFLAGS'] = '$( ${_concat(SWIGINCPREFIX, SWIGPATH, SWIGINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - env['SWIGCOM'] = '$SWIG -o $TARGET ${_SWIGOUTDIR} ${_SWIGINCFLAGS} $SWIGFLAGS $SOURCES' - -def exists(env): - swig = env.get('SWIG') or env.Detect(['swig']) - return swig - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/tar.py b/scons/scons-local-4.1.0/SCons/Tool/tar.py deleted file mode 100644 index 25937811c..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/tar.py +++ /dev/null @@ -1,73 +0,0 @@ -"""SCons.Tool.tar - -Tool-specific initialization for tar. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Node.FS -import SCons.Util - -tars = ['tar', 'gtar'] - -TarAction = SCons.Action.Action('$TARCOM', '$TARCOMSTR') - -TarBuilder = SCons.Builder.Builder(action = TarAction, - source_factory = SCons.Node.FS.Entry, - source_scanner = SCons.Defaults.DirScanner, - suffix = '$TARSUFFIX', - multi = 1) - - -def generate(env): - """Add Builders and construction variables for tar to an Environment.""" - try: - bld = env['BUILDERS']['Tar'] - except KeyError: - bld = TarBuilder - env['BUILDERS']['Tar'] = bld - - env['TAR'] = env.Detect(tars) or 'gtar' - env['TARFLAGS'] = SCons.Util.CLVar('-c') - env['TARCOM'] = '$TAR $TARFLAGS -f $TARGET $SOURCES' - env['TARSUFFIX'] = '.tar' - -def exists(env): - return env.Detect(tars) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/tex.py b/scons/scons-local-4.1.0/SCons/Tool/tex.py deleted file mode 100644 index 0ca7e2da4..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/tex.py +++ /dev/null @@ -1,996 +0,0 @@ -"""SCons.Tool.tex - -Tool-specific initialization for TeX. -Generates .dvi files from .tex files - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path -import re -import shutil -import sys -import platform -import glob - -import SCons.Action -import SCons.Node -import SCons.Node.FS -import SCons.Util -import SCons.Scanner.LaTeX - -Verbose = False - -must_rerun_latex = True - -# these are files that just need to be checked for changes and then rerun latex -check_suffixes = ['.toc', '.lof', '.lot', '.out', '.nav', '.snm'] - -# these are files that require bibtex or makeindex to be run when they change -all_suffixes = check_suffixes + ['.bbl', '.idx', '.nlo', '.glo', '.acn', '.bcf'] - -# -# regular expressions used to search for Latex features -# or outputs that require rerunning latex -# -# search for all .aux files opened by latex (recorded in the .fls file) -openout_aux_re = re.compile(r"OUTPUT *(.*\.aux)") - -# search for all .bcf files opened by latex (recorded in the .fls file) -# for use by biber -openout_bcf_re = re.compile(r"OUTPUT *(.*\.bcf)") - -#printindex_re = re.compile(r"^[^%]*\\printindex", re.MULTILINE) -#printnomenclature_re = re.compile(r"^[^%]*\\printnomenclature", re.MULTILINE) -#printglossary_re = re.compile(r"^[^%]*\\printglossary", re.MULTILINE) - -# search to find rerun warnings -warning_rerun_str = r'(^LaTeX Warning:.*Rerun)|(^Package \w+ Warning:.*Rerun)' -warning_rerun_re = re.compile(warning_rerun_str, re.MULTILINE) - -# search to find citation rerun warnings -rerun_citations_str = r"^LaTeX Warning:.*\n.*Rerun to get citations correct" -rerun_citations_re = re.compile(rerun_citations_str, re.MULTILINE) - -# search to find undefined references or citations warnings -undefined_references_str = r'(^LaTeX Warning:.*undefined references)|(^Package \w+ Warning:.*undefined citations)' -undefined_references_re = re.compile(undefined_references_str, re.MULTILINE) - -# used by the emitter -auxfile_re = re.compile(r".", re.MULTILINE) -tableofcontents_re = re.compile(r"^[^%\n]*\\tableofcontents", re.MULTILINE) -makeindex_re = re.compile(r"^[^%\n]*\\makeindex", re.MULTILINE) -bibliography_re = re.compile(r"^[^%\n]*\\bibliography", re.MULTILINE) -bibunit_re = re.compile(r"^[^%\n]*\\begin\{bibunit\}", re.MULTILINE) -multibib_re = re.compile(r"^[^%\n]*\\newcites\{([^\}]*)\}", re.MULTILINE) -addbibresource_re = re.compile(r"^[^%\n]*\\(addbibresource|addglobalbib|addsectionbib)", re.MULTILINE) -listoffigures_re = re.compile(r"^[^%\n]*\\listoffigures", re.MULTILINE) -listoftables_re = re.compile(r"^[^%\n]*\\listoftables", re.MULTILINE) -hyperref_re = re.compile(r"^[^%\n]*\\usepackage.*\{hyperref\}", re.MULTILINE) -makenomenclature_re = re.compile(r"^[^%\n]*\\makenomenclature", re.MULTILINE) -makeglossary_re = re.compile(r"^[^%\n]*\\makeglossary", re.MULTILINE) -makeglossaries_re = re.compile(r"^[^%\n]*\\makeglossaries", re.MULTILINE) -makeacronyms_re = re.compile(r"^[^%\n]*\\makeglossaries", re.MULTILINE) -beamer_re = re.compile(r"^[^%\n]*\\documentclass\{beamer\}", re.MULTILINE) -regex = r'^[^%\n]*\\newglossary\s*\[([^\]]+)\]?\s*\{([^}]*)\}\s*\{([^}]*)\}\s*\{([^}]*)\}\s*\{([^}]*)\}' -newglossary_re = re.compile(regex, re.MULTILINE) -biblatex_re = re.compile(r"^[^%\n]*\\usepackage.*\{biblatex\}", re.MULTILINE) - -newglossary_suffix = [] - -# search to find all files included by Latex -include_re = re.compile(r'^[^%\n]*\\(?:include|input){([^}]*)}', re.MULTILINE) -includeOnly_re = re.compile(r'^[^%\n]*\\(?:include){([^}]*)}', re.MULTILINE) - -# search to find all graphics files included by Latex -includegraphics_re = re.compile(r'^[^%\n]*\\(?:includegraphics(?:\[[^\]]+\])?){([^}]*)}', re.MULTILINE) - -# search to find all files opened by Latex (recorded in .log file) -openout_re = re.compile(r"OUTPUT *(.*)") - -# list of graphics file extensions for TeX and LaTeX -TexGraphics = SCons.Scanner.LaTeX.TexGraphics -LatexGraphics = SCons.Scanner.LaTeX.LatexGraphics - -# 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 Biber on a file. -BiberAction = None - -# An action to run MakeIndex on a file. -MakeIndexAction = None - -# An action to run MakeIndex (for nomencl) on a file. -MakeNclAction = None - -# An action to run MakeIndex (for glossary) on a file. -MakeGlossaryAction = None - -# An action to run MakeIndex (for acronyms) on a file. -MakeAcronymsAction = None - -# An action to run MakeIndex (for newglossary commands) on a file. -MakeNewGlossaryAction = None - -# Used as a return value of modify_env_var if the variable is not set. -_null = SCons.Scanner.LaTeX._null - -modify_env_var = SCons.Scanner.LaTeX.modify_env_var - -def check_file_error_message(utility, filename='log'): - msg = '%s returned an error, check the %s file\n' % (utility, filename) - sys.stdout.write(msg) - -def FindFile(name,suffixes,paths,env,requireExt=False): - if requireExt: - name,ext = SCons.Util.splitext(name) - # if the user gave an extension use it. - if ext: - name = name + ext - if Verbose: - print(" searching for '%s' with extensions: " % name,suffixes) - - for path in paths: - testName = os.path.join(path,name) - if Verbose: - print(" look for '%s'" % testName) - if os.path.isfile(testName): - if Verbose: - print(" found '%s'" % testName) - return env.fs.File(testName) - else: - name_ext = SCons.Util.splitext(testName)[1] - if name_ext: - continue - - # if no suffix try adding those passed in - for suffix in suffixes: - testNameExt = testName + suffix - if Verbose: - print(" look for '%s'" % testNameExt) - - if os.path.isfile(testNameExt): - if Verbose: - print(" found '%s'" % testNameExt) - return env.fs.File(testNameExt) - if Verbose: - print(" did not find '%s'" % name) - return 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.""" - - global must_rerun_latex - - # This routine is called with two actions. In this file for DVI builds - # with LaTeXAction and from the pdflatex.py with PDFLaTeXAction - # set this up now for the case where the user requests a different extension - # for the target filename - if XXXLaTeXAction == LaTeXAction: - callerSuffix = ".dvi" - else: - callerSuffix = env['PDFSUFFIX'] - - basename = SCons.Util.splitext(str(source[0]))[0] - basedir = os.path.split(str(source[0]))[0] - basefile = os.path.split(str(basename))[1] - abspath = os.path.abspath(basedir) - - targetext = os.path.splitext(str(target[0]))[1] - targetdir = os.path.split(str(target[0]))[0] - - saved_env = {} - for var in SCons.Scanner.LaTeX.LaTeX.env_variables: - saved_env[var] = modify_env_var(env, var, abspath) - - # Create base file names with the target directory since the auxiliary files - # will be made there. That's because the *COM variables have the cd - # command in the prolog. 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. - - targetbase = os.path.join(targetdir, basefile) - - # if there is a \makeindex there will be a .idx and thus - # we have to run makeindex at least once to keep the build - # happy even if there is no index. - # Same for glossaries, nomenclature, and acronyms - src_content = source[0].get_text_contents() - run_makeindex = makeindex_re.search(src_content) and not os.path.isfile(targetbase + '.idx') - run_nomenclature = makenomenclature_re.search(src_content) and not os.path.isfile(targetbase + '.nlo') - run_glossary = makeglossary_re.search(src_content) and not os.path.isfile(targetbase + '.glo') - run_glossaries = makeglossaries_re.search(src_content) and not os.path.isfile(targetbase + '.glo') - run_acronyms = makeacronyms_re.search(src_content) and not os.path.isfile(targetbase + '.acn') - - saved_hashes = {} - suffix_nodes = {} - - - for suffix in all_suffixes+sum(newglossary_suffix, []): - theNode = env.fs.File(targetbase + suffix) - suffix_nodes[suffix] = theNode - saved_hashes[suffix] = theNode.get_csig() - - if Verbose: - print("hashes: ",saved_hashes) - - must_rerun_latex = True - - # .aux files already processed by BibTex - already_bibtexed = [] - - # - # routine to update MD5 hash and compare - # - def check_MD5(filenode, suffix): - global must_rerun_latex - # two calls to clear old csig - filenode.clear_memoized_values() - filenode.ninfo = filenode.new_ninfo() - new_md5 = filenode.get_csig() - - if saved_hashes[suffix] == new_md5: - if Verbose: - print("file %s not changed" % (targetbase+suffix)) - return False # unchanged - saved_hashes[suffix] = new_md5 - must_rerun_latex = True - if Verbose: - print("file %s changed, rerunning Latex, new hash = " % (targetbase+suffix), new_md5) - return True # changed - - # generate the file name that latex will generate - resultfilename = targetbase + callerSuffix - - count = 0 - - while must_rerun_latex and count < int(env.subst('$LATEXRETRIES')): - result = XXXLaTeXAction(target, source, env) - if result != 0: - return result - - count = count + 1 - - must_rerun_latex = False - # Decide if various things need to be run, or run again. - - # Read the log file to find warnings/errors - logfilename = targetbase + '.log' - logContent = '' - if os.path.isfile(logfilename): - with open(logfilename, "rb") as f: - logContent = f.read().decode(errors='replace') - - - # Read the fls file to find all .aux files - flsfilename = targetbase + '.fls' - flsContent = '' - auxfiles = [] - if os.path.isfile(flsfilename): - with open(flsfilename, "r") as f: - flsContent = f.read() - auxfiles = openout_aux_re.findall(flsContent) - # remove duplicates - dups = {} - for x in auxfiles: - dups[x] = 1 - auxfiles = list(dups.keys()) - - bcffiles = [] - if os.path.isfile(flsfilename): - with open(flsfilename, "r") as f: - flsContent = f.read() - bcffiles = openout_bcf_re.findall(flsContent) - # remove duplicates - dups = {} - for x in bcffiles: - dups[x] = 1 - bcffiles = list(dups.keys()) - - if Verbose: - print("auxfiles ",auxfiles) - print("bcffiles ",bcffiles) - - # Now decide if bibtex will need to be run. - # The information that bibtex reads from the .aux file is - # pass-independent. If we find (below) that the .bbl file is unchanged, - # then the last latex saw a correct bibliography. - # Therefore only do this once - # Go through all .aux files and remember the files already done. - for auxfilename in auxfiles: - if auxfilename not in already_bibtexed: - already_bibtexed.append(auxfilename) - target_aux = os.path.join(targetdir, auxfilename) - if os.path.isfile(target_aux): - with open(target_aux, "r") as f: - content = f.read() - if content.find("bibdata") != -1: - if Verbose: - print("Need to run bibtex on ",auxfilename) - bibfile = env.fs.File(SCons.Util.splitext(target_aux)[0]) - result = BibTeXAction(bibfile, bibfile, env) - if result != 0: - check_file_error_message(env['BIBTEX'], 'blg') - must_rerun_latex = True - - # Now decide if biber will need to be run. - # When the backend for biblatex is biber (by choice or default) the - # citation information is put in the .bcf file. - # The information that biber reads from the .bcf file is - # pass-independent. If we find (below) that the .bbl file is unchanged, - # then the last latex saw a correct bibliography. - # Therefore only do this once - # Go through all .bcf files and remember the files already done. - for bcffilename in bcffiles: - if bcffilename not in already_bibtexed: - already_bibtexed.append(bcffilename) - target_bcf = os.path.join(targetdir, bcffilename) - if os.path.isfile(target_bcf): - with open(target_bcf, "r") as f: - content = f.read() - if content.find("bibdata") != -1: - if Verbose: - print("Need to run biber on ",bcffilename) - bibfile = env.fs.File(SCons.Util.splitext(target_bcf)[0]) - result = BiberAction(bibfile, bibfile, env) - if result != 0: - check_file_error_message(env['BIBER'], 'blg') - must_rerun_latex = True - - # Now decide if latex will need to be run again due to index. - if check_MD5(suffix_nodes['.idx'],'.idx') or (count == 1 and run_makeindex): - # We must run makeindex - if Verbose: - print("Need to run makeindex") - idxfile = suffix_nodes['.idx'] - result = MakeIndexAction(idxfile, idxfile, env) - if result != 0: - check_file_error_message(env['MAKEINDEX'], 'ilg') - return result - - # TO-DO: need to add a way for the user to extend this list for whatever - # auxiliary files they create in other (or their own) packages - # Harder is case is where an action needs to be called -- that should be rare (I hope?) - - for index in check_suffixes: - check_MD5(suffix_nodes[index],index) - - # Now decide if latex will need to be run again due to nomenclature. - if check_MD5(suffix_nodes['.nlo'],'.nlo') or (count == 1 and run_nomenclature): - # We must run makeindex - if Verbose: - print("Need to run makeindex for nomenclature") - nclfile = suffix_nodes['.nlo'] - result = MakeNclAction(nclfile, nclfile, env) - if result != 0: - check_file_error_message('%s (nomenclature)' % env['MAKENCL'], - 'nlg') - #return result - - # Now decide if latex will need to be run again due to glossary. - if check_MD5(suffix_nodes['.glo'],'.glo') or (count == 1 and run_glossaries) or (count == 1 and run_glossary): - # We must run makeindex - if Verbose: - print("Need to run makeindex for glossary") - glofile = suffix_nodes['.glo'] - result = MakeGlossaryAction(glofile, glofile, env) - if result != 0: - check_file_error_message('%s (glossary)' % env['MAKEGLOSSARY'], - 'glg') - #return result - - # Now decide if latex will need to be run again due to acronyms. - if check_MD5(suffix_nodes['.acn'],'.acn') or (count == 1 and run_acronyms): - # We must run makeindex - if Verbose: - print("Need to run makeindex for acronyms") - acrfile = suffix_nodes['.acn'] - result = MakeAcronymsAction(acrfile, acrfile, env) - if result != 0: - check_file_error_message('%s (acronyms)' % env['MAKEACRONYMS'], - 'alg') - return result - - # Now decide if latex will need to be run again due to newglossary command. - for ng in newglossary_suffix: - if check_MD5(suffix_nodes[ng[2]], ng[2]) or (count == 1): - # We must run makeindex - if Verbose: - print("Need to run makeindex for newglossary") - newglfile = suffix_nodes[ng[2]] - MakeNewGlossaryAction = SCons.Action.Action( - "$MAKENEWGLOSSARYCOM ${SOURCE.filebase}%s -s ${SOURCE.filebase}.ist -t ${SOURCE.filebase}%s -o ${SOURCE.filebase}%s" - % (ng[2], ng[0], ng[1]), - "$MAKENEWGLOSSARYCOMSTR", - ) - - result = MakeNewGlossaryAction(newglfile, newglfile, env) - if result != 0: - check_file_error_message( - '%s (newglossary)' % env['MAKENEWGLOSSARY'], ng[0] - ) - return result - - # Now decide if latex needs to be run yet again to resolve warnings. - if warning_rerun_re.search(logContent): - must_rerun_latex = True - if Verbose: - print("rerun Latex due to latex or package rerun warning") - - if rerun_citations_re.search(logContent): - must_rerun_latex = True - if Verbose: - print("rerun Latex due to 'Rerun to get citations correct' warning") - - if undefined_references_re.search(logContent): - must_rerun_latex = True - if Verbose: - print("rerun Latex due to undefined references or citations") - - if count >= int(env.subst('$LATEXRETRIES')) and must_rerun_latex: - print("reached max number of retries on Latex ,",int(env.subst('$LATEXRETRIES'))) -# end of while loop - - # rename Latex's output to what the target name is - if not (str(target[0]) == resultfilename and os.path.isfile(resultfilename)): - if os.path.isfile(resultfilename): - print("move %s to %s" % (resultfilename, str(target[0]), )) - shutil.move(resultfilename,str(target[0])) - - # Original comment (when TEXPICTS was not restored): - # The TEXPICTS enviroment variable is needed by a dvi -> pdf step - # later on Mac OSX so leave it - # - # It is also used when searching for pictures (implicit dependencies). - # Why not set the variable again in the respective builder instead - # of leaving local modifications in the environment? What if multiple - # latex builds in different directories need different TEXPICTS? - for var in SCons.Scanner.LaTeX.LaTeX.env_variables: - if var == 'TEXPICTS': - continue - if saved_env[var] is _null: - try: - del env['ENV'][var] - except KeyError: - pass # was never set - else: - env['ENV'][var] = saved_env[var] - - return result - -def LaTeXAuxAction(target = None, source= None, env=None): - result = InternalLaTeXAuxAction( LaTeXAction, target, source, env ) - return result - -LaTeX_re = re.compile("\\\\document(style|class)") - -def is_LaTeX(flist,env,abspath): - """Scan a file list to decide if it's TeX- or LaTeX-flavored.""" - - # We need to scan files that are included in case the - # \documentclass command is in them. - - # get path list from both env['TEXINPUTS'] and env['ENV']['TEXINPUTS'] - savedpath = modify_env_var(env, 'TEXINPUTS', abspath) - paths = env['ENV']['TEXINPUTS'] - if SCons.Util.is_List(paths): - pass - else: - # Split at os.pathsep to convert into absolute path - paths = paths.split(os.pathsep) - - # now that we have the path list restore the env - if savedpath is _null: - try: - del env['ENV']['TEXINPUTS'] - except KeyError: - pass # was never set - else: - env['ENV']['TEXINPUTS'] = savedpath - if Verbose: - print("is_LaTeX search path ",paths) - print("files to search :",flist) - - # Now that we have the search path and file list, check each one - for f in flist: - if Verbose: - print(" checking for Latex source ",str(f)) - - content = f.get_text_contents() - if LaTeX_re.search(content): - if Verbose: - print("file %s is a LaTeX file" % str(f)) - return 1 - if Verbose: - print("file %s is not a LaTeX file" % str(f)) - - # now find included files - inc_files = [ ] - inc_files.extend( include_re.findall(content) ) - if Verbose: - print("files included by '%s': "%str(f),inc_files) - # inc_files is list of file names as given. need to find them - # using TEXINPUTS paths. - - # search the included files - for src in inc_files: - srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env,requireExt=False) - # make this a list since is_LaTeX takes a list. - fileList = [srcNode,] - if Verbose: - print("FindFile found ",srcNode) - if srcNode is not None: - file_test = is_LaTeX(fileList, env, abspath) - - # return on first file that finds latex is needed. - if file_test: - return file_test - - if Verbose: - print(" done scanning ",str(f)) - - 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.""" - - # find these paths for use in is_LaTeX to search for included files - basedir = os.path.split(str(source[0]))[0] - abspath = os.path.abspath(basedir) - - if is_LaTeX(source,env,abspath): - result = LaTeXAuxAction(target,source,env) - if result != 0: - check_file_error_message(env['LATEX']) - else: - result = TeXAction(target,source,env) - if result != 0: - check_file_error_message(env['TEX']) - return result - -def TeXLaTeXStrFunction(target = None, source= None, env=None): - """A strfunction for TeX and LaTeX that scans the source file to - decide the "flavor" of the source and then returns the appropriate - command string.""" - if env.GetOption("no_exec"): - - # find these paths for use in is_LaTeX to search for included files - basedir = os.path.split(str(source[0]))[0] - abspath = os.path.abspath(basedir) - - if is_LaTeX(source,env,abspath): - result = env.subst('$LATEXCOM',0,target,source)+" ..." - else: - result = env.subst("$TEXCOM",0,target,source)+" ..." - else: - result = '' - return result - -def tex_eps_emitter(target, source, env): - """An emitter for TeX and LaTeX sources when - executing tex or latex. It will accept .ps and .eps - graphics files - """ - (target, source) = tex_emitter_core(target, source, env, TexGraphics) - - return (target, source) - -def tex_pdf_emitter(target, source, env): - """An emitter for TeX and LaTeX sources when - executing pdftex or pdflatex. It will accept graphics - files of types .pdf, .jpg, .png, .gif, and .tif - """ - (target, source) = tex_emitter_core(target, source, env, LatexGraphics) - - return (target, source) - -def ScanFiles(theFile, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir, aux_files): - """ For theFile (a Node) update any file_tests and search for graphics files - then find all included files and call ScanFiles recursively for each of them""" - - content = theFile.get_text_contents() - if Verbose: - print(" scanning ",str(theFile)) - - for i in range(len(file_tests_search)): - if file_tests[i][0] is None: - if Verbose: - print("scan i ",i," files_tests[i] ",file_tests[i], file_tests[i][1]) - file_tests[i][0] = file_tests_search[i].search(content) - if Verbose and file_tests[i][0]: - print(" found match for ",file_tests[i][1][-1]) - # for newglossary insert the suffixes in file_tests[i] - if file_tests[i][0] and file_tests[i][1][-1] == 'newglossary': - findresult = file_tests_search[i].findall(content) - for l in range(len(findresult)) : - (file_tests[i][1]).insert(0,'.'+findresult[l][3]) - (file_tests[i][1]).insert(0,'.'+findresult[l][2]) - (file_tests[i][1]).insert(0,'.'+findresult[l][0]) - suffix_list = ['.'+findresult[l][0],'.'+findresult[l][2],'.'+findresult[l][3] ] - newglossary_suffix.append(suffix_list) - if Verbose: - print(" new suffixes for newglossary ",newglossary_suffix) - - - incResult = includeOnly_re.search(content) - if incResult: - aux_files.append(os.path.join(targetdir, incResult.group(1))) - if Verbose: - print(r"\include file names : ", aux_files) - # recursively call this on each of the included files - inc_files = [ ] - inc_files.extend( include_re.findall(content) ) - if Verbose: - print("files included by '%s': "%str(theFile),inc_files) - # inc_files is list of file names as given. need to find them - # using TEXINPUTS paths. - - for src in inc_files: - srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env,requireExt=False) - if srcNode is not None: - file_tests = ScanFiles(srcNode, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir, aux_files) - if Verbose: - print(" done scanning ",str(theFile)) - return file_tests - -def tex_emitter_core(target, source, env, graphics_extensions): - """An emitter for TeX and LaTeX sources. - For LaTeX sources we try and find the common created files that - are needed on subsequent runs of latex to finish tables of contents, - bibliographies, indices, lists of figures, and hyperlink references. - """ - basename = SCons.Util.splitext(str(source[0]))[0] - basefile = os.path.split(str(basename))[1] - targetdir = os.path.split(str(target[0]))[0] - targetbase = os.path.join(targetdir, basefile) - - basedir = os.path.split(str(source[0]))[0] - abspath = os.path.abspath(basedir) - target[0].attributes.path = abspath - - # - # file names we will make use of in searching the sources and log file - # - emit_suffixes = ['.aux', '.log', '.ilg', '.blg', '.nls', '.nlg', '.gls', '.glg', '.alg'] + all_suffixes - auxfilename = targetbase + '.aux' - logfilename = targetbase + '.log' - flsfilename = targetbase + '.fls' - syncfilename = targetbase + '.synctex.gz' - - env.SideEffect(auxfilename,target[0]) - env.SideEffect(logfilename,target[0]) - env.SideEffect(flsfilename,target[0]) - env.SideEffect(syncfilename,target[0]) - if Verbose: - print("side effect :",auxfilename,logfilename,flsfilename,syncfilename) - env.Clean(target[0],auxfilename) - env.Clean(target[0],logfilename) - env.Clean(target[0],flsfilename) - env.Clean(target[0],syncfilename) - - content = source[0].get_text_contents() - - # set up list with the regular expressions - # we use to find features used - file_tests_search = [auxfile_re, - makeindex_re, - bibliography_re, - bibunit_re, - multibib_re, - addbibresource_re, - tableofcontents_re, - listoffigures_re, - listoftables_re, - hyperref_re, - makenomenclature_re, - makeglossary_re, - makeglossaries_re, - makeacronyms_re, - beamer_re, - newglossary_re, - biblatex_re ] - # set up list with the file suffixes that need emitting - # when a feature is found - file_tests_suff = [['.aux','aux_file'], - ['.idx', '.ind', '.ilg','makeindex'], - ['.bbl', '.blg','bibliography'], - ['.bbl', '.blg','bibunit'], - ['.bbl', '.blg','multibib'], - ['.bbl', '.blg','.bcf','addbibresource'], - ['.toc','contents'], - ['.lof','figures'], - ['.lot','tables'], - ['.out','hyperref'], - ['.nlo', '.nls', '.nlg','nomenclature'], - ['.glo', '.gls', '.glg','glossary'], - ['.glo', '.gls', '.glg','glossaries'], - ['.acn', '.acr', '.alg','acronyms'], - ['.nav', '.snm', '.out', '.toc','beamer'], - ['newglossary',], - ['.bcf', '.blg','biblatex'] ] - # for newglossary the suffixes are added as we find the command - # build the list of lists - file_tests = [] - for i in range(len(file_tests_search)): - file_tests.append( [None, file_tests_suff[i]] ) - - # TO-DO: need to add a way for the user to extend this list for whatever - # auxiliary files they create in other (or their own) packages - - # get path list from both env['TEXINPUTS'] and env['ENV']['TEXINPUTS'] - savedpath = modify_env_var(env, 'TEXINPUTS', abspath) - paths = env['ENV']['TEXINPUTS'] - if SCons.Util.is_List(paths): - pass - else: - # Split at os.pathsep to convert into absolute path - paths = paths.split(os.pathsep) - - # now that we have the path list restore the env - if savedpath is _null: - try: - del env['ENV']['TEXINPUTS'] - except KeyError: - pass # was never set - else: - env['ENV']['TEXINPUTS'] = savedpath - if Verbose: - print("search path ",paths) - - # scan all sources for side effect files - aux_files = [] - file_tests = ScanFiles(source[0], target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir, aux_files) - - for (theSearch,suffix_list) in file_tests: - # add side effects if feature is present.If file is to be generated,add all side effects - if Verbose and theSearch: - print("check side effects for ",suffix_list[-1]) - if theSearch is not None or not source[0].exists(): - file_list = [targetbase,] - # for bibunit we need a list of files - if suffix_list[-1] == 'bibunit': - file_basename = os.path.join(targetdir, 'bu*.aux') - file_list = glob.glob(file_basename) - # remove the suffix '.aux' - for fl in file_list.copy(): - file_list.append(SCons.Util.splitext(fl)[0]) - # for multibib we need a list of files - if suffix_list[-1] == 'multibib': - for multibibmatch in multibib_re.finditer(content): - if Verbose: - print("multibib match ",multibibmatch.group(1)) - if multibibmatch is not None: - baselist = multibibmatch.group(1).split(',') - if Verbose: - print("multibib list ", baselist) - for bl in baselist: - file_list.append(os.path.join(targetdir, bl)) - # now define the side effects - for file_name in file_list: - for suffix in suffix_list[:-1]: - env.SideEffect(file_name + suffix,target[0]) - if Verbose: - print("side effect tst :",file_name + suffix, " target is ",str(target[0])) - env.Clean(target[0],file_name + suffix) - - for aFile in aux_files: - aFile_base = SCons.Util.splitext(aFile)[0] - env.SideEffect(aFile_base + '.aux',target[0]) - if Verbose: - print("side effect aux :",aFile_base + '.aux') - env.Clean(target[0],aFile_base + '.aux') - # read fls file to get all other files that latex creates and will read on the next pass - # remove files from list that we explicitly dealt with above - if os.path.isfile(flsfilename): - with open(flsfilename, "r") as f: - content = f.read() - out_files = openout_re.findall(content) - myfiles = [auxfilename, logfilename, flsfilename, targetbase+'.dvi',targetbase+'.pdf'] - for filename in out_files[:]: - if filename in myfiles: - out_files.remove(filename) - env.SideEffect(out_files,target[0]) - if Verbose: - print("side effect fls :",out_files) - env.Clean(target[0],out_files) - - return (target, source) - - -TeXLaTeXAction = None - -def generate(env): - """Add Builders and construction variables for TeX to an Environment.""" - - global TeXLaTeXAction - if TeXLaTeXAction is None: - TeXLaTeXAction = SCons.Action.Action(TeXLaTeXFunction, - strfunction=TeXLaTeXStrFunction) - - env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) - - generate_common(env) - - from . import dvi - dvi.generate(env) - - bld = env['BUILDERS']['DVI'] - bld.add_action('.tex', TeXLaTeXAction) - bld.add_emitter('.tex', tex_eps_emitter) - -def generate_darwin(env): - try: - environ = env['ENV'] - except KeyError: - environ = {} - env['ENV'] = environ - - if platform.system() == 'Darwin': - try: - ospath = env['ENV']['PATHOSX'] - except: - ospath = None - if ospath: - env.AppendENVPath('PATH', ospath) - -def generate_common(env): - """Add internal Builders and construction variables for LaTeX to an Environment.""" - - # Add OSX system paths so TeX tools can be found - # when a list of tools is given the exists() method is not called - generate_darwin(env) - - # 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 Biber on a file. - global BiberAction - if BiberAction is None: - BiberAction = SCons.Action.Action("$BIBERCOM", "$BIBERCOMSTR") - - # Define an action to run MakeIndex on a file. - global MakeIndexAction - if MakeIndexAction is None: - MakeIndexAction = SCons.Action.Action("$MAKEINDEXCOM", "$MAKEINDEXCOMSTR") - - # Define an action to run MakeIndex on a file for nomenclatures. - global MakeNclAction - if MakeNclAction is None: - MakeNclAction = SCons.Action.Action("$MAKENCLCOM", "$MAKENCLCOMSTR") - - # Define an action to run MakeIndex on a file for glossaries. - global MakeGlossaryAction - if MakeGlossaryAction is None: - MakeGlossaryAction = SCons.Action.Action("$MAKEGLOSSARYCOM", "$MAKEGLOSSARYCOMSTR") - - # Define an action to run MakeIndex on a file for acronyms. - global MakeAcronymsAction - if MakeAcronymsAction is None: - MakeAcronymsAction = SCons.Action.Action("$MAKEACRONYMSCOM", "$MAKEACRONYMSCOMSTR") - - try: - environ = env['ENV'] - except KeyError: - environ = {} - env['ENV'] = environ - - # Some Linux platforms have pdflatex set up in a way - # that requires that the HOME environment variable be set. - # Add it here if defined. - v = os.environ.get('HOME') - if v: - environ['HOME'] = v - - CDCOM = 'cd ' - if platform.system() == 'Windows': - # allow cd command to change drives on Windows - CDCOM = 'cd /D ' - - env['TEX'] = 'tex' - env['TEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') - env['TEXCOM'] = CDCOM + '${TARGET.dir} && $TEX $TEXFLAGS ${SOURCE.file}' - - env['PDFTEX'] = 'pdftex' - env['PDFTEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') - env['PDFTEXCOM'] = CDCOM + '${TARGET.dir} && $PDFTEX $PDFTEXFLAGS ${SOURCE.file}' - - env['LATEX'] = 'latex' - env['LATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') - env['LATEXCOM'] = CDCOM + '${TARGET.dir} && $LATEX $LATEXFLAGS ${SOURCE.file}' - env['LATEXRETRIES'] = 4 - - env['PDFLATEX'] = 'pdflatex' - env['PDFLATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') - env['PDFLATEXCOM'] = CDCOM + '${TARGET.dir} && $PDFLATEX $PDFLATEXFLAGS ${SOURCE.file}' - - env['BIBTEX'] = 'bibtex' - env['BIBTEXFLAGS'] = SCons.Util.CLVar('') - env['BIBTEXCOM'] = CDCOM + '${TARGET.dir} && $BIBTEX $BIBTEXFLAGS ${SOURCE.filebase}' - - env['BIBER'] = 'biber' - env['BIBERFLAGS'] = SCons.Util.CLVar('') - env['BIBERCOM'] = CDCOM + '${TARGET.dir} && $BIBER $BIBERFLAGS ${SOURCE.filebase}' - - env['MAKEINDEX'] = 'makeindex' - env['MAKEINDEXFLAGS'] = SCons.Util.CLVar('') - env['MAKEINDEXCOM'] = CDCOM + '${TARGET.dir} && $MAKEINDEX $MAKEINDEXFLAGS ${SOURCE.file}' - - env['MAKEGLOSSARY'] = 'makeindex' - env['MAKEGLOSSARYSTYLE'] = '${SOURCE.filebase}.ist' - env['MAKEGLOSSARYFLAGS'] = SCons.Util.CLVar('-s ${MAKEGLOSSARYSTYLE} -t ${SOURCE.filebase}.glg') - env['MAKEGLOSSARYCOM'] = CDCOM + '${TARGET.dir} && $MAKEGLOSSARY ${SOURCE.filebase}.glo $MAKEGLOSSARYFLAGS -o ${SOURCE.filebase}.gls' - - env['MAKEACRONYMS'] = 'makeindex' - env['MAKEACRONYMSSTYLE'] = '${SOURCE.filebase}.ist' - env['MAKEACRONYMSFLAGS'] = SCons.Util.CLVar('-s ${MAKEACRONYMSSTYLE} -t ${SOURCE.filebase}.alg') - env['MAKEACRONYMSCOM'] = CDCOM + '${TARGET.dir} && $MAKEACRONYMS ${SOURCE.filebase}.acn $MAKEACRONYMSFLAGS -o ${SOURCE.filebase}.acr' - - env['MAKENCL'] = 'makeindex' - env['MAKENCLSTYLE'] = 'nomencl.ist' - env['MAKENCLFLAGS'] = '-s ${MAKENCLSTYLE} -t ${SOURCE.filebase}.nlg' - env['MAKENCLCOM'] = CDCOM + '${TARGET.dir} && $MAKENCL ${SOURCE.filebase}.nlo $MAKENCLFLAGS -o ${SOURCE.filebase}.nls' - - env['MAKENEWGLOSSARY'] = 'makeindex' - env['MAKENEWGLOSSARYCOM'] = CDCOM + '${TARGET.dir} && $MAKENEWGLOSSARY ' - -def exists(env): - generate_darwin(env) - return env.Detect('tex') - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/textfile.py b/scons/scons-local-4.1.0/SCons/Tool/textfile.py deleted file mode 100644 index c1b597fcd..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/textfile.py +++ /dev/null @@ -1,200 +0,0 @@ -# -*- python -*- -# -# __COPYRIGHT__ -# -# 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. -# - -__doc__ = """ -Textfile/Substfile builder for SCons. - - Create file 'target' which typically is a textfile. The 'source' - may be any combination of strings, Nodes, or lists of same. A - 'linesep' will be put between any part written and defaults to - os.linesep. - - The only difference between the Textfile builder and the Substfile - builder is that strings are converted to Value() nodes for the - former and File() nodes for the latter. To insert files in the - former or strings in the latter, wrap them in a File() or Value(), - respectively. - - The values of SUBST_DICT first have any construction variables - expanded (its keys are not expanded). If a value of SUBST_DICT is - a python callable function, it is called and the result is expanded - as the value. Values are substituted in a "random" order; if any - substitution could be further expanded by another substitution, it - is unpredictable whether the expansion will occur. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons - - -from SCons.Node import Node -from SCons.Node.Python import Value -from SCons.Util import is_String, is_Sequence, is_Dict, to_bytes - - -TEXTFILE_FILE_WRITE_MODE = 'w' - -LINESEP = '\n' - -def _do_subst(node, subs): - """ - Fetch the node contents and replace all instances of the keys with - their values. For example, if subs is - {'%VERSION%': '1.2345', '%BASE%': 'MyProg', '%prefix%': '/bin'}, - then all instances of %VERSION% in the file will be replaced with - 1.2345 and so forth. - """ - contents = node.get_text_contents() - if subs: - for (k, val) in subs: - contents = contents.replace(k, val) - - if 'b' in TEXTFILE_FILE_WRITE_MODE: - try: - contents = bytearray(contents, 'utf-8') - except TypeError: - # TODO: this should not happen, get_text_contents returns text - contents = bytearray(contents) - - return contents - - -def _action(target, source, env): - - # prepare the line separator - linesep = env['LINESEPARATOR'] - if linesep is None: - linesep = LINESEP # os.linesep - elif is_String(linesep): - pass - elif isinstance(linesep, Value): - linesep = linesep.get_text_contents() - else: - raise SCons.Errors.UserError('unexpected type/class for LINESEPARATOR: %s' - % repr(linesep), None) - - if 'b' in TEXTFILE_FILE_WRITE_MODE: - linesep = to_bytes(linesep) - - # create a dictionary to use for the substitutions - if 'SUBST_DICT' not in env: - subs = None # no substitutions - else: - subst_dict = env['SUBST_DICT'] - if is_Dict(subst_dict): - subst_dict = list(subst_dict.items()) - elif is_Sequence(subst_dict): - pass - else: - raise SCons.Errors.UserError('SUBST_DICT must be dict or sequence') - subs = [] - for (k, value) in subst_dict: - if callable(value): - value = value() - if is_String(value): - value = env.subst(value) - else: - value = str(value) - subs.append((k, value)) - - # write the file - try: - target_file = open(target[0].get_path(), TEXTFILE_FILE_WRITE_MODE, newline='') - except (OSError, IOError) as e: - raise SCons.Errors.UserError("Can't write target file %s [%s]" % (target[0],e)) - - # separate lines by 'linesep' only if linesep is not empty - lsep = None - for line in source: - if lsep: - target_file.write(lsep) - - target_file.write(_do_subst(line, subs)) - lsep = linesep - target_file.close() - - -def _strfunc(target, source, env): - return "Creating '%s'" % target[0] - - -def _convert_list_R(newlist, sources): - for elem in sources: - if is_Sequence(elem): - _convert_list_R(newlist, elem) - elif isinstance(elem, Node): - newlist.append(elem) - else: - newlist.append(Value(elem)) - - -def _convert_list(target, source, env): - if len(target) != 1: - raise SCons.Errors.UserError("Only one target file allowed") - newlist = [] - _convert_list_R(newlist, source) - return target, newlist - - -_common_varlist = ['SUBST_DICT', 'LINESEPARATOR'] - -_text_varlist = _common_varlist + ['TEXTFILEPREFIX', 'TEXTFILESUFFIX'] -_text_builder = SCons.Builder.Builder( - action=SCons.Action.Action(_action, _strfunc, varlist=_text_varlist), - source_factory=Value, - emitter=_convert_list, - prefix='$TEXTFILEPREFIX', - suffix='$TEXTFILESUFFIX', -) - -_subst_varlist = _common_varlist + ['SUBSTFILEPREFIX', 'SUBSTFILESUFFIX'] -_subst_builder = SCons.Builder.Builder( - action=SCons.Action.Action(_action, _strfunc, varlist=_subst_varlist), - source_factory=SCons.Node.FS.File, - emitter=_convert_list, - prefix='$SUBSTFILEPREFIX', - suffix='$SUBSTFILESUFFIX', - src_suffix=['.in'], -) - - -def generate(env): - env['LINESEPARATOR'] = LINESEP # os.linesep - env['BUILDERS']['Textfile'] = _text_builder - env['TEXTFILEPREFIX'] = '' - env['TEXTFILESUFFIX'] = '.txt' - env['BUILDERS']['Substfile'] = _subst_builder - env['SUBSTFILEPREFIX'] = '' - env['SUBSTFILESUFFIX'] = '' - - -def exists(env): - return 1 - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/tlib.py b/scons/scons-local-4.1.0/SCons/Tool/tlib.py deleted file mode 100644 index 33adb576b..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/tlib.py +++ /dev/null @@ -1,53 +0,0 @@ -"""SCons.Tool.tlib - -XXX - -""" - -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Tool -import SCons.Tool.bcc32 -import SCons.Util - -def generate(env): - SCons.Tool.bcc32.findIt('tlib', env) - """Add Builders and construction variables for ar to an Environment.""" - SCons.Tool.createStaticLibBuilder(env) - env['AR'] = 'tlib' - env['ARFLAGS'] = SCons.Util.CLVar('') - env['ARCOM'] = '$AR $TARGET $ARFLAGS /a $SOURCES' - env['LIBPREFIX'] = '' - env['LIBSUFFIX'] = '.lib' - -def exists(env): - return SCons.Tool.bcc32.findIt('tlib', env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/wix.py b/scons/scons-local-4.1.0/SCons/Tool/wix.py deleted file mode 100644 index 04136ce8e..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/wix.py +++ /dev/null @@ -1,104 +0,0 @@ -"""SCons.Tool.wix - -Tool-specific initialization for wix, the Windows Installer XML Tool. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import SCons.Builder -import SCons.Action -import os - -def generate(env): - """Add Builders and construction variables for WiX to an Environment.""" - if not exists(env): - return - - env['WIXCANDLEFLAGS'] = ['-nologo'] - env['WIXCANDLEINCLUDE'] = [] - env['WIXCANDLECOM'] = '$WIXCANDLE $WIXCANDLEFLAGS -I $WIXCANDLEINCLUDE -o ${TARGET} ${SOURCE}' - - env['WIXLIGHTFLAGS'].append( '-nologo' ) - env['WIXLIGHTCOM'] = "$WIXLIGHT $WIXLIGHTFLAGS -out ${TARGET} ${SOURCES}" - env['WIXSRCSUF'] = '.wxs' - env['WIXOBJSUF'] = '.wixobj' - - object_builder = SCons.Builder.Builder( - action = '$WIXCANDLECOM', - suffix = '$WIXOBJSUF', - src_suffix = '$WIXSRCSUF') - - linker_builder = SCons.Builder.Builder( - action = '$WIXLIGHTCOM', - src_suffix = '$WIXOBJSUF', - src_builder = object_builder) - - env['BUILDERS']['WiX'] = linker_builder - -def exists(env): - env['WIXCANDLE'] = 'candle.exe' - env['WIXLIGHT'] = 'light.exe' - - # try to find the candle.exe and light.exe tools and - # add the install directory to light libpath. - for path in os.environ['PATH'].split(os.pathsep): - if not path: - continue - - # workaround for some weird python win32 bug. - if path[0] == '"' and path[-1:]=='"': - path = path[1:-1] - - # normalize the path - path = os.path.normpath(path) - - # search for the tools in the PATH environment variable - try: - files = os.listdir(path) - if env['WIXCANDLE'] in files and env['WIXLIGHT'] in files: - env.PrependENVPath('PATH', path) - # include appropriate flags if running WiX 2.0 - if 'wixui.wixlib' in files and 'WixUI_en-us.wxl' in files: - env['WIXLIGHTFLAGS'] = [ os.path.join( path, 'wixui.wixlib' ), - '-loc', - os.path.join( path, 'WixUI_en-us.wxl' ) ] - else: - env['WIXLIGHTFLAGS'] = [] - return 1 - except OSError: - pass # ignore this, could be a stale PATH entry. - - return None - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/xgettext.py b/scons/scons-local-4.1.0/SCons/Tool/xgettext.py deleted file mode 100644 index ae4055501..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/xgettext.py +++ /dev/null @@ -1,357 +0,0 @@ -""" xgettext tool - -Tool specific initialization of `xgettext` tool. -""" - -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import re -import subprocess -import sys - -import SCons.Action -import SCons.Node.FS -import SCons.Tool -import SCons.Util -from SCons.Builder import BuilderBase -from SCons.Environment import _null -from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS -from SCons.Platform.mingw import MINGW_DEFAULT_PATHS -from SCons.Tool.GettextCommon import _POTargetFactory -from SCons.Tool.GettextCommon import RPaths, _detect_xgettext -from SCons.Tool.GettextCommon import _xgettext_exists - - -############################################################################# -class _CmdRunner: - """ Callable object, which runs shell command storing its stdout and stderr to - variables. It also provides `strfunction()` method, which shall be used by - scons Action objects to print command string. """ - - def __init__(self, command, commandstr=None): - self.out = None - self.err = None - self.status = None - self.command = command - self.commandstr = commandstr - - def __call__(self, target, source, env): - kw = { - 'stdin': 'devnull', - 'stdout': subprocess.PIPE, - 'stderr': subprocess.PIPE, - 'universal_newlines': True, - 'shell': True - } - command = env.subst(self.command, target=target, source=source) - proc = SCons.Action._subproc(env, command, **kw) - self.out, self.err = proc.communicate() - self.status = proc.wait() - if self.err: - sys.stderr.write(str(self.err)) - return self.status - - def strfunction(self, target, source, env): - comstr = self.commandstr - if env.subst(comstr, target=target, source=source) == "": - comstr = self.command - s = env.subst(comstr, target=target, source=source) - return s - - -############################################################################# - -############################################################################# -def _update_pot_file(target, source, env): - """ Action function for `POTUpdate` builder """ - nop = lambda target, source, env: 0 - - # Save scons cwd and os cwd (NOTE: they may be different. After the job, we - # revert each one to its original state). - save_cwd = env.fs.getcwd() - save_os_cwd = os.getcwd() - chdir = target[0].dir - chdir_str = repr(chdir.get_abspath()) - # Print chdir message (employ SCons.Action.Action for that. It knows better - # than me how to to this correctly). - env.Execute(SCons.Action.Action(nop, "Entering " + chdir_str)) - # Go to target's directory and do our job - env.fs.chdir(chdir, 1) # Go into target's directory - try: - cmd = _CmdRunner('$XGETTEXTCOM', '$XGETTEXTCOMSTR') - action = SCons.Action.Action(cmd, strfunction=cmd.strfunction) - status = action([target[0]], source, env) - except: - # Something went wrong. - env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str)) - # Revert working dirs to previous state and re-throw exception. - env.fs.chdir(save_cwd, 0) - os.chdir(save_os_cwd) - raise - # Print chdir message. - env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str)) - # Revert working dirs to previous state. - env.fs.chdir(save_cwd, 0) - os.chdir(save_os_cwd) - # If the command was not successfull, return error code. - if status: return status - - new_content = cmd.out - - if not new_content: - # When xgettext finds no internationalized messages, no *.pot is created - # (because we don't want to bother translators with empty POT files). - needs_update = False - explain = "no internationalized messages encountered" - else: - if target[0].exists(): - # If the file already exists, it's left unaltered unless its messages - # are outdated (w.r.t. to these recovered by xgettext from sources). - old_content = target[0].get_text_contents() - re_cdate = re.compile(r'^"POT-Creation-Date: .*"$[\r\n]?', re.M) - old_content_nocdate = re.sub(re_cdate, "", old_content) - new_content_nocdate = re.sub(re_cdate, "", new_content) - if old_content_nocdate == new_content_nocdate: - # Messages are up-to-date - needs_update = False - explain = "messages in file found to be up-to-date" - else: - # Messages are outdated - needs_update = True - explain = "messages in file were outdated" - else: - # No POT file found, create new one - needs_update = True - explain = "new file" - if needs_update: - # Print message employing SCons.Action.Action for that. - msg = "Writing " + repr(str(target[0])) + " (" + explain + ")" - env.Execute(SCons.Action.Action(nop, msg)) - f = open(str(target[0]), "w") - f.write(new_content) - f.close() - return 0 - else: - # Print message employing SCons.Action.Action for that. - msg = "Not writing " + repr(str(target[0])) + " (" + explain + ")" - env.Execute(SCons.Action.Action(nop, msg)) - return 0 - - -############################################################################# - -############################################################################# -class _POTBuilder(BuilderBase): - def _execute(self, env, target, source, *args): - if not target: - if 'POTDOMAIN' in env and env['POTDOMAIN']: - domain = env['POTDOMAIN'] - else: - domain = 'messages' - target = [domain] - return BuilderBase._execute(self, env, target, source, *args) - - -############################################################################# - -############################################################################# -def _scan_xgettext_from_files(target, source, env, files=None, path=None): - """ Parses `POTFILES.in`-like file and returns list of extracted file names. - """ - if files is None: - return 0 - if not SCons.Util.is_List(files): - files = [files] - - if path is None: - if 'XGETTEXTPATH' in env: - path = env['XGETTEXTPATH'] - else: - path = [] - if not SCons.Util.is_List(path): - path = [path] - - path = SCons.Util.flatten(path) - - dirs = () - for p in path: - if not isinstance(p, SCons.Node.FS.Base): - if SCons.Util.is_String(p): - p = env.subst(p, source=source, target=target) - p = env.arg2nodes(p, env.fs.Dir) - dirs += tuple(p) - # cwd is the default search path (when no path is defined by user) - if not dirs: - dirs = (env.fs.getcwd(),) - - # Parse 'POTFILE.in' files. - re_comment = re.compile(r'^#[^\n\r]*$\r?\n?', re.M) - re_emptyln = re.compile(r'^[ \t\r]*$\r?\n?', re.M) - re_trailws = re.compile(r'[ \t\r]+$') - for f in files: - # Find files in search path $XGETTEXTPATH - if isinstance(f, SCons.Node.FS.Base) and f.rexists(): - contents = f.get_text_contents() - contents = re_comment.sub("", contents) - contents = re_emptyln.sub("", contents) - contents = re_trailws.sub("", contents) - depnames = contents.splitlines() - for depname in depnames: - depfile = SCons.Node.FS.find_file(depname, dirs) - if not depfile: - depfile = env.arg2nodes(depname, dirs[0].File) - env.Depends(target, depfile) - return 0 - - -############################################################################# - -############################################################################# -def _pot_update_emitter(target, source, env): - """ Emitter function for `POTUpdate` builder """ - if 'XGETTEXTFROM' in env: - xfrom = env['XGETTEXTFROM'] - else: - return target, source - if not SCons.Util.is_List(xfrom): - xfrom = [xfrom] - - xfrom = SCons.Util.flatten(xfrom) - - # Prepare list of 'POTFILE.in' files. - files = [] - for xf in xfrom: - if not isinstance(xf, SCons.Node.FS.Base): - if SCons.Util.is_String(xf): - # Interpolate variables in strings - xf = env.subst(xf, source=source, target=target) - xf = env.arg2nodes(xf) - files.extend(xf) - if files: - env.Depends(target, files) - _scan_xgettext_from_files(target, source, env, files) - return target, source - - -############################################################################# - -############################################################################# -def _POTUpdateBuilderWrapper(env, target=None, source=_null, **kw): - return env._POTUpdateBuilder(target, source, **kw) - - -############################################################################# - -############################################################################# -def _POTUpdateBuilder(env, **kw): - """ Creates `POTUpdate` builder object """ - kw['action'] = SCons.Action.Action(_update_pot_file, None) - kw['suffix'] = '$POTSUFFIX' - kw['target_factory'] = _POTargetFactory(env, alias='$POTUPDATE_ALIAS').File - kw['emitter'] = _pot_update_emitter - return _POTBuilder(**kw) - - -############################################################################# - -############################################################################# -def generate(env, **kw): - """ Generate `xgettext` tool """ - - if sys.platform == 'win32': - xgettext = SCons.Tool.find_program_path(env, 'xgettext', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if xgettext: - xgettext_bin_dir = os.path.dirname(xgettext) - env.AppendENVPath('PATH', xgettext_bin_dir) - else: - SCons.Warnings.SConsWarning('xgettext tool requested, but binary not found in ENV PATH') - try: - env['XGETTEXT'] = _detect_xgettext(env) - except: - env['XGETTEXT'] = 'xgettext' - # NOTE: sources="$SOURCES" would work as well. However, we use following - # construction to convert absolute paths provided by scons onto paths - # relative to current working dir. Note, that scons expands $SOURCE(S) to - # absolute paths for sources $SOURCE(s) outside of current subtree (e.g. in - # "../"). With source=$SOURCE these absolute paths would be written to the - # resultant *.pot file (and its derived *.po files) as references to lines in - # source code (e.g. referring lines in *.c files). Such references would be - # correct (e.g. in poedit) only on machine on which *.pot was generated and - # would be of no use on other hosts (having a copy of source code located - # in different place in filesystem). - sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET' \ - + ', SOURCES)} $)' - - # NOTE: the output from $XGETTEXTCOM command must go to stdout, not to a file. - # This is required by the POTUpdate builder's action. - xgettextcom = '$XGETTEXT $XGETTEXTFLAGS $_XGETTEXTPATHFLAGS' \ - + ' $_XGETTEXTFROMFLAGS -o - ' + sources - - xgettextpathflags = '$( ${_concat( XGETTEXTPATHPREFIX, XGETTEXTPATH' \ - + ', XGETTEXTPATHSUFFIX, __env__, RDirs, TARGET, SOURCES)} $)' - xgettextfromflags = '$( ${_concat( XGETTEXTFROMPREFIX, XGETTEXTFROM' \ - + ', XGETTEXTFROMSUFFIX, __env__, target=TARGET, source=SOURCES)} $)' - - env.SetDefault( - _XGETTEXTDOMAIN='${TARGET.filebase}', - XGETTEXTFLAGS=[], - XGETTEXTCOM=xgettextcom, - XGETTEXTCOMSTR='', - XGETTEXTPATH=[], - XGETTEXTPATHPREFIX='-D', - XGETTEXTPATHSUFFIX='', - XGETTEXTFROM=None, - XGETTEXTFROMPREFIX='-f', - XGETTEXTFROMSUFFIX='', - _XGETTEXTPATHFLAGS=xgettextpathflags, - _XGETTEXTFROMFLAGS=xgettextfromflags, - POTSUFFIX=['.pot'], - POTUPDATE_ALIAS='pot-update', - XgettextRPaths=RPaths(env) - ) - env.Append(BUILDERS={ - '_POTUpdateBuilder': _POTUpdateBuilder(env) - }) - env.AddMethod(_POTUpdateBuilderWrapper, 'POTUpdate') - env.AlwaysBuild(env.Alias('$POTUPDATE_ALIAS')) - - -############################################################################# - -############################################################################# -def exists(env): - """ Check, whether the tool exists """ - try: - return _xgettext_exists(env) - except: - return False - -############################################################################# - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/yacc.py b/scons/scons-local-4.1.0/SCons/Tool/yacc.py deleted file mode 100644 index ab019b2ed..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/yacc.py +++ /dev/null @@ -1,177 +0,0 @@ -"""SCons.Tool.yacc - -Tool-specific initialization for yacc. - -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__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os.path -import sys - -import SCons.Defaults -import SCons.Tool -import SCons.Util -from SCons.Platform.mingw import MINGW_DEFAULT_PATHS -from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS -from SCons.Platform.win32 import CHOCO_DEFAULT_PATH - -YaccAction = SCons.Action.Action("$YACCCOM", "$YACCCOMSTR") - -if sys.platform == 'win32': - BINS = ['bison', 'yacc', 'win_bison'] -else: - BINS = ["bison", "yacc"] - - -def _yaccEmitter(target, source, env, ysuf, hsuf): - yaccflags = env.subst("$YACCFLAGS", target=target, source=source) - flags = SCons.Util.CLVar(yaccflags) - targetBase, targetExt = os.path.splitext(SCons.Util.to_String(target[0])) - - if '.ym' in ysuf: # If using Objective-C - target = [targetBase + ".m"] # the extension is ".m". - - # If -d is specified on the command line, yacc will emit a .h - # or .hpp file with the same name as the .c or .cpp output file. - if '-d' in flags: - target.append(targetBase + env.subst(hsuf, target=target, source=source)) - - # If -g is specified on the command line, yacc will emit a .vcg - # file with the same base name as the .y, .yacc, .ym or .yy file. - if "-g" in flags: - base, ext = os.path.splitext(SCons.Util.to_String(source[0])) - target.append(base + env.subst("$YACCVCGFILESUFFIX")) - - # If -v is specified yacc will create the output debug file - # which is not really source for any process, but should - # be noted and also be cleaned - # Bug #2558 - if "-v" in flags: - env.SideEffect(targetBase + '.output', target[0]) - env.Clean(target[0], targetBase + '.output') - - # With --defines and --graph, the name of the file is totally defined - # in the options. - fileGenOptions = ["--defines=", "--graph="] - for option in flags: - for fileGenOption in fileGenOptions: - l = len(fileGenOption) - if option[:l] == fileGenOption: - # A file generating option is present, so add the file - # name to the list of targets. - fileName = option[l:].strip() - target.append(fileName) - - return (target, source) - - -def yEmitter(target, source, env): - return _yaccEmitter(target, source, env, ['.y', '.yacc'], '$YACCHFILESUFFIX') - - -def ymEmitter(target, source, env): - return _yaccEmitter(target, source, env, ['.ym'], '$YACCHFILESUFFIX') - - -def yyEmitter(target, source, env): - return _yaccEmitter(target, source, env, ['.yy'], '$YACCHXXFILESUFFIX') - - -def get_yacc_path(env, append_paths=False): - """ - Find the path to the yacc tool, searching several possible names - - Only called in the Windows case, so the default_path - can be Windows-specific - - :param env: current construction environment - :param append_paths: if set, add the path to the tool to PATH - :return: path to yacc tool, if found - """ - for prog in BINS: - bin_path = SCons.Tool.find_program_path( - env, - prog, - default_paths=CHOCO_DEFAULT_PATH + MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS) - if bin_path: - if append_paths: - env.AppendENVPath('PATH', os.path.dirname(bin_path)) - return bin_path - SCons.Warnings.SConsWarning('yacc tool requested, but yacc or bison binary not found in ENV PATH') - - -def generate(env): - """Add Builders and construction variables for yacc to an Environment.""" - c_file, cxx_file = SCons.Tool.createCFileBuilders(env) - - # C - c_file.add_action('.y', YaccAction) - c_file.add_emitter('.y', yEmitter) - - c_file.add_action('.yacc', YaccAction) - c_file.add_emitter('.yacc', yEmitter) - - # Objective-C - c_file.add_action('.ym', YaccAction) - c_file.add_emitter('.ym', ymEmitter) - - # C++ - cxx_file.add_action('.yy', YaccAction) - cxx_file.add_emitter('.yy', yyEmitter) - - if sys.platform == 'win32': - # ignore the return, all we need is for the path to be added - _ = get_yacc_path(env, append_paths=True) - - if 'YACC' not in env: - env["YACC"] = env.Detect(BINS) - - env['YACCFLAGS'] = SCons.Util.CLVar('') - env['YACCCOM'] = '$YACC $YACCFLAGS -o $TARGET $SOURCES' - env['YACCHFILESUFFIX'] = '.h' - env['YACCHXXFILESUFFIX'] = '.hpp' - env['YACCVCGFILESUFFIX'] = '.vcg' - - -def exists(env): - if 'YACC' in env: - return env.Detect(env['YACC']) - - if sys.platform == 'win32': - return get_yacc_path(env) - else: - return env.Detect(BINS) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Tool/zip.py b/scons/scons-local-4.1.0/SCons/Tool/zip.py deleted file mode 100644 index f3d38fe7a..000000000 --- a/scons/scons-local-4.1.0/SCons/Tool/zip.py +++ /dev/null @@ -1,120 +0,0 @@ -"""SCons.Tool.zip - -Tool-specific initialization for zip. - -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. - -""" - -# MIT License -# -# Copyright 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. - -import os - -import SCons.Builder -import SCons.Defaults -import SCons.Node.FS -import SCons.Util - -import time -import zipfile - - -zip_compression = zipfile.ZIP_DEFLATED - - -def _create_zipinfo_for_file(fname, arcname, date_time, compression): - st = os.stat(fname) - if not date_time: - mtime = time.localtime(st.st_mtime) - date_time = mtime[0:6] - zinfo = zipfile.ZipInfo(filename=arcname, date_time=date_time) - zinfo.external_attr = (st.st_mode & 0xFFFF) << 16 # Unix attributes - zinfo.compress_type = compression - zinfo.file_size = st.st_size - return zinfo - - -def zip_builder(target, source, env): - compression = env.get('ZIPCOMPRESSION', zipfile.ZIP_STORED) - zip_root = str(env.get('ZIPROOT', '')) - date_time = env.get('ZIP_OVERRIDE_TIMESTAMP') - - files = [] - for s in source: - if s.isdir(): - for dirpath, dirnames, filenames in os.walk(str(s)): - for fname in filenames: - path = os.path.join(dirpath, fname) - if os.path.isfile(path): - files.append(path) - else: - files.append(str(s)) - - with zipfile.ZipFile(str(target[0]), 'w', compression) as zf: - for fname in files: - arcname = os.path.relpath(fname, zip_root) - # TODO: Switch to ZipInfo.from_file when 3.6 becomes the base python version - zinfo = _create_zipinfo_for_file(fname, arcname, date_time, compression) - with open(fname, "rb") as f: - zf.writestr(zinfo, f.read()) - - -# Fix PR #3569 - If you don't specify ZIPCOM and ZIPCOMSTR when creating -# env, then it will ignore ZIPCOMSTR set afterwards. -zipAction = SCons.Action.Action(zip_builder, "$ZIPCOMSTR", - varlist=['ZIPCOMPRESSION', 'ZIPROOT', 'ZIP_OVERRIDE_TIMESTAMP']) - -ZipBuilder = SCons.Builder.Builder(action=SCons.Action.Action('$ZIPCOM', '$ZIPCOMSTR'), - source_factory=SCons.Node.FS.Entry, - source_scanner=SCons.Defaults.DirScanner, - suffix='$ZIPSUFFIX', - multi=1) - - -def generate(env): - """Add Builders and construction variables for zip to an Environment.""" - try: - bld = env['BUILDERS']['Zip'] - except KeyError: - bld = ZipBuilder - env['BUILDERS']['Zip'] = bld - - env['ZIP'] = 'zip' - env['ZIPFLAGS'] = SCons.Util.CLVar('') - env['ZIPCOM'] = zipAction - env['ZIPCOMPRESSION'] = zip_compression - env['ZIPSUFFIX'] = '.zip' - env['ZIPROOT'] = SCons.Util.CLVar('') - - -def exists(env): - return True - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Util.py b/scons/scons-local-4.1.0/SCons/Util.py deleted file mode 100644 index 0f26fb134..000000000 --- a/scons/scons-local-4.1.0/SCons/Util.py +++ /dev/null @@ -1,1655 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Various SCons utility functions.""" - -import os -import sys -import copy -import re -import pprint -import hashlib -from collections import UserDict, UserList, UserString, OrderedDict -from collections.abc import MappingView -from types import MethodType, FunctionType - -PYPY = hasattr(sys, 'pypy_translation_info') - -# this string will be hashed if a Node refers to a file that doesn't exist -# in order to distinguish from a file that exists but is empty. -NOFILE = "SCONS_MAGIC_MISSING_FILE_STRING" - -# unused? -def dictify(keys, values, result=None): - if result is None: - result = {} - result.update(dict(zip(keys, values))) - return result - -_altsep = os.altsep -if _altsep is None and sys.platform == 'win32': - # My ActivePython 2.0.1 doesn't set os.altsep! What gives? - _altsep = '/' -if _altsep: - def rightmost_separator(path, sep): - return max(path.rfind(sep), path.rfind(_altsep)) -else: - def rightmost_separator(path, sep): - return path.rfind(sep) - -# First two from the Python Cookbook, just for completeness. -# (Yeah, yeah, YAGNI...) -def containsAny(str, set): - """Check whether sequence str contains ANY of the items in set.""" - for c in set: - if c in str: return 1 - return 0 - -def containsAll(str, set): - """Check whether sequence str contains ALL of the items in set.""" - for c in set: - if c not in str: return 0 - return 1 - -def containsOnly(str, set): - """Check whether sequence str contains ONLY items in set.""" - for c in str: - if c not in set: return 0 - return 1 - -def splitext(path): - """Same as os.path.splitext() but faster.""" - sep = rightmost_separator(path, os.sep) - dot = path.rfind('.') - # An ext is only real if it has at least one non-digit char - if dot > sep and not containsOnly(path[dot:], "0123456789."): - return path[:dot],path[dot:] - else: - return path,"" - -def updrive(path): - """ - Make the drive letter (if any) upper case. - This is useful because Windows is inconsistent on the case - of the drive letter, which can cause inconsistencies when - calculating command signatures. - """ - drive, rest = os.path.splitdrive(path) - if drive: - path = drive.upper() + rest - return path - -class NodeList(UserList): - """This class is almost exactly like a regular list of Nodes - (actually it can hold any object), with one important difference. - If you try to get an attribute from this list, it will return that - attribute from every item in the list. For example: - - >>> someList = NodeList([ ' foo ', ' bar ' ]) - >>> someList.strip() - [ 'foo', 'bar' ] - """ - -# def __init__(self, initlist=None): -# self.data = [] -# # print("TYPE:%s"%type(initlist)) -# if initlist is not None: -# # XXX should this accept an arbitrary sequence? -# if type(initlist) == type(self.data): -# self.data[:] = initlist -# elif isinstance(initlist, (UserList, NodeList)): -# self.data[:] = initlist.data[:] -# elif isinstance(initlist, Iterable): -# self.data = list(initlist) -# else: -# self.data = [ initlist,] - - - def __bool__(self): - return len(self.data) != 0 - - def __str__(self): - return ' '.join(map(str, self.data)) - - def __iter__(self): - return iter(self.data) - - def __call__(self, *args, **kwargs): - result = [x(*args, **kwargs) for x in self.data] - return self.__class__(result) - - def __getattr__(self, name): - result = [getattr(x, name) for x in self.data] - return self.__class__(result) - - def __getitem__(self, index): - """ - This comes for free on py2, - but py3 slices of NodeList are returning a list - breaking slicing nodelist and refering to - properties and methods on contained object - """ -# return self.__class__(self.data[index]) - - if isinstance(index, slice): - # Expand the slice object using range() - # limited by number of items in self.data - indices = index.indices(len(self.data)) - return self.__class__([self[x] for x in - range(*indices)]) - else: - # Return one item of the tart - return self.data[index] - - -_get_env_var = re.compile(r'^\$([_a-zA-Z]\w*|{[_a-zA-Z]\w*})$') - -def get_environment_var(varstr): - """Given a string, first determine if it looks like a reference - to a single environment variable, like "$FOO" or "${FOO}". - If so, return that variable with no decorations ("FOO"). - If not, return None.""" - mo=_get_env_var.match(to_String(varstr)) - if mo: - var = mo.group(1) - if var[0] == '{': - return var[1:-1] - else: - return var - else: - return None - - -class DisplayEngine: - print_it = True - - def __call__(self, text, append_newline=1): - if not self.print_it: - return - if append_newline: text = text + '\n' - try: - sys.stdout.write(str(text)) - except IOError: - # Stdout might be connected to a pipe that has been closed - # by now. The most likely reason for the pipe being closed - # is that the user has press ctrl-c. It this is the case, - # then SCons is currently shutdown. We therefore ignore - # IOError's here so that SCons can continue and shutdown - # properly so that the .sconsign is correctly written - # before SCons exits. - pass - - def set_mode(self, mode): - self.print_it = mode - - -def render_tree(root, child_func, prune=0, margin=[0], visited=None): - """ - Render a tree of nodes into an ASCII tree view. - - :Parameters: - - `root`: the root node of the tree - - `child_func`: the function called to get the children of a node - - `prune`: don't visit the same node twice - - `margin`: the format of the left margin to use for children of root. 1 results in a pipe, and 0 results in no pipe. - - `visited`: a dictionary of visited nodes in the current branch if not prune, or in the whole tree if prune. - """ - - rname = str(root) - - # Initialize 'visited' dict, if required - if visited is None: - visited = {} - - children = child_func(root) - retval = "" - for pipe in margin[:-1]: - if pipe: - retval = retval + "| " - else: - retval = retval + " " - - if rname in visited: - return retval + "+-[" + rname + "]\n" - - retval = retval + "+-" + rname + "\n" - if not prune: - visited = copy.copy(visited) - visited[rname] = 1 - - for i in range(len(children)): - margin.append(i < len(children)-1) - retval = retval + render_tree(children[i], child_func, prune, margin, visited) - margin.pop() - - return retval - -IDX = lambda N: N and 1 or 0 - -# unicode line drawing chars: -BOX_HORIZ = chr(0x2500) # '─' -BOX_VERT = chr(0x2502) # '│' -BOX_UP_RIGHT = chr(0x2514) # '└' -BOX_DOWN_RIGHT = chr(0x250c) # '┌' -BOX_DOWN_LEFT = chr(0x2510) # '┐' -BOX_UP_LEFT = chr(0x2518) # '┘' -BOX_VERT_RIGHT = chr(0x251c) # '├' -BOX_HORIZ_DOWN = chr(0x252c) # '┬' - - -def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited=None, lastChild=False, singleLineDraw=False): - """ - Print a tree of nodes. This is like render_tree, except it prints - lines directly instead of creating a string representation in memory, - so that huge trees can be printed. - - :Parameters: - - `root` - the root node of the tree - - `child_func` - the function called to get the children of a node - - `prune` - don't visit the same node twice - - `showtags` - print status information to the left of each node line - - `margin` - the format of the left margin to use for children of root. 1 results in a pipe, and 0 results in no pipe. - - `visited` - a dictionary of visited nodes in the current branch if not prune, or in the whole tree if prune. - - `singleLineDraw` - use line-drawing characters rather than ASCII. - """ - - rname = str(root) - - - # Initialize 'visited' dict, if required - if visited is None: - visited = {} - - if showtags: - - if showtags == 2: - legend = (' E = exists\n' + - ' R = exists in repository only\n' + - ' b = implicit builder\n' + - ' B = explicit builder\n' + - ' S = side effect\n' + - ' P = precious\n' + - ' A = always build\n' + - ' C = current\n' + - ' N = no clean\n' + - ' H = no cache\n' + - '\n') - sys.stdout.write(legend) - - tags = [ - '[', - ' E'[IDX(root.exists())], - ' R'[IDX(root.rexists() and not root.exists())], - ' BbB'[ - [0, 1][IDX(root.has_explicit_builder())] + - [0, 2][IDX(root.has_builder())] - ], - ' S'[IDX(root.side_effect)], - ' P'[IDX(root.precious)], - ' A'[IDX(root.always_build)], - ' C'[IDX(root.is_up_to_date())], - ' N'[IDX(root.noclean)], - ' H'[IDX(root.nocache)], - ']' - ] - - else: - tags = [] - - def MMM(m): - if singleLineDraw: - return [" ", BOX_VERT + " "][m] - else: - return [" ", "| "][m] - - margins = list(map(MMM, margin[:-1])) - - children = child_func(root) - - - cross = "+-" - if singleLineDraw: - cross = BOX_VERT_RIGHT + BOX_HORIZ # sign used to point to the leaf. - # check if this is the last leaf of the branch - if lastChild: - #if this if the last leaf, then terminate: - cross = BOX_UP_RIGHT + BOX_HORIZ # sign for the last leaf - - # if this branch has children then split it - if children: - # if it's a leaf: - if prune and rname in visited and children: - cross += BOX_HORIZ - else: - cross += BOX_HORIZ_DOWN - - if prune and rname in visited and children: - sys.stdout.write(''.join(tags + margins + [cross,'[', rname, ']']) + '\n') - return - - sys.stdout.write(''.join(tags + margins + [cross, rname]) + '\n') - - visited[rname] = 1 - - # if this item has children: - if children: - margin.append(1) # Initialize margin with 1 for vertical bar. - idx = IDX(showtags) - _child = 0 # Initialize this for the first child. - for C in children[:-1]: - _child = _child + 1 # number the children - print_tree(C, child_func, prune, idx, margin, visited, (len(children) - _child) <= 0 ,singleLineDraw) - margin[-1] = 0 # margins are with space (index 0) because we arrived to the last child. - print_tree(children[-1], child_func, prune, idx, margin, visited, True ,singleLineDraw) # for this call child and nr of children needs to be set 0, to signal the second phase. - margin.pop() # destroy the last margin added - - -# Functions for deciding if things are like various types, mainly to -# handle UserDict, UserList and UserString like their underlying types. -# -# Yes, all of this manual testing breaks polymorphism, and the real -# Pythonic way to do all of this would be to just try it and handle the -# exception, but handling the exception when it's not the right type is -# often too slow. - -# We are using the following trick to speed up these -# functions. Default arguments are used to take a snapshot of -# the global functions and constants used by these functions. This -# transforms accesses to global variable into local variables -# accesses (i.e. LOAD_FAST instead of LOAD_GLOBAL). - -DictTypes = (dict, UserDict) -ListTypes = (list, UserList) - -# Handle getting dictionary views. -SequenceTypes = (list, tuple, UserList, MappingView) - -# TODO: PY3 check this benchmarking is still correct. -# Note that profiling data shows a speed-up when comparing -# explicitly with str instead of simply comparing -# with basestring. (at least on Python 2.5.1) -StringTypes = (str, UserString) - -# Empirically, it is faster to check explicitly for str than for basestring. -BaseStringTypes = str - -def is_Dict(obj, isinstance=isinstance, DictTypes=DictTypes): - return isinstance(obj, DictTypes) - -def is_List(obj, isinstance=isinstance, ListTypes=ListTypes): - return isinstance(obj, ListTypes) - -def is_Sequence(obj, isinstance=isinstance, SequenceTypes=SequenceTypes): - return isinstance(obj, SequenceTypes) - -def is_Tuple(obj, isinstance=isinstance, tuple=tuple): - return isinstance(obj, tuple) - -def is_String(obj, isinstance=isinstance, StringTypes=StringTypes): - return isinstance(obj, StringTypes) - -def is_Scalar(obj, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes): - # Profiling shows that there is an impressive speed-up of 2x - # when explicitly checking for strings instead of just not - # sequence when the argument (i.e. obj) is already a string. - # But, if obj is a not string then it is twice as fast to - # check only for 'not sequence'. The following code therefore - # assumes that the obj argument is a string most of the time. - return isinstance(obj, StringTypes) or not isinstance(obj, SequenceTypes) - -def do_flatten(sequence, result, isinstance=isinstance, - StringTypes=StringTypes, SequenceTypes=SequenceTypes): - for item in sequence: - if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes): - result.append(item) - else: - do_flatten(item, result) - -def flatten(obj, isinstance=isinstance, StringTypes=StringTypes, - SequenceTypes=SequenceTypes, do_flatten=do_flatten): - """Flatten a sequence to a non-nested list. - - Flatten() converts either a single scalar or a nested sequence - to a non-nested list. Note that flatten() considers strings - to be scalars instead of sequences like Python would. - """ - if isinstance(obj, StringTypes) or not isinstance(obj, SequenceTypes): - return [obj] - result = [] - for item in obj: - if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes): - result.append(item) - else: - do_flatten(item, result) - return result - -def flatten_sequence(sequence, isinstance=isinstance, StringTypes=StringTypes, - SequenceTypes=SequenceTypes, do_flatten=do_flatten): - """Flatten a sequence to a non-nested list. - - Same as flatten(), but it does not handle the single scalar - case. This is slightly more efficient when one knows that - the sequence to flatten can not be a scalar. - """ - result = [] - for item in sequence: - if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes): - result.append(item) - else: - do_flatten(item, result) - return result - -# Generic convert-to-string functions. The wrapper -# to_String_for_signature() will use a for_signature() method if the -# specified object has one. -# - - -def to_String(s, - isinstance=isinstance, str=str, - UserString=UserString, BaseStringTypes=BaseStringTypes): - if isinstance(s, BaseStringTypes): - # Early out when already a string! - return s - elif isinstance(s, UserString): - # s.data can only be a regular string. Please see the UserString initializer. - return s.data - else: - return str(s) - - -def to_String_for_subst(s, - isinstance=isinstance, str=str, to_String=to_String, - BaseStringTypes=BaseStringTypes, SequenceTypes=SequenceTypes, - UserString=UserString): - - # Note that the test cases are sorted by order of probability. - if isinstance(s, BaseStringTypes): - return s - elif isinstance(s, SequenceTypes): - return ' '.join([to_String_for_subst(e) for e in s]) - elif isinstance(s, UserString): - # s.data can only a regular string. Please see the UserString initializer. - return s.data - else: - return str(s) - - -def to_String_for_signature(obj, to_String_for_subst=to_String_for_subst, - AttributeError=AttributeError): - try: - f = obj.for_signature - except AttributeError: - if isinstance(obj, dict): - # pprint will output dictionary in key sorted order - # with py3.5 the order was randomized. In general depending on dictionary order - # which was undefined until py3.6 (where it's by insertion order) was not wise. - # TODO: Change code when floor is raised to PY36 - return pprint.pformat(obj, width=1000000) - else: - return to_String_for_subst(obj) - else: - return f() - - -# The SCons "semi-deep" copy. -# -# This makes separate copies of lists (including UserList objects) -# dictionaries (including UserDict objects) and tuples, but just copies -# references to anything else it finds. -# -# A special case is any object that has a __semi_deepcopy__() method, -# which we invoke to create the copy. Currently only used by -# BuilderDict to actually prevent the copy operation (as invalid on that object). -# -# The dispatch table approach used here is a direct rip-off from the -# normal Python copy module. - -_semi_deepcopy_dispatch = d = {} - -def semi_deepcopy_dict(x, exclude = [] ): - copy = {} - for key, val in x.items(): - # The regular Python copy.deepcopy() also deepcopies the key, - # as follows: - # - # copy[semi_deepcopy(key)] = semi_deepcopy(val) - # - # Doesn't seem like we need to, but we'll comment it just in case. - if key not in exclude: - copy[key] = semi_deepcopy(val) - return copy -d[dict] = semi_deepcopy_dict - -def _semi_deepcopy_list(x): - return list(map(semi_deepcopy, x)) -d[list] = _semi_deepcopy_list - -def _semi_deepcopy_tuple(x): - return tuple(map(semi_deepcopy, x)) -d[tuple] = _semi_deepcopy_tuple - -def semi_deepcopy(x): - copier = _semi_deepcopy_dispatch.get(type(x)) - if copier: - return copier(x) - else: - if hasattr(x, '__semi_deepcopy__') and callable(x.__semi_deepcopy__): - return x.__semi_deepcopy__() - elif isinstance(x, UserDict): - return x.__class__(semi_deepcopy_dict(x)) - elif isinstance(x, UserList): - return x.__class__(_semi_deepcopy_list(x)) - - return x - - -class Proxy: - """A simple generic Proxy class, forwarding all calls to - subject. So, for the benefit of the python newbie, what does - this really mean? Well, it means that you can take an object, let's - call it 'objA', and wrap it in this Proxy class, with a statement - like this - - proxyObj = Proxy(objA), - - Then, if in the future, you do something like this - - x = proxyObj.var1, - - since Proxy does not have a 'var1' attribute (but presumably objA does), - the request actually is equivalent to saying - - x = objA.var1 - - Inherit from this class to create a Proxy. - - Note that, with new-style classes, this does *not* work transparently - for Proxy subclasses that use special .__*__() method names, because - those names are now bound to the class, not the individual instances. - You now need to know in advance which .__*__() method names you want - to pass on to the underlying Proxy object, and specifically delegate - their calls like this: - - class Foo(Proxy): - __str__ = Delegate('__str__') - """ - - def __init__(self, subject): - """Wrap an object as a Proxy object""" - self._subject = subject - - def __getattr__(self, name): - """Retrieve an attribute from the wrapped object. If the named - attribute doesn't exist, AttributeError is raised""" - return getattr(self._subject, name) - - def get(self): - """Retrieve the entire wrapped object""" - return self._subject - - def __eq__(self, other): - if issubclass(other.__class__, self._subject.__class__): - return self._subject == other - return self.__dict__ == other.__dict__ - - -class Delegate: - """A Python Descriptor class that delegates attribute fetches - to an underlying wrapped subject of a Proxy. Typical use: - - class Foo(Proxy): - __str__ = Delegate('__str__') - """ - def __init__(self, attribute): - self.attribute = attribute - - def __get__(self, obj, cls): - if isinstance(obj, cls): - return getattr(obj._subject, self.attribute) - else: - return self - - -class MethodWrapper: - """A generic Wrapper class that associates a method with an object. - - As part of creating this MethodWrapper object an attribute with the - specified name (by default, the name of the supplied method) is added - to the underlying object. When that new "method" is called, our - __call__() method adds the object as the first argument, simulating - the Python behavior of supplying "self" on method calls. - - We hang on to the name by which the method was added to the underlying - base class so that we can provide a method to "clone" ourselves onto - a new underlying object being copied (without which we wouldn't need - to save that info). - """ - def __init__(self, object, method, name=None): - if name is None: - name = method.__name__ - self.object = object - self.method = method - self.name = name - setattr(self.object, name, self) - - def __call__(self, *args, **kwargs): - nargs = (self.object,) + args - return self.method(*nargs, **kwargs) - - def clone(self, new_object): - """ - Returns an object that re-binds the underlying "method" to - the specified new object. - """ - return self.__class__(new_object, self.method, self.name) - - -# attempt to load the windows registry module: -can_read_reg = 0 -try: - import winreg - - can_read_reg = 1 - hkey_mod = winreg - - RegOpenKeyEx = winreg.OpenKeyEx - RegEnumKey = winreg.EnumKey - RegEnumValue = winreg.EnumValue - RegQueryValueEx = winreg.QueryValueEx - RegError = winreg.error - -except ImportError: - class _NoError(Exception): - pass - RegError = _NoError - - -# Make sure we have a definition of WindowsError so we can -# run platform-independent tests of Windows functionality on -# platforms other than Windows. (WindowsError is, in fact, an -# OSError subclass on Windows.) - -class PlainWindowsError(OSError): - pass - -try: - WinError = WindowsError -except NameError: - WinError = PlainWindowsError - - -if can_read_reg: - HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT - HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE - HKEY_CURRENT_USER = hkey_mod.HKEY_CURRENT_USER - HKEY_USERS = hkey_mod.HKEY_USERS - - def RegGetValue(root, key): - r"""This utility function returns a value in the registry - without having to open the key first. Only available on - Windows platforms with a version of Python that can read the - registry. Returns the same thing as - SCons.Util.RegQueryValueEx, except you just specify the entire - path to the value, and don't have to bother opening the key - first. So: - - Instead of: - k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, - r'SOFTWARE\Microsoft\Windows\CurrentVersion') - out = SCons.Util.RegQueryValueEx(k, - 'ProgramFilesDir') - - You can write: - out = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, - r'SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir') - """ - # I would use os.path.split here, but it's not a filesystem - # path... - p = key.rfind('\\') + 1 - keyp = key[:p-1] # -1 to omit trailing slash - val = key[p:] - k = RegOpenKeyEx(root, keyp) - return RegQueryValueEx(k,val) -else: - HKEY_CLASSES_ROOT = None - HKEY_LOCAL_MACHINE = None - HKEY_CURRENT_USER = None - HKEY_USERS = None - - def RegGetValue(root, key): - raise WinError - - def RegOpenKeyEx(root, key): - raise WinError - -if sys.platform == 'win32': - - def WhereIs(file, path=None, pathext=None, reject=[]): - if path is None: - try: - path = os.environ['PATH'] - except KeyError: - return None - if is_String(path): - path = path.split(os.pathsep) - if pathext is None: - try: - pathext = os.environ['PATHEXT'] - except KeyError: - pathext = '.COM;.EXE;.BAT;.CMD' - if is_String(pathext): - pathext = pathext.split(os.pathsep) - for ext in pathext: - if ext.lower() == file[-len(ext):].lower(): - pathext = [''] - break - if not is_List(reject) and not is_Tuple(reject): - reject = [reject] - for dir in path: - f = os.path.join(dir, file) - for ext in pathext: - fext = f + ext - if os.path.isfile(fext): - try: - reject.index(fext) - except ValueError: - return os.path.normpath(fext) - continue - return None - -elif os.name == 'os2': - - def WhereIs(file, path=None, pathext=None, reject=[]): - if path is None: - try: - path = os.environ['PATH'] - except KeyError: - return None - if is_String(path): - path = path.split(os.pathsep) - if pathext is None: - pathext = ['.exe', '.cmd'] - for ext in pathext: - if ext.lower() == file[-len(ext):].lower(): - pathext = [''] - break - if not is_List(reject) and not is_Tuple(reject): - reject = [reject] - for dir in path: - f = os.path.join(dir, file) - for ext in pathext: - fext = f + ext - if os.path.isfile(fext): - try: - reject.index(fext) - except ValueError: - return os.path.normpath(fext) - continue - return None - -else: - - def WhereIs(file, path=None, pathext=None, reject=[]): - import stat - if path is None: - try: - path = os.environ['PATH'] - except KeyError: - return None - if is_String(path): - path = path.split(os.pathsep) - if not is_List(reject) and not is_Tuple(reject): - reject = [reject] - for d in path: - f = os.path.join(d, file) - if os.path.isfile(f): - try: - st = os.stat(f) - except OSError: - # os.stat() raises OSError, not IOError if the file - # doesn't exist, so in this case we let IOError get - # raised so as to not mask possibly serious disk or - # network issues. - continue - if stat.S_IMODE(st[stat.ST_MODE]) & 0o111: - try: - reject.index(f) - except ValueError: - return os.path.normpath(f) - continue - return None - -def PrependPath(oldpath, newpath, sep = os.pathsep, - delete_existing=1, canonicalize=None): - """This prepends newpath elements to the given oldpath. Will only - add any particular path once (leaving the first one it encounters - and ignoring the rest, to preserve path order), and will - os.path.normpath and os.path.normcase all paths to help assure - this. This can also handle the case where the given old path - variable is a list instead of a string, in which case a list will - be returned instead of a string. - - Example: - Old Path: "/foo/bar:/foo" - New Path: "/biz/boom:/foo" - Result: "/biz/boom:/foo:/foo/bar" - - If delete_existing is 0, then adding a path that exists will - not move it to the beginning; it will stay where it is in the - list. - - If canonicalize is not None, it is applied to each element of - newpath before use. - """ - - orig = oldpath - is_list = 1 - paths = orig - if not is_List(orig) and not is_Tuple(orig): - paths = paths.split(sep) - is_list = 0 - - if is_String(newpath): - newpaths = newpath.split(sep) - elif not is_List(newpath) and not is_Tuple(newpath): - newpaths = [ newpath ] # might be a Dir - else: - newpaths = newpath - - if canonicalize: - newpaths=list(map(canonicalize, newpaths)) - - if not delete_existing: - # First uniquify the old paths, making sure to - # preserve the first instance (in Unix/Linux, - # the first one wins), and remembering them in normpaths. - # Then insert the new paths at the head of the list - # if they're not already in the normpaths list. - result = [] - normpaths = [] - for path in paths: - if not path: - continue - normpath = os.path.normpath(os.path.normcase(path)) - if normpath not in normpaths: - result.append(path) - normpaths.append(normpath) - newpaths.reverse() # since we're inserting at the head - for path in newpaths: - if not path: - continue - normpath = os.path.normpath(os.path.normcase(path)) - if normpath not in normpaths: - result.insert(0, path) - normpaths.append(normpath) - paths = result - - else: - newpaths = newpaths + paths # prepend new paths - - normpaths = [] - paths = [] - # now we add them only if they are unique - for path in newpaths: - normpath = os.path.normpath(os.path.normcase(path)) - if path and normpath not in normpaths: - paths.append(path) - normpaths.append(normpath) - - if is_list: - return paths - else: - return sep.join(paths) - -def AppendPath(oldpath, newpath, sep = os.pathsep, - delete_existing=1, canonicalize=None): - """This appends new path elements to the given old path. Will - only add any particular path once (leaving the last one it - encounters and ignoring the rest, to preserve path order), and - will os.path.normpath and os.path.normcase all paths to help - assure this. This can also handle the case where the given old - path variable is a list instead of a string, in which case a list - will be returned instead of a string. - - Example: - Old Path: "/foo/bar:/foo" - New Path: "/biz/boom:/foo" - Result: "/foo/bar:/biz/boom:/foo" - - If delete_existing is 0, then adding a path that exists - will not move it to the end; it will stay where it is in the list. - - If canonicalize is not None, it is applied to each element of - newpath before use. - """ - - orig = oldpath - is_list = 1 - paths = orig - if not is_List(orig) and not is_Tuple(orig): - paths = paths.split(sep) - is_list = 0 - - if is_String(newpath): - newpaths = newpath.split(sep) - elif not is_List(newpath) and not is_Tuple(newpath): - newpaths = [ newpath ] # might be a Dir - else: - newpaths = newpath - - if canonicalize: - newpaths=list(map(canonicalize, newpaths)) - - if not delete_existing: - # add old paths to result, then - # add new paths if not already present - # (I thought about using a dict for normpaths for speed, - # but it's not clear hashing the strings would be faster - # than linear searching these typically short lists.) - result = [] - normpaths = [] - for path in paths: - if not path: - continue - result.append(path) - normpaths.append(os.path.normpath(os.path.normcase(path))) - for path in newpaths: - if not path: - continue - normpath = os.path.normpath(os.path.normcase(path)) - if normpath not in normpaths: - result.append(path) - normpaths.append(normpath) - paths = result - else: - # start w/ new paths, add old ones if not present, - # then reverse. - newpaths = paths + newpaths # append new paths - newpaths.reverse() - - normpaths = [] - paths = [] - # now we add them only if they are unique - for path in newpaths: - normpath = os.path.normpath(os.path.normcase(path)) - if path and normpath not in normpaths: - paths.append(path) - normpaths.append(normpath) - paths.reverse() - - if is_list: - return paths - else: - return sep.join(paths) - -def AddPathIfNotExists(env_dict, key, path, sep=os.pathsep): - """This function will take 'key' out of the dictionary - 'env_dict', then add the path 'path' to that key if it is not - already there. This treats the value of env_dict[key] as if it - has a similar format to the PATH variable...a list of paths - separated by tokens. The 'path' will get added to the list if it - is not already there.""" - try: - is_list = 1 - paths = env_dict[key] - if not is_List(env_dict[key]): - paths = paths.split(sep) - is_list = 0 - if os.path.normcase(path) not in list(map(os.path.normcase, paths)): - paths = [ path ] + paths - if is_list: - env_dict[key] = paths - else: - env_dict[key] = sep.join(paths) - except KeyError: - env_dict[key] = path - -if sys.platform == 'cygwin': - def get_native_path(path): - """Transforms an absolute path into a native path for the system. In - Cygwin, this converts from a Cygwin path to a Windows one.""" - with os.popen('cygpath -w ' + path) as p: - npath = p.read().replace('\n', '') - return npath -else: - def get_native_path(path): - """Transforms an absolute path into a native path for the system. - Non-Cygwin version, just leave the path alone.""" - return path - -display = DisplayEngine() - -def Split(arg): - if is_List(arg) or is_Tuple(arg): - return arg - elif is_String(arg): - return arg.split() - else: - return [arg] - -class CLVar(UserList): - """A class for command-line construction variables. - - This is a list that uses Split() to split an initial string along - white-space arguments, and similarly to split any strings that get - added. This allows us to Do the Right Thing with Append() and - Prepend() (as well as straight Python foo = env['VAR'] + 'arg1 - arg2') regardless of whether a user adds a list or a string to a - command-line construction variable. - """ - def __init__(self, seq = []): - UserList.__init__(self, Split(seq)) - def __add__(self, other): - return UserList.__add__(self, CLVar(other)) - def __radd__(self, other): - return UserList.__radd__(self, CLVar(other)) - def __str__(self): - return ' '.join(self.data) - - -class Selector(OrderedDict): - """A callable ordered dictionary that maps file suffixes to - dictionary values. We preserve the order in which items are added - so that get_suffix() calls always return the first suffix added.""" - def __call__(self, env, source, ext=None): - if ext is None: - try: - ext = source[0].get_suffix() - except IndexError: - ext = "" - try: - return self[ext] - except KeyError: - # Try to perform Environment substitution on the keys of - # the dictionary before giving up. - s_dict = {} - for (k,v) in self.items(): - if k is not None: - s_k = env.subst(k) - if s_k in s_dict: - # We only raise an error when variables point - # to the same suffix. If one suffix is literal - # and a variable suffix contains this literal, - # the literal wins and we don't raise an error. - raise KeyError(s_dict[s_k][0], k, s_k) - s_dict[s_k] = (k,v) - try: - return s_dict[ext][1] - except KeyError: - try: - return self[None] - except KeyError: - return None - - -if sys.platform == 'cygwin': - # On Cygwin, os.path.normcase() lies, so just report back the - # fact that the underlying Windows OS is case-insensitive. - def case_sensitive_suffixes(s1, s2): - return 0 -else: - def case_sensitive_suffixes(s1, s2): - return (os.path.normcase(s1) != os.path.normcase(s2)) - -def adjustixes(fname, pre, suf, ensure_suffix=False): - if pre: - path, fn = os.path.split(os.path.normpath(fname)) - if fn[:len(pre)] != pre: - fname = os.path.join(path, pre + fn) - # Only append a suffix if the suffix we're going to add isn't already - # there, and if either we've been asked to ensure the specific suffix - # is present or there's no suffix on it at all. - if suf and fname[-len(suf):] != suf and \ - (ensure_suffix or not splitext(fname)[1]): - fname = fname + suf - return fname - - - -# From Tim Peters, -# https://code.activestate.com/recipes/52560 -# ASPN: Python Cookbook: Remove duplicates from a sequence -# (Also in the printed Python Cookbook.) - -def unique(s): - """Return a list of the elements in s, but without duplicates. - - For example, unique([1,2,3,1,2,3]) is some permutation of [1,2,3], - unique("abcabc") some permutation of ["a", "b", "c"], and - unique(([1, 2], [2, 3], [1, 2])) some permutation of - [[2, 3], [1, 2]]. - - For best speed, all sequence elements should be hashable. Then - unique() will usually work in linear time. - - If not possible, the sequence elements should enjoy a total - ordering, and if list(s).sort() doesn't raise TypeError it's - assumed that they do enjoy a total ordering. Then unique() will - usually work in O(N*log2(N)) time. - - If that's not possible either, the sequence elements must support - equality-testing. Then unique() will usually work in quadratic - time. - """ - - n = len(s) - if n == 0: - return [] - - # Try using a dict first, as that's the fastest and will usually - # work. If it doesn't work, it will usually fail quickly, so it - # usually doesn't cost much to *try* it. It requires that all the - # sequence elements be hashable, and support equality comparison. - u = {} - try: - for x in s: - u[x] = 1 - except TypeError: - pass # move on to the next method - else: - return list(u.keys()) - del u - - # We can't hash all the elements. Second fastest is to sort, - # which brings the equal elements together; then duplicates are - # easy to weed out in a single pass. - # NOTE: Python's list.sort() was designed to be efficient in the - # presence of many duplicate elements. This isn't true of all - # sort functions in all languages or libraries, so this approach - # is more effective in Python than it may be elsewhere. - try: - t = sorted(s) - except TypeError: - pass # move on to the next method - else: - assert n > 0 - last = t[0] - lasti = i = 1 - while i < n: - if t[i] != last: - t[lasti] = last = t[i] - lasti = lasti + 1 - i = i + 1 - return t[:lasti] - del t - - # Brute force is all that's left. - u = [] - for x in s: - if x not in u: - u.append(x) - return u - - -# From Alex Martelli, -# https://code.activestate.com/recipes/52560 -# ASPN: Python Cookbook: Remove duplicates from a sequence -# First comment, dated 2001/10/13. -# (Also in the printed Python Cookbook.) -# This not currently used, in favor of the next function... - -def uniquer(seq, idfun=None): - def default_idfun(x): - return x - if not idfun: - idfun = default_idfun - seen = {} - result = [] - for item in seq: - marker = idfun(item) - # in old Python versions: - # if seen.has_key(marker) - # but in new ones: - if marker in seen: continue - seen[marker] = 1 - result.append(item) - return result - -# A more efficient implementation of Alex's uniquer(), this avoids the -# idfun() argument and function-call overhead by assuming that all -# items in the sequence are hashable. - -def uniquer_hashables(seq): - seen = {} - result = [] - for item in seq: - #if not item in seen: - if item not in seen: - seen[item] = 1 - result.append(item) - return result - - -# Recipe 19.11 "Reading Lines with Continuation Characters", -# by Alex Martelli, straight from the Python CookBook (2nd edition). -def logical_lines(physical_lines, joiner=''.join): - logical_line = [] - for line in physical_lines: - stripped = line.rstrip() - if stripped.endswith('\\'): - # a line which continues w/the next physical line - logical_line.append(stripped[:-1]) - else: - # a line which does not continue, end of logical line - logical_line.append(line) - yield joiner(logical_line) - logical_line = [] - if logical_line: - # end of sequence implies end of last logical line - yield joiner(logical_line) - - -class LogicalLines: - """ Wrapper class for the logical_lines method. - - Allows us to read all "logical" lines at once from a - given file object. - """ - - def __init__(self, fileobj): - self.fileobj = fileobj - - def readlines(self): - result = [l for l in logical_lines(self.fileobj)] - return result - - -class UniqueList(UserList): - def __init__(self, seq = []): - UserList.__init__(self, seq) - self.unique = True - def __make_unique(self): - if not self.unique: - self.data = uniquer_hashables(self.data) - self.unique = True - def __lt__(self, other): - self.__make_unique() - return UserList.__lt__(self, other) - def __le__(self, other): - self.__make_unique() - return UserList.__le__(self, other) - def __eq__(self, other): - self.__make_unique() - return UserList.__eq__(self, other) - def __ne__(self, other): - self.__make_unique() - return UserList.__ne__(self, other) - def __gt__(self, other): - self.__make_unique() - return UserList.__gt__(self, other) - def __ge__(self, other): - self.__make_unique() - return UserList.__ge__(self, other) - def __cmp__(self, other): - self.__make_unique() - return UserList.__cmp__(self, other) - def __len__(self): - self.__make_unique() - return UserList.__len__(self) - def __getitem__(self, i): - self.__make_unique() - return UserList.__getitem__(self, i) - def __setitem__(self, i, item): - UserList.__setitem__(self, i, item) - self.unique = False - def __getslice__(self, i, j): - self.__make_unique() - return UserList.__getslice__(self, i, j) - def __setslice__(self, i, j, other): - UserList.__setslice__(self, i, j, other) - self.unique = False - def __add__(self, other): - result = UserList.__add__(self, other) - result.unique = False - return result - def __radd__(self, other): - result = UserList.__radd__(self, other) - result.unique = False - return result - def __iadd__(self, other): - result = UserList.__iadd__(self, other) - result.unique = False - return result - def __mul__(self, other): - result = UserList.__mul__(self, other) - result.unique = False - return result - def __rmul__(self, other): - result = UserList.__rmul__(self, other) - result.unique = False - return result - def __imul__(self, other): - result = UserList.__imul__(self, other) - result.unique = False - return result - def append(self, item): - UserList.append(self, item) - self.unique = False - def insert(self, i): - UserList.insert(self, i) - self.unique = False - def count(self, item): - self.__make_unique() - return UserList.count(self, item) - def index(self, item): - self.__make_unique() - return UserList.index(self, item) - def reverse(self): - self.__make_unique() - UserList.reverse(self) - def sort(self, *args, **kwds): - self.__make_unique() - return UserList.sort(self, *args, **kwds) - def extend(self, other): - UserList.extend(self, other) - self.unique = False - - -class Unbuffered: - """ - A proxy class that wraps a file object, flushing after every write, - and delegating everything else to the wrapped object. - """ - def __init__(self, file): - self.file = file - self.softspace = 0 ## backward compatibility; not supported in Py3k - def write(self, arg): - try: - self.file.write(arg) - self.file.flush() - except IOError: - # Stdout might be connected to a pipe that has been closed - # by now. The most likely reason for the pipe being closed - # is that the user has press ctrl-c. It this is the case, - # then SCons is currently shutdown. We therefore ignore - # IOError's here so that SCons can continue and shutdown - # properly so that the .sconsign is correctly written - # before SCons exits. - pass - def __getattr__(self, attr): - return getattr(self.file, attr) - -def make_path_relative(path): - """ makes an absolute path name to a relative pathname. - """ - if os.path.isabs(path): - drive_s,path = os.path.splitdrive(path) - - import re - if not drive_s: - path=re.compile("/*(.*)").findall(path)[0] - else: - path=path[1:] - - assert( not os.path.isabs( path ) ), path - return path - - -# The original idea for AddMethod() came from the -# following post to the ActiveState Python Cookbook: -# -# ASPN: Python Cookbook : Install bound methods in an instance -# https://code.activestate.com/recipes/223613 -# -# Changed as follows: -# * Switched the installmethod() "object" and "function" arguments, -# so the order reflects that the left-hand side is the thing being -# "assigned to" and the right-hand side is the value being assigned. -# * The instance/class detection is changed a bit, as it's all -# new-style classes now with Py3. -# * The by-hand construction of the function object from renamefunction() -# is not needed, the remaining bit is now used inline in AddMethod. - -def AddMethod(obj, function, name=None): - """Adds a method to an object. - - Adds `function` to `obj` if `obj` is a class object. - Adds `function` as a bound method if `obj` is an instance object. - If `obj` looks like an environment instance, use `MethodWrapper` - to add it. If `name` is supplied it is used as the name of `function`. - - Although this works for any class object, the intent as a public - API is to be used on Environment, to be able to add a method to all - construction environments; it is preferred to use env.AddMethod - to add to an individual environment. - - Example:: - - class A: - ... - a = A() - def f(self, x, y): - self.z = x + y - AddMethod(f, A, "add") - a.add(2, 4) - print(a.z) - AddMethod(lambda self, i: self.l[i], a, "listIndex") - print(a.listIndex(5)) - """ - if name is None: - name = function.__name__ - else: - # "rename" - function = FunctionType( - function.__code__, function.__globals__, name, function.__defaults__ - ) - - if hasattr(obj, '__class__') and obj.__class__ is not type: - # obj is an instance, so it gets a bound method. - if hasattr(obj, "added_methods"): - method = MethodWrapper(obj, function, name) - obj.added_methods.append(method) - else: - method = MethodType(function, obj) - else: - # obj is a class - method = function - - setattr(obj, name, method) - - -if hasattr(hashlib, 'md5'): - md5 = True - - def MD5signature(s): - """ - Generate md5 signature of a string - - :param s: either string or bytes. Normally should be bytes - :return: String of hex digits representing the signature - """ - m = hashlib.md5() - - try: - m.update(to_bytes(s)) - except TypeError as e: - m.update(to_bytes(str(s))) - - return m.hexdigest() - - def MD5filesignature(fname, chunksize=65536): - """ - Generate the md5 signature of a file - - :param fname: file to hash - :param chunksize: chunk size to read - :return: String of Hex digits representing the signature - """ - m = hashlib.md5() - with open(fname, "rb") as f: - while True: - blck = f.read(chunksize) - if not blck: - break - m.update(to_bytes(blck)) - return m.hexdigest() -else: - # if md5 algorithm not available, just return data unmodified - # could add alternative signature scheme here - md5 = False - - def MD5signature(s): - return str(s) - - def MD5filesignature(fname, chunksize=65536): - with open(fname, "rb") as f: - result = f.read() - return result - - -def MD5collect(signatures): - """ - Collects a list of signatures into an aggregate signature. - - signatures - a list of signatures - returns - the aggregate signature - """ - if len(signatures) == 1: - return signatures[0] - else: - return MD5signature(', '.join(signatures)) - - -def silent_intern(x): - """ - Perform sys.intern() on the passed argument and return the result. - If the input is ineligible the original argument is - returned and no exception is thrown. - """ - try: - return sys.intern(x) - except TypeError: - return x - - -# From Dinu C. Gherman, -# Python Cookbook, second edition, recipe 6.17, p. 277. -# Also: https://code.activestate.com/recipes/68205 -# ASPN: Python Cookbook: Null Object Design Pattern - -class Null: - """ Null objects always and reliably "do nothing." """ - def __new__(cls, *args, **kwargs): - if '_instance' not in vars(cls): - cls._instance = super(Null, cls).__new__(cls, *args, **kwargs) - return cls._instance - def __init__(self, *args, **kwargs): - pass - def __call__(self, *args, **kwargs): - return self - def __repr__(self): - return "Null(0x%08X)" % id(self) - def __bool__(self): - return False - def __getattr__(self, name): - return self - def __setattr__(self, name, value): - return self - def __delattr__(self, name): - return self - - -class NullSeq(Null): - """ A Null object that can also be iterated over. """ - def __len__(self): - return 0 - def __iter__(self): - return iter(()) - def __getitem__(self, i): - return self - def __delitem__(self, i): - return self - def __setitem__(self, i, v): - return self - - -def to_bytes(s): - if s is None: - return b'None' - if isinstance(s, (bytes, bytearray)): - # if already bytes return. - return s - return bytes(s, 'utf-8') - - -def to_str(s): - if s is None: - return 'None' - if is_String(s): - return s - return str(s, 'utf-8') - - -def cmp(a, b): - """ - Define cmp because it's no longer available in python3 - Works under python 2 as well - """ - return (a > b) - (a < b) - - -def get_env_bool(env, name, default=False): - """Convert a construction variable to bool. - - If the value of *name* in *env* is 'true', 'yes', 'y', 'on' (case - insensitive) or anything convertible to int that yields non-zero then - return True; if 'false', 'no', 'n', 'off' (case insensitive) - or a number that converts to integer zero return False. - Otherwise, return *default*. - - Args: - env: construction environment, or any dict-like object - name: name of the variable - default: value to return if *name* not in *env* or cannot - be converted (default: False) - Returns: - bool: the "truthiness" of *name* - """ - try: - var = env[name] - except KeyError: - return default - try: - return bool(int(var)) - except ValueError: - if str(var).lower() in ('true', 'yes', 'y', 'on'): - return True - elif str(var).lower() in ('false', 'no', 'n', 'off'): - return False - else: - return default - - -def get_os_env_bool(name, default=False): - """Convert an environment variable to bool. - - Conversion is the same as for :func:`get_env_bool`. - """ - return get_env_bool(os.environ, name, default) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Utilities/ConfigureCache.py b/scons/scons-local-4.1.0/SCons/Utilities/ConfigureCache.py deleted file mode 100644 index 67aac3c5b..000000000 --- a/scons/scons-local-4.1.0/SCons/Utilities/ConfigureCache.py +++ /dev/null @@ -1,171 +0,0 @@ -#! /usr/bin/env python -# -# SCons - a Software Constructor -# -# MIT License -# -# Copyright 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. - -"""Show or convert the configuration of an SCons cache directory. - -A cache of derived files is stored by file signature. -The files are split into directories named by the first few -digits of the signature. The prefix length used for directory -names can be changed by this script. -""" - -import argparse -import glob -import json -import os - -def rearrange_cache_entries(current_prefix_len, new_prefix_len): - """Move cache files if prefix length changed. - - Move the existing cache files to new directories of the - appropriate name length and clean up the old directories. - """ - print('Changing prefix length from', current_prefix_len, - 'to', new_prefix_len) - dirs = set() - old_dirs = set() - for file in glob.iglob(os.path.join('*', '*')): - name = os.path.basename(file) - dname = name[:current_prefix_len].upper() - if dname not in old_dirs: - print('Migrating', dname) - old_dirs.add(dname) - dname = name[:new_prefix_len].upper() - if dname not in dirs: - os.mkdir(dname) - dirs.add(dname) - os.rename(file, os.path.join(dname, name)) - - # Now delete the original directories - for dname in old_dirs: - os.rmdir(dname) - - -# The configuration dictionary should have one entry per entry in the -# cache config. The value of each entry should include the following: -# implicit - (optional) This is to allow adding a new config entry and also -# changing the behaviour of the system at the same time. This -# indicates the value the config entry would have had if it had -# been specified. -# default - The value the config entry should have if it wasn't previously -# specified -# command-line - parameters to pass to ArgumentParser.add_argument -# converter - (optional) Function to call if conversion is required -# if this configuration entry changes -config_entries = { - 'prefix_len': { - 'implicit': 1, - 'default': 2, - 'command-line': { - 'help': 'Length of cache file name used as subdirectory prefix', - 'metavar': '', - 'type': int - }, - 'converter': rearrange_cache_entries - } -} - - -def main(): - parser = argparse.ArgumentParser( - description='Modify the configuration of an scons cache directory', - epilog=''' - Unspecified options will not be changed unless they are not - set at all, in which case they are set to an appropriate default. - ''') - - parser.add_argument('cache-dir', help='Path to scons cache directory') - for param in config_entries: - parser.add_argument('--' + param.replace('_', '-'), - **config_entries[param]['command-line']) - parser.add_argument('--version', - action='version', - version='%(prog)s 1.0') - parser.add_argument('--show', - action="store_true", - help="show current configuration") - - # Get the command line as a dict without any of the unspecified entries. - args = dict([x for x in vars(parser.parse_args()).items() if x[1]]) - - # It seems somewhat strange to me, but positional arguments don't get the - - # in the name changed to _, whereas optional arguments do... - cache = args['cache-dir'] - if not os.path.isdir(cache): - raise RuntimeError("There is no cache directory named %s" % cache) - os.chdir(cache) - del args['cache-dir'] - - if not os.path.exists('config'): - # old config dirs did not have a 'config' file. Try to update. - # Validate the only files in the directory are directories 0-9, a-f - expected = ['{:X}'.format(x) for x in range(0, 16)] - if not set(os.listdir('.')).issubset(expected): - raise RuntimeError( - "%s does not look like a valid version 1 cache directory" % cache) - config = dict() - else: - with open('config') as conf: - config = json.load(conf) - - if args.get('show', None): - print("Current configuration in '%s':" % cache) - print(json.dumps(config, sort_keys=True, - indent=4, separators=(',', ': '))) - # in case of the show argument, emit some stats as well - file_count = 0 - for _, _, files in os.walk('.'): - file_count += len(files) - if file_count: # skip config file if it exists - file_count -= 1 - print("Cache contains %s files" % file_count) - del args['show'] - - # Find any keys that are not currently set but should be - for key in config_entries: - if key not in config: - if 'implicit' in config_entries[key]: - config[key] = config_entries[key]['implicit'] - else: - config[key] = config_entries[key]['default'] - if key not in args: - args[key] = config_entries[key]['default'] - - # Now go through each entry in args to see if it changes an existing config - # setting. - for key in args: - if args[key] != config[key]: - if 'converter' in config_entries[key]: - config_entries[key]['converter'](config[key], args[key]) - config[key] = args[key] - - # and write the updated config file - with open('config', 'w') as conf: - json.dump(config, conf) - -if __name__ == "__main__": - main() diff --git a/scons/scons-local-4.1.0/SCons/Utilities/__init__.py b/scons/scons-local-4.1.0/SCons/Utilities/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/scons/scons-local-4.1.0/SCons/Utilities/sconsign.py b/scons/scons-local-4.1.0/SCons/Utilities/sconsign.py deleted file mode 100644 index e595b2daf..000000000 --- a/scons/scons-local-4.1.0/SCons/Utilities/sconsign.py +++ /dev/null @@ -1,494 +0,0 @@ -#! /usr/bin/env python -# -# SCons - a Software Constructor -# -# MIT License -# -# Copyright 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. - -"""Utility script to dump information from SCons signature database.""" - -import getopt -import os -import sys -from dbm import whichdb - -import time -import pickle - -import SCons.compat -import SCons.SConsign - - -def my_whichdb(filename): - if filename[-7:] == ".dblite": - return "SCons.dblite" - try: - with open(filename + ".dblite", "rb"): - return "SCons.dblite" - except IOError: - pass - return whichdb(filename) - - -def my_import(mname): - import imp - - if '.' in mname: - i = mname.rfind('.') - parent = my_import(mname[:i]) - fp, pathname, description = imp.find_module(mname[i+1:], - parent.__path__) - else: - fp, pathname, description = imp.find_module(mname) - return imp.load_module(mname, fp, pathname, description) - - -class Flagger: - default_value = 1 - - def __setitem__(self, item, value): - self.__dict__[item] = value - self.default_value = 0 - - def __getitem__(self, item): - return self.__dict__.get(item, self.default_value) - - -Do_Call = None -Print_Directories = [] -Print_Entries = [] -Print_Flags = Flagger() -Verbose = 0 -Readable = 0 -Warns = 0 - - -def default_mapper(entry, name): - """ - Stringify an entry that doesn't have an explicit mapping. - - Args: - entry: entry - name: field name - - Returns: str - - """ - try: - val = eval("entry." + name) - except AttributeError: - val = None - return str(val) - - -def map_action(entry, _): - """ - Stringify an action entry and signature. - - Args: - entry: action entry - second argument is not used - - Returns: str - - """ - try: - bact = entry.bact - bactsig = entry.bactsig - except AttributeError: - return None - return '%s [%s]' % (bactsig, bact) - - -def map_timestamp(entry, _): - """ - Stringify a timestamp entry. - - Args: - entry: timestamp entry - second argument is not used - - Returns: str - - """ - try: - timestamp = entry.timestamp - except AttributeError: - timestamp = None - if Readable and timestamp: - return "'" + time.ctime(timestamp) + "'" - else: - return str(timestamp) - - -def map_bkids(entry, _): - """ - Stringify an implicit entry. - - Args: - entry: - second argument is not used - - Returns: str - - """ - try: - bkids = entry.bsources + entry.bdepends + entry.bimplicit - bkidsigs = entry.bsourcesigs + entry.bdependsigs + entry.bimplicitsigs - except AttributeError: - return None - - if len(bkids) != len(bkidsigs): - global Warns - Warns += 1 - # add warning to result rather than direct print so it will line up - msg = "Warning: missing information, {} ids but {} sigs" - result = [msg.format(len(bkids), len(bkidsigs))] - else: - result = [] - result += [nodeinfo_string(bkid, bkidsig, " ") - for bkid, bkidsig in zip(bkids, bkidsigs)] - if not result: - return None - return "\n ".join(result) - - -map_field = { - 'action' : map_action, - 'timestamp' : map_timestamp, - 'bkids' : map_bkids, -} - -map_name = { - 'implicit' : 'bkids', -} - - -def field(name, entry, verbose=Verbose): - if not Print_Flags[name]: - return None - fieldname = map_name.get(name, name) - mapper = map_field.get(fieldname, default_mapper) - val = mapper(entry, name) - if verbose: - val = name + ": " + val - return val - - -def nodeinfo_raw(name, ninfo, prefix=""): - """ - This just formats the dictionary, which we would normally use str() - to do, except that we want the keys sorted for deterministic output. - """ - d = ninfo.__getstate__() - try: - keys = ninfo.field_list + ['_version_id'] - except AttributeError: - keys = sorted(d.keys()) - values = [] - for key in keys: - values.append('%s: %s' % (repr(key), repr(d.get(key)))) - if '\n' in name: - name = repr(name) - return name + ': {' + ', '.join(values) + '}' - - -def nodeinfo_cooked(name, ninfo, prefix=""): - try: - field_list = ninfo.field_list - except AttributeError: - field_list = [] - if '\n' in name: - name = repr(name) - outlist = [name + ':'] + [ - f for f in [field(x, ninfo, Verbose) for x in field_list] if f - ] - if Verbose: - sep = '\n ' + prefix - else: - sep = ' ' - return sep.join(outlist) - - -nodeinfo_string = nodeinfo_cooked - - -def printfield(name, entry, prefix=""): - outlist = field("implicit", entry, 0) - if outlist: - if Verbose: - print(" implicit:") - print(" " + outlist) - outact = field("action", entry, 0) - if outact: - if Verbose: - print(" action: " + outact) - else: - print(" " + outact) - - -def printentries(entries, location): - if Print_Entries: - for name in Print_Entries: - try: - entry = entries[name] - except KeyError: - err = "sconsign: no entry `%s' in `%s'\n" % (name, location) - sys.stderr.write(err) - else: - try: - ninfo = entry.ninfo - except AttributeError: - print(name + ":") - else: - print(nodeinfo_string(name, entry.ninfo)) - printfield(name, entry.binfo) - else: - for name in sorted(entries.keys()): - entry = entries[name] - try: - entry.ninfo - except AttributeError: - print(name + ":") - else: - print(nodeinfo_string(name, entry.ninfo)) - printfield(name, entry.binfo) - - -class Do_SConsignDB: - def __init__(self, dbm_name, dbm): - self.dbm_name = dbm_name - self.dbm = dbm - - def __call__(self, fname): - # The *dbm modules stick their own file suffixes on the names - # that are passed in. This causes us to jump through some - # hoops here. - try: - # Try opening the specified file name. Example: - # SPECIFIED OPENED BY self.dbm.open() - # --------- ------------------------- - # .sconsign => .sconsign.dblite - # .sconsign.dblite => .sconsign.dblite.dblite - db = self.dbm.open(fname, "r") - except (IOError, OSError) as e: - print_e = e - try: - # That didn't work, so try opening the base name, - # so that if they actually passed in 'sconsign.dblite' - # (for example), the dbm module will put the suffix back - # on for us and open it anyway. - db = self.dbm.open(os.path.splitext(fname)[0], "r") - except (IOError, OSError): - # That didn't work either. See if the file name - # they specified even exists (independent of the dbm - # suffix-mangling). - try: - with open(fname, "rb"): - pass # this is a touch only, we don't use it here. - except (IOError, OSError) as e: - # Nope, that file doesn't even exist, so report that - # fact back. - print_e = e - sys.stderr.write("sconsign: %s\n" % print_e) - return - except KeyboardInterrupt: - raise - except pickle.UnpicklingError: - sys.stderr.write("sconsign: ignoring invalid `%s' file `%s'\n" - % (self.dbm_name, fname)) - return - except Exception as e: - sys.stderr.write("sconsign: ignoring invalid `%s' file `%s': %s\n" - % (self.dbm_name, fname, e)) - exc_type, _, _ = sys.exc_info() - if exc_type.__name__ == "ValueError": - sys.stderr.write("unrecognized pickle protocol.\n") - return - - if Print_Directories: - for dir in Print_Directories: - try: - val = db[dir] - except KeyError: - err = "sconsign: no dir `%s' in `%s'\n" % (dir, args[0]) - sys.stderr.write(err) - else: - self.printentries(dir, val) - else: - for dir in sorted(db.keys()): - self.printentries(dir, db[dir]) - - @staticmethod - def printentries(dir, val): - try: - print('=== ' + dir + ':') - except TypeError: - print('=== ' + dir.decode() + ':') - printentries(pickle.loads(val), dir) - - -def Do_SConsignDir(name): - try: - with open(name, 'rb') as fp: - try: - sconsign = SCons.SConsign.Dir(fp) - except KeyboardInterrupt: - raise - except pickle.UnpicklingError: - err = "sconsign: ignoring invalid .sconsign file `%s'\n" % name - sys.stderr.write(err) - return - except Exception as e: - err = "sconsign: ignoring invalid .sconsign file `%s': %s\n" % (name, e) - sys.stderr.write(err) - return - printentries(sconsign.entries, args[0]) - except (IOError, OSError) as e: - sys.stderr.write("sconsign: %s\n" % e) - return - - -############################################################################## -def main(): - global Do_Call - global nodeinfo_string - global args - global Verbose - global Readable - - helpstr = """\ - Usage: sconsign [OPTIONS] [FILE ...] - Options: - -a, --act, --action Print build action information. - -c, --csig Print content signature information. - -d DIR, --dir=DIR Print only info about DIR. - -e ENTRY, --entry=ENTRY Print only info about ENTRY. - -f FORMAT, --format=FORMAT FILE is in the specified FORMAT. - -h, --help Print this message and exit. - -i, --implicit Print implicit dependency information. - -r, --readable Print timestamps in human-readable form. - --raw Print raw Python object representations. - -s, --size Print file sizes. - -t, --timestamp Print timestamp information. - -v, --verbose Verbose, describe each field. - """ - - try: - opts, args = getopt.getopt(sys.argv[1:], "acd:e:f:hirstv", - ['act', 'action', - 'csig', 'dir=', 'entry=', - 'format=', 'help', 'implicit', - 'raw', 'readable', - 'size', 'timestamp', 'verbose']) - except getopt.GetoptError as err: - sys.stderr.write(str(err) + '\n') - print(helpstr) - sys.exit(2) - - for o, a in opts: - if o in ('-a', '--act', '--action'): - Print_Flags['action'] = 1 - elif o in ('-c', '--csig'): - Print_Flags['csig'] = 1 - elif o in ('-d', '--dir'): - Print_Directories.append(a) - elif o in ('-e', '--entry'): - Print_Entries.append(a) - elif o in ('-f', '--format'): - # Try to map the given DB format to a known module - # name, that we can then try to import... - Module_Map = {'dblite': 'SCons.dblite', 'sconsign': None} - dbm_name = Module_Map.get(a, a) - if dbm_name: - try: - if dbm_name != "SCons.dblite": - dbm = my_import(dbm_name) - else: - import SCons.dblite - - dbm = SCons.dblite - # Ensure that we don't ignore corrupt DB files, - # this was handled by calling my_import('SCons.dblite') - # again in earlier versions... - SCons.dblite.IGNORE_CORRUPT_DBFILES = False - except ImportError: - sys.stderr.write("sconsign: illegal file format `%s'\n" % a) - print(helpstr) - sys.exit(2) - Do_Call = Do_SConsignDB(a, dbm) - else: - Do_Call = Do_SConsignDir - elif o in ('-h', '--help'): - print(helpstr) - sys.exit(0) - elif o in ('-i', '--implicit'): - Print_Flags['implicit'] = 1 - elif o in ('--raw',): - nodeinfo_string = nodeinfo_raw - elif o in ('-r', '--readable'): - Readable = 1 - elif o in ('-s', '--size'): - Print_Flags['size'] = 1 - elif o in ('-t', '--timestamp'): - Print_Flags['timestamp'] = 1 - elif o in ('-v', '--verbose'): - Verbose = 1 - - if Do_Call: - for a in args: - Do_Call(a) - else: - if not args: - args = [".sconsign.dblite"] - for a in args: - dbm_name = my_whichdb(a) - if dbm_name: - Map_Module = {'SCons.dblite': 'dblite'} - if dbm_name != "SCons.dblite": - dbm = my_import(dbm_name) - else: - import SCons.dblite - - dbm = SCons.dblite - # Ensure that we don't ignore corrupt DB files, - # this was handled by calling my_import('SCons.dblite') - # again in earlier versions... - SCons.dblite.IGNORE_CORRUPT_DBFILES = False - Do_SConsignDB(Map_Module.get(dbm_name, dbm_name), dbm)(a) - else: - Do_SConsignDir(a) - - if Warns: - print("NOTE: there were %d warnings, please check output" % Warns) - - -if __name__ == "__main__": - main() - sys.exit(0) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Variables/BoolVariable.py b/scons/scons-local-4.1.0/SCons/Variables/BoolVariable.py deleted file mode 100644 index 6d9ff72f2..000000000 --- a/scons/scons-local-4.1.0/SCons/Variables/BoolVariable.py +++ /dev/null @@ -1,85 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Option type for true/false Variables. - -Usage example:: - - opts = Variables() - opts.Add(BoolVariable('embedded', 'build for an embedded system', 0)) - ... - if env['embedded'] == 1: - ... -""" - -__all__ = ['BoolVariable',] - -import SCons.Errors - -__true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' ) -__false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none') - - -def _text2bool(val): - """ - Converts strings to True/False depending on the 'truth' expressed by - the string. If the string can't be converted, the original value - will be returned. - - See '__true_strings' and '__false_strings' for values considered - 'true' or 'false respectively. - - This is usable as 'converter' for SCons' Variables. - """ - lval = val.lower() - if lval in __true_strings: return True - if lval in __false_strings: return False - raise ValueError("Invalid value for boolean option: %s" % val) - - -def _validator(key, val, env): - """ - Validates the given value to be either '0' or '1'. - - This is usable as 'validator' for SCons' Variables. - """ - if not env[key] in (True, False): - raise SCons.Errors.UserError( - 'Invalid value for boolean option %s: %s' % (key, env[key])) - - -def BoolVariable(key, help, default): - """ - The input parameters describe a boolean option, thus they are - returned with the correct converter and validator appended. The - 'help' text will by appended by '(yes|no) to show the valid - valued. The result is usable for input to opts.Add(). - """ - return (key, '%s (yes|no)' % help, default, - _validator, _text2bool) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Variables/EnumVariable.py b/scons/scons-local-4.1.0/SCons/Variables/EnumVariable.py deleted file mode 100644 index 6e0a8c585..000000000 --- a/scons/scons-local-4.1.0/SCons/Variables/EnumVariable.py +++ /dev/null @@ -1,107 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Option type for enumeration Variables. - -This file defines the option type for SCons allowing only specified -input-values. - -Usage example:: - - opts = Variables() - opts.Add( - EnumVariable( - 'debug', - 'debug output and symbols', - 'no', - allowed_values=('yes', 'no', 'full'), - map={}, - ignorecase=2, - ) - ) - ... - if env['debug'] == 'full': - ... -""" - - -__all__ = ['EnumVariable',] - - -import SCons.Errors - -def _validator(key, val, env, vals): - if val not in vals: - raise SCons.Errors.UserError( - 'Invalid value for option %s: %s. Valid values are: %s' % (key, val, vals)) - - -def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0): - """ - The input parameters describe an option with only certain values - allowed. They are returned with an appropriate converter and - validator appended. The result is usable for input to - Variables.Add(). - - 'key' and 'default' are the values to be passed on to Variables.Add(). - - 'help' will be appended by the allowed values automatically - - 'allowed_values' is a list of strings, which are allowed as values - for this option. - - The 'map'-dictionary may be used for converting the input value - into canonical values (e.g. for aliases). - - 'ignorecase' defines the behaviour of the validator: - - If ignorecase == 0, the validator/converter are case-sensitive. - If ignorecase == 1, the validator/converter are case-insensitive. - If ignorecase == 2, the validator/converter is case-insensitive and the converted value will always be lower-case. - - The 'validator' tests whether the value is in the list of allowed values. The 'converter' converts input values - according to the given 'map'-dictionary (unmapped input values are returned unchanged). - """ - - help = '%s (%s)' % (help, '|'.join(allowed_values)) - # define validator - if ignorecase >= 1: - validator = lambda key, val, env: \ - _validator(key, val.lower(), env, allowed_values) - else: - validator = lambda key, val, env: \ - _validator(key, val, env, allowed_values) - # define converter - if ignorecase == 2: - converter = lambda val: map.get(val.lower(), val).lower() - elif ignorecase == 1: - converter = lambda val: map.get(val.lower(), val) - else: - converter = lambda val: map.get(val, val) - return (key, help, default, validator, converter) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Variables/ListVariable.py b/scons/scons-local-4.1.0/SCons/Variables/ListVariable.py deleted file mode 100644 index c6152585d..000000000 --- a/scons/scons-local-4.1.0/SCons/Variables/ListVariable.py +++ /dev/null @@ -1,138 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Option type for list Variables. - -This file defines the option type for SCons implementing 'lists'. - -A 'list' option may either be 'all', 'none' or a list of names -separated by comma. After the option has been processed, the option -value holds either the named list elements, all list elements or no -list elements at all. - -Usage example:: - - list_of_libs = Split('x11 gl qt ical') - - opts = Variables() - opts.Add( - ListVariable( - 'shared', - 'libraries to build as shared libraries', - 'all', - elems=list_of_libs, - ) - ) - ... - for lib in list_of_libs: - if lib in env['shared']: - env.SharedObject(...) - else: - env.Object(...) -""" - -# Known Bug: This should behave like a Set-Type, but does not really, -# since elements can occur twice. - -__all__ = ['ListVariable',] - -import collections - -import SCons.Util - - -class _ListVariable(collections.UserList): - def __init__(self, initlist=[], allowedElems=[]): - collections.UserList.__init__(self, [_f for _f in initlist if _f]) - self.allowedElems = sorted(allowedElems) - - def __cmp__(self, other): - raise NotImplementedError - def __eq__(self, other): - raise NotImplementedError - def __ge__(self, other): - raise NotImplementedError - def __gt__(self, other): - raise NotImplementedError - def __le__(self, other): - raise NotImplementedError - def __lt__(self, other): - raise NotImplementedError - def __str__(self): - if len(self) == 0: - return 'none' - self.data.sort() - if self.data == self.allowedElems: - return 'all' - else: - return ','.join(self) - def prepare_to_store(self): - return self.__str__() - -def _converter(val, allowedElems, mapdict): - """ - """ - if val == 'none': - val = [] - elif val == 'all': - val = allowedElems - else: - val = [_f for _f in val.split(',') if _f] - val = [mapdict.get(v, v) for v in val] - notAllowed = [v for v in val if v not in allowedElems] - if notAllowed: - raise ValueError("Invalid value(s) for option: %s" % - ','.join(notAllowed)) - return _ListVariable(val, allowedElems) - - -## def _validator(key, val, env): -## """ -## """ -## # todo: write validator for pgk list -## return 1 - - -def ListVariable(key, help, default, names, map={}): - """ - The input parameters describe a 'package list' option, thus they - are returned with the correct converter and validator appended. The - result is usable for input to opts.Add() . - - A 'package list' option may either be 'all', 'none' or a list of - package names (separated by space). - """ - names_str = 'allowed names: %s' % ' '.join(names) - if SCons.Util.is_List(default): - default = ','.join(default) - help = '\n '.join( - (help, '(all|none|comma-separated list of names)', names_str)) - return (key, help, default, - None, #_validator, - lambda val: _converter(val, names, map)) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Variables/PackageVariable.py b/scons/scons-local-4.1.0/SCons/Variables/PackageVariable.py deleted file mode 100644 index d4dafd541..000000000 --- a/scons/scons-local-4.1.0/SCons/Variables/PackageVariable.py +++ /dev/null @@ -1,104 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Option type for package Variables. - -This file defines the option type for SCons implementing 'package activation'. - -To be used whenever a 'package' may be enabled/disabled and the -package path may be specified. - -Usage example: - - Examples: - x11=no (disables X11 support) - x11=yes (will search for the package installation dir) - x11=/usr/local/X11 (will check this path for existence) - - To replace autoconf's --with-xxx=yyy :: - - - opts = Variables() - opts.Add(PackageVariable('x11', - 'use X11 installed here (yes = search some places', - 'yes')) - ... - if env['x11'] == True: - dir = ... search X11 in some standard places ... - env['x11'] = dir - if env['x11']: - ... build with x11 ... -""" - -__all__ = ['PackageVariable',] - -import SCons.Errors - -__enable_strings = ('1', 'yes', 'true', 'on', 'enable', 'search') -__disable_strings = ('0', 'no', 'false', 'off', 'disable') - -def _converter(val): - """ - """ - lval = val.lower() - if lval in __enable_strings: return True - if lval in __disable_strings: return False - #raise ValueError("Invalid value for boolean option: %s" % val) - return val - - -def _validator(key, val, env, searchfunc): - # NB: searchfunc is currently undocumented and unsupported - """ - """ - # TODO write validator, check for path - import os - if env[key] is True: - if searchfunc: - env[key] = searchfunc(key, val) - elif env[key] and not os.path.exists(val): - raise SCons.Errors.UserError( - 'Path does not exist for option %s: %s' % (key, val)) - - -def PackageVariable(key, help, default, searchfunc=None): - # NB: searchfunc is currently undocumented and unsupported - """ - The input parameters describe a 'package list' option, thus they - are returned with the correct converter and validator appended. The - result is usable for input to opts.Add() . - - A 'package list' option may either be 'all', 'none' or a list of - package names (separated by space). - """ - help = '\n '.join( - (help, '( yes | no | /path/to/%s )' % key)) - return (key, help, default, - lambda k, v, e: _validator(k,v,e,searchfunc), - _converter) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Variables/PathVariable.py b/scons/scons-local-4.1.0/SCons/Variables/PathVariable.py deleted file mode 100644 index 081872b7f..000000000 --- a/scons/scons-local-4.1.0/SCons/Variables/PathVariable.py +++ /dev/null @@ -1,144 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Option type for path Variables. - -This file defines an option type for SCons implementing path settings. - -To be used whenever a user-specified path override should be allowed. - -Arguments to PathVariable are: - option-name = name of this option on the command line (e.g. "prefix") - option-help = help string for option - option-dflt = default value for this option - validator = [optional] validator for option value. Predefined are: - PathAccept -- accepts any path setting; no validation - PathIsDir -- path must be an existing directory - PathIsDirCreate -- path must be a dir; will create - PathIsFile -- path must be a file - PathExists -- path must exist (any type) [default] - - The validator is a function that is called and which should return - True or False to indicate if the path is valid. The arguments - to the validator function are: (key, val, env). The key is the - name of the option, the val is the path specified for the option, - and the env is the env to which the Options have been added. - -Usage example:: - - Examples: - prefix=/usr/local - - opts = Variables() - - opts = Variables() - opts.Add(PathVariable('qtdir', - 'where the root of Qt is installed', - qtdir, PathIsDir)) - opts.Add(PathVariable('qt_includes', - 'where the Qt includes are installed', - '$qtdir/includes', PathIsDirCreate)) - opts.Add(PathVariable('qt_libraries', - 'where the Qt library is installed', - '$qtdir/lib')) -""" - -__all__ = ['PathVariable',] - -import os -import os.path - -import SCons.Errors - -class _PathVariableClass: - - @staticmethod - def PathAccept(key, val, env): - """Accepts any path, no checking done.""" - pass - - @staticmethod - def PathIsDir(key, val, env): - """Validator to check if Path is a directory.""" - if not os.path.isdir(val): - if os.path.isfile(val): - m = 'Directory path for option %s is a file: %s' - else: - m = 'Directory path for option %s does not exist: %s' - raise SCons.Errors.UserError(m % (key, val)) - - @staticmethod - def PathIsDirCreate(key, val, env): - """Validator to check if Path is a directory, - creating it if it does not exist.""" - if os.path.isfile(val): - m = 'Path for option %s is a file, not a directory: %s' - raise SCons.Errors.UserError(m % (key, val)) - if not os.path.isdir(val): - os.makedirs(val) - - @staticmethod - def PathIsFile(key, val, env): - """Validator to check if Path is a file""" - if not os.path.isfile(val): - if os.path.isdir(val): - m = 'File path for option %s is a directory: %s' - else: - m = 'File path for option %s does not exist: %s' - raise SCons.Errors.UserError(m % (key, val)) - - @staticmethod - def PathExists(key, val, env): - """Validator to check if Path exists""" - if not os.path.exists(val): - m = 'Path for option %s does not exist: %s' - raise SCons.Errors.UserError(m % (key, val)) - - def __call__(self, key, help, default, validator=None): - """ - The input parameters describe a 'path list' option, thus they - are returned with the correct converter and validator appended. The - result is usable for input to opts.Add() . - - The 'default' option specifies the default path to use if the - user does not specify an override with this option. - - validator is a validator, see this file for examples - """ - if validator is None: - validator = self.PathExists - - if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key): - return (key, '%s ( /path/to/%s )' % (help, key[0]), default, - validator, None) - else: - return (key, '%s ( /path/to/%s )' % (help, key), default, - validator, None) - -PathVariable = _PathVariableClass() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Variables/__init__.py b/scons/scons-local-4.1.0/SCons/Variables/__init__.py deleted file mode 100644 index 2c3231086..000000000 --- a/scons/scons-local-4.1.0/SCons/Variables/__init__.py +++ /dev/null @@ -1,325 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Add user-friendly customizable variables to an SCons build. """ - -import os.path -import sys -from functools import cmp_to_key - -import SCons.Environment -import SCons.Errors -import SCons.Util -import SCons.Warnings - -from .BoolVariable import BoolVariable # okay -from .EnumVariable import EnumVariable # okay -from .ListVariable import ListVariable # naja -from .PackageVariable import PackageVariable # naja -from .PathVariable import PathVariable # okay - - -class Variables: - """ - Holds all the options, updates the environment with the variables, - and renders the help text. - - If is_global is True, this is a singleton, create only once. - - Args: - files (optional): List of option configuration files to load - (backward compatibility). If a single string is passed it is - automatically placed in a file list (Default value = None) - args (optional): dictionary to override values set from *files*. - (Default value = None) - is_global (optional): global instance? (Default value = True) - - """ - instance = None - - def __init__(self, files=None, args=None, is_global=True): - if args is None: - args = {} - self.options = [] - self.args = args - if not SCons.Util.is_List(files): - if files: - files = [ files ] - else: - files = [] - self.files = files - self.unknown = {} - - # create the singleton instance - if is_global: - self = Variables.instance - - if not Variables.instance: - Variables.instance=self - - def _do_add(self, key, help="", default=None, validator=None, converter=None): - class Variable: - pass - - option = Variable() - - # if we get a list or a tuple, we take the first element as the - # option key and store the remaining in aliases. - if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key): - option.key = key[0] - option.aliases = key[1:] - else: - option.key = key - option.aliases = [ key ] - option.help = help - option.default = default - option.validator = validator - option.converter = converter - - self.options.append(option) - - # options might be added after the 'unknown' dict has been set up, - # so we remove the key and all its aliases from that dict - for alias in list(option.aliases) + [ option.key ]: - if alias in self.unknown: - del self.unknown[alias] - - def keys(self): - """ - Returns the keywords for the options - """ - return [o.key for o in self.options] - - def Add(self, key, help="", default=None, validator=None, converter=None, **kw): - """Add an option. - - Args: - key: the name of the variable, or a list or tuple of arguments - help: optional help text for the options (Default value = "") - default: optional default value for option (Default value = None) - validator: optional function called to validate the option's value - (Default value = None) - converter: optional function to be called to convert the option's - value before putting it in the environment. (Default value = None) - \*\*kw: keyword args, unused. - - """ - if SCons.Util.is_List(key) or isinstance(key, tuple): - self._do_add(*key) - return - - if not SCons.Util.is_String(key) or \ - not SCons.Environment.is_valid_construction_var(key): - raise SCons.Errors.UserError("Illegal Variables.Add() key `%s'" % str(key)) - - self._do_add(key, help, default, validator, converter) - - def AddVariables(self, *optlist): - """ - Add a list of options. - - Each list element is a tuple/list of arguments to be passed on - to the underlying method for adding options. - - Example:: - - opt.AddVariables( - ('debug', '', 0), - ('CC', 'The C compiler'), - ('VALIDATE', 'An option for testing validation', 'notset', validator, None), - ) - - """ - - for o in optlist: - self._do_add(*o) - - - def Update(self, env, args=None): - """ - Update an environment with the option variables. - - env - the environment to update. - """ - - values = {} - - # first set the defaults: - for option in self.options: - if option.default is not None: - values[option.key] = option.default - - # next set the value specified in the options file - for filename in self.files: - if os.path.exists(filename): - dir = os.path.split(os.path.abspath(filename))[0] - if dir: - sys.path.insert(0, dir) - try: - values['__name__'] = filename - with open(filename, 'r') as f: - contents = f.read() - exec(contents, {}, values) - finally: - if dir: - del sys.path[0] - del values['__name__'] - - # set the values specified on the command line - if args is None: - args = self.args - - for arg, value in args.items(): - added = False - for option in self.options: - if arg in list(option.aliases) + [ option.key ]: - values[option.key] = value - added = True - if not added: - self.unknown[arg] = value - - # put the variables in the environment: - # (don't copy over variables that are not declared as options) - for option in self.options: - try: - env[option.key] = values[option.key] - except KeyError: - pass - - # Call the convert functions: - for option in self.options: - if option.converter and option.key in values: - value = env.subst('${%s}'%option.key) - try: - try: - env[option.key] = option.converter(value) - except TypeError: - env[option.key] = option.converter(value, env) - except ValueError as x: - raise SCons.Errors.UserError('Error converting option: %s\n%s'%(option.key, x)) - - - # Finally validate the values: - for option in self.options: - if option.validator and option.key in values: - option.validator(option.key, env.subst('${%s}'%option.key), env) - - def UnknownVariables(self): - """ - Returns any options in the specified arguments lists that - were not known, declared options in this object. - """ - return self.unknown - - def Save(self, filename, env): - """ - Saves all the options in the given file. This file can - then be used to load the options next run. This can be used - to create an option cache file. - - filename - Name of the file to save into - env - the environment get the option values from - """ - - # Create the file and write out the header - try: - fh = open(filename, 'w') - - try: - # Make an assignment in the file for each option - # within the environment that was assigned a value - # other than the default. - for option in self.options: - try: - value = env[option.key] - try: - prepare = value.prepare_to_store - except AttributeError: - try: - eval(repr(value)) - except KeyboardInterrupt: - raise - except: - # Convert stuff that has a repr() that - # cannot be evaluated into a string - value = SCons.Util.to_String(value) - else: - value = prepare() - - defaultVal = env.subst(SCons.Util.to_String(option.default)) - if option.converter: - defaultVal = option.converter(defaultVal) - - if str(env.subst('${%s}' % option.key)) != str(defaultVal): - fh.write('%s = %s\n' % (option.key, repr(value))) - except KeyError: - pass - finally: - fh.close() - - except IOError as x: - raise SCons.Errors.UserError('Error writing options to file: %s\n%s' % (filename, x)) - - def GenerateHelpText(self, env, sort=None): - """ - Generate the help text for the options. - - env - an environment that is used to get the current values - of the options. - cmp - Either a function as follows: The specific sort function should take two arguments and return -1, 0 or 1 - or a boolean to indicate if it should be sorted. - """ - - if callable(sort): - options = sorted(self.options, key=cmp_to_key(lambda x,y: sort(x.key,y.key))) - elif sort is True: - options = sorted(self.options, key=lambda x: x.key) - else: - options = self.options - - def format(opt, self=self, env=env): - if opt.key in env: - actual = env.subst('${%s}' % opt.key) - else: - actual = None - return self.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases) - lines = [_f for _f in map(format, options) if _f] - - return ''.join(lines) - - format = '\n%s: %s\n default: %s\n actual: %s\n' - format_ = '\n%s: %s\n default: %s\n actual: %s\n aliases: %s\n' - - def FormatVariableHelpText(self, env, key, help, default, actual, aliases=[]): - # Don't display the key name itself as an alias. - aliases = [a for a in aliases if a != key] - if len(aliases)==0: - return self.format % (key, help, default, actual) - else: - return self.format_ % (key, help, default, actual, aliases) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/Warnings.py b/scons/scons-local-4.1.0/SCons/Warnings.py deleted file mode 100644 index 198c6aeda..000000000 --- a/scons/scons-local-4.1.0/SCons/Warnings.py +++ /dev/null @@ -1,236 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""The SCons warnings framework.""" - -import sys - -import SCons.Errors - -class SConsWarning(SCons.Errors.UserError): - pass - -class WarningOnByDefault(SConsWarning): - pass - - -# NOTE: If you add a new warning class, add it to the man page, too! -# Not all warnings are defined here, some are defined in the location of use - -class TargetNotBuiltWarning(SConsWarning): # Should go to OnByDefault - pass - -class CacheVersionWarning(WarningOnByDefault): - pass - -class CacheWriteErrorWarning(SConsWarning): - pass - -class CorruptSConsignWarning(WarningOnByDefault): - pass - -class DependencyWarning(SConsWarning): - pass - -class DevelopmentVersionWarning(WarningOnByDefault): - pass - -class DuplicateEnvironmentWarning(WarningOnByDefault): - pass - -class FutureReservedVariableWarning(WarningOnByDefault): - pass - -class LinkWarning(WarningOnByDefault): - pass - -class MisleadingKeywordsWarning(WarningOnByDefault): - pass - -class MissingSConscriptWarning(WarningOnByDefault): - pass - -class NoObjectCountWarning(WarningOnByDefault): - pass - -class NoParallelSupportWarning(WarningOnByDefault): - pass - -class ReservedVariableWarning(WarningOnByDefault): - pass - -class StackSizeWarning(WarningOnByDefault): - pass - -class VisualCMissingWarning(WarningOnByDefault): - pass - -# Used when MSVC_VERSION and MSVS_VERSION do not point to the -# same version (MSVS_VERSION is deprecated) -class VisualVersionMismatch(WarningOnByDefault): - pass - -class VisualStudioMissingWarning(SConsWarning): - pass - -class FortranCxxMixWarning(LinkWarning): - pass - - -# Deprecation warnings - -class FutureDeprecatedWarning(SConsWarning): - pass - -class DeprecatedWarning(SConsWarning): - pass - -class MandatoryDeprecatedWarning(DeprecatedWarning): - pass - - -# Special case; base always stays DeprecatedWarning -class PythonVersionWarning(DeprecatedWarning): - pass - -class DeprecatedSourceCodeWarning(FutureDeprecatedWarning): - pass - -class TaskmasterNeedsExecuteWarning(DeprecatedWarning): - pass - -class DeprecatedOptionsWarning(MandatoryDeprecatedWarning): - pass - -class DeprecatedDebugOptionsWarning(MandatoryDeprecatedWarning): - pass - -class DeprecatedMissingSConscriptWarning(DeprecatedWarning): - pass - - -# The below is a list of 2-tuples. The first element is a class object. -# The second element is true if that class is enabled, false if it is disabled. -_enabled = [] - -# If set, raise the warning as an exception -_warningAsException = False - -# If not None, a function to call with the warning -_warningOut = None - -def suppressWarningClass(clazz): - """Suppresses all warnings of type clazz or derived from clazz.""" - _enabled.insert(0, (clazz, False)) - -def enableWarningClass(clazz): - """Enables all warnings of type clazz or derived from clazz.""" - _enabled.insert(0, (clazz, True)) - -def warningAsException(flag=True): - """Set global _warningAsExeption flag. - - Args: - flag: value to set warnings-as-exceptions to [default: True] - - Returns: - The previous value. - """ - global _warningAsException - old = _warningAsException - _warningAsException = flag - return old - -def warn(clazz, *args): - """Issue a warning, accounting for SCons rules. - - Check if warnings for this class are enabled. - If warnings are treated as exceptions, raise exception. - Use the global warning-emitter _warningOut, which allows selecting - different ways of presenting a traceback (see Script/Main.py) - """ - warning = clazz(args) - for cls, flag in _enabled: - if isinstance(warning, cls): - if flag: - if _warningAsException: - raise warning - - if _warningOut: - _warningOut(warning) - break - -def process_warn_strings(arguments): - """Process requests to enable/disable warnings. - - The requests are strings passed to the --warn option or the - SetOption('warn') function. - - An argument to this option should be of the form "warning-class" - or "no-warning-class". The warning class is munged and has - the suffix "Warning" added in order to get an actual class name - from the classes above, which we need to pass to the - {enable,disable}WarningClass() functions. - - For example, "deprecated" will enable the DeprecatedWarning class. - "no-dependency" will disable the DependencyWarning class. - - As a special case, --warn=all and --warn=no-all will enable or - disable (respectively) the base class of all SCons warnings. - """ - - def _classmunge(s): - """Convert a warning argument to SConsCase. - - The result is CamelCase, except "Scons" is changed to "SCons" - """ - s = s.replace("-", " ").title().replace(" ", "") - return s.replace("Scons", "SCons") - - for arg in arguments: - enable = True - if arg.startswith("no-"): - enable = False - arg = arg[len("no-") :] - if arg == 'all': - class_name = "SConsWarning" - else: - class_name = _classmunge(arg) + 'Warning' - try: - clazz = globals()[class_name] - except KeyError: - sys.stderr.write("No warning type: '%s'\n" % arg) - else: - if enable: - enableWarningClass(clazz) - elif issubclass(clazz, MandatoryDeprecatedWarning): - fmt = "Can not disable mandataory warning: '%s'\n" - sys.stderr.write(fmt % arg) - else: - suppressWarningClass(clazz) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/__init__.py b/scons/scons-local-4.1.0/SCons/__init__.py deleted file mode 100644 index 6e1dd87f8..000000000 --- a/scons/scons-local-4.1.0/SCons/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -__version__="4.1.0" -__copyright__="Copyright (c) 2001 - 2021 The SCons Foundation" -__developer__="bdbaddog" -__date__="2021-01-19 20:03:01" -__buildsys__="ProDog2020" -__revision__="215860fd4f6bea67896c145660a035fad20cc41c" -__build__="215860fd4f6bea67896c145660a035fad20cc41c" -# make sure compatibility is always in place -import SCons.compat # noqa \ No newline at end of file diff --git a/scons/scons-local-4.1.0/SCons/__main__.py b/scons/scons-local-4.1.0/SCons/__main__.py deleted file mode 100644 index 67120c896..000000000 --- a/scons/scons-local-4.1.0/SCons/__main__.py +++ /dev/null @@ -1,27 +0,0 @@ -# MIT License -# -# Copyright 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. - -import SCons.Script -# this does all the work, and calls sys.exit -# with the proper exit status when done. -SCons.Script.main() diff --git a/scons/scons-local-4.1.0/SCons/compat/__init__.py b/scons/scons-local-4.1.0/SCons/compat/__init__.py deleted file mode 100644 index 03b12af99..000000000 --- a/scons/scons-local-4.1.0/SCons/compat/__init__.py +++ /dev/null @@ -1,104 +0,0 @@ -# MIT License -# -# Copyright 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 compatibility package for old Python versions - -This subpackage holds modules that provide backwards-compatible -implementations of various things from newer Python versions -that we cannot count on because SCons still supported older Pythons. - -Other code will not generally reference things in this package through -the SCons.compat namespace. The modules included here add things to -the builtins namespace or the global module list so that the rest -of our code can use the objects and names imported here regardless of -Python version. As a result, if this module is used, it should violate -the normal convention for imports (standard library imports first, -then program-specific imports, each ordered aplhabetically) -and needs to be listed first. - -The rest of the things here will be in individual compatibility modules -that are either: 1) suitably modified copies of the future modules that -we want to use; or 2) backwards compatible re-implementations of the -specific portions of a future module's API that we want to use. - -GENERAL WARNINGS: Implementations of functions in the SCons.compat -modules are *NOT* guaranteed to be fully compliant with these functions in -later versions of Python. We are only concerned with adding functionality -that we actually use in SCons, so be wary if you lift this code for -other uses. (That said, making these more nearly the same as later, -official versions is still a desirable goal, we just don't need to be -obsessive about it.) - -We name the compatibility modules with an initial '_scons_' (for example, -_scons_subprocess.py is our compatibility module for subprocess) so -that we can still try to import the real module name and fall back to -our compatibility module if we get an ImportError. The import_as() -function defined below loads the module as the "real" name (without the -'_scons'), after which all of the "import {module}" statements in the -rest of our code will find our pre-loaded compatibility module. -""" - -import sys -import importlib - -PYPY = hasattr(sys, 'pypy_translation_info') - - -def rename_module(new, old): - """ - Attempt to import the old module and load it under the new name. - Used for purely cosmetic name changes in Python 3.x. - """ - try: - sys.modules[new] = importlib.import_module(old) - return True - except ImportError: - return False - - -# Default pickle protocol. Higher protocols are more efficient/featured -# but incompatible with older Python versions. -# Negative numbers choose the highest available protocol. - -# Was pickle.HIGHEST_PROTOCOL -# Changed to 4 so that python 3.8's not incompatible with previous versions -# Python 3.8 introduced protocol 5 which is mainly an improvement for for out-of-band data buffers -PICKLE_PROTOCOL = 4 - - -class NoSlotsPyPy(type): - """ Metaclass for PyPy compatitbility. - - PyPy does not work well with __slots__ and __class__ assignment. - """ - - def __new__(meta, name, bases, dct): - if PYPY and '__slots__' in dct: - dct.pop('__slots__') - return super(NoSlotsPyPy, meta).__new__(meta, name, bases, dct) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/compat/_scons_dbm.py b/scons/scons-local-4.1.0/SCons/compat/_scons_dbm.py deleted file mode 100644 index 72e5d6afe..000000000 --- a/scons/scons-local-4.1.0/SCons/compat/_scons_dbm.py +++ /dev/null @@ -1,42 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""dbm compatibility module for Python versions that don't have dbm. - -This does not not NOT (repeat, *NOT*) provide complete dbm functionality. -It's just a stub on which to hang just enough pieces of dbm functionality -that the whichdb.whichdb() implementstation in the various 2.X versions of -Python won't blow up even if dbm wasn't compiled in. -""" - -class error(Exception): - pass - -def open(*args, **kw): - raise error() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/compat/win32.py b/scons/scons-local-4.1.0/SCons/compat/win32.py deleted file mode 100644 index e01adfa7e..000000000 --- a/scons/scons-local-4.1.0/SCons/compat/win32.py +++ /dev/null @@ -1,101 +0,0 @@ -# MIT License -# -# Copyright 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. -"""Logic to replicate parts of pywin32 SCons uses.""" - -__all__ = ['get_current_process', 'get_memory_info', 'get_memory_usage', 'get_peak_memory_usage'] - -import ctypes -from ctypes import wintypes - -# -# From Activestate Recipe -# https://code.activestate.com/recipes/578513-get-memory-usage-of-windows-processes-using-getpro/ -# MIT licensed -# -GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess -GetCurrentProcess.argtypes = [] -GetCurrentProcess.restype = wintypes.HANDLE - -SIZE_T = ctypes.c_size_t - - -class PROCESS_MEMORY_COUNTERS_EX(ctypes.Structure): - _fields_ = [ - ('cb', wintypes.DWORD), - ('PageFaultCount', wintypes.DWORD), - ('PeakWorkingSetSize', SIZE_T), - ('WorkingSetSize', SIZE_T), - ('QuotaPeakPagedPoolUsage', SIZE_T), - ('QuotaPagedPoolUsage', SIZE_T), - ('QuotaPeakNonPagedPoolUsage', SIZE_T), - ('QuotaNonPagedPoolUsage', SIZE_T), - ('PagefileUsage', SIZE_T), - ('PeakPagefileUsage', SIZE_T), - ('PrivateUsage', SIZE_T), - ] - - -GetProcessMemoryInfo = ctypes.windll.psapi.GetProcessMemoryInfo -GetProcessMemoryInfo.argtypes = [ - wintypes.HANDLE, - ctypes.POINTER(PROCESS_MEMORY_COUNTERS_EX), - wintypes.DWORD, -] -GetProcessMemoryInfo.restype = wintypes.BOOL - - -def get_current_process(): - """Return handle to current process.""" - return GetCurrentProcess() - - -def get_memory_info(process=None): - """Return Win32 process memory counters structure as a dict.""" - if process is None: - process = get_current_process() - counters = PROCESS_MEMORY_COUNTERS_EX() - ret = GetProcessMemoryInfo(process, ctypes.byref(counters), - ctypes.sizeof(counters)) - if not ret: - raise ctypes.WinError() - info = dict((name, getattr(counters, name)) - for name, _ in counters._fields_) - return info - - -def get_memory_usage(process=None): - """Return this process's memory usage in bytes.""" - info = get_memory_info(process=process) - return info['PrivateUsage'] - - -def get_peak_memory_usage(process=None): - """Return this process's memory usage in bytes.""" - info = get_memory_info(process=process) - return info['PeakWorkingSetSize'] - - -if __name__ == '__main__': - import pprint - - pprint.pprint(get_memory_info()) diff --git a/scons/scons-local-4.1.0/SCons/cpp.py b/scons/scons-local-4.1.0/SCons/cpp.py deleted file mode 100644 index 65358b3ab..000000000 --- a/scons/scons-local-4.1.0/SCons/cpp.py +++ /dev/null @@ -1,655 +0,0 @@ -# MIT License -# -# Copyright 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 C Pre-Processor module""" - -import SCons.compat - -import os -import re - -# -# First "subsystem" of regular expressions that we set up: -# -# Stuff to turn the C preprocessor directives in a file's contents into -# a list of tuples that we can process easily. -# - -# A table of regular expressions that fetch the arguments from the rest of -# a C preprocessor line. Different directives have different arguments -# that we want to fetch, using the regular expressions to which the lists -# of preprocessor directives map. -cpp_lines_dict = { - # Fetch the rest of a #if/#elif as one argument, - # with white space optional. - ('if', 'elif') : r'\s*(.+)', - - # Fetch the rest of a #ifdef/#ifndef as one argument, - # separated from the keyword by white space. - ('ifdef', 'ifndef',): r'\s+(.+)', - - # Fetch the rest of a #import/#include/#include_next line as one - # argument, with white space optional. - ('import', 'include', 'include_next',) - : r'\s*(.+)', - - # We don't care what comes after a #else or #endif line. - ('else', 'endif',) : '', - - # Fetch three arguments from a #define line: - # 1) The #defined keyword. - # 2) The optional parentheses and arguments (if it's a function-like - # macro, '' if it's not). - # 3) The expansion value. - ('define',) : r'\s+([_A-Za-z][_A-Za-z0-9_]*)(\([^)]*\))?\s*(.*)', - - # Fetch the #undefed keyword from a #undef line. - ('undef',) : r'\s+([_A-Za-z][A-Za-z0-9_]*)', -} - -# Create a table that maps each individual C preprocessor directive to -# the corresponding compiled regular expression that fetches the arguments -# we care about. -Table = {} -for op_list, expr in cpp_lines_dict.items(): - e = re.compile(expr) - for op in op_list: - Table[op] = e -del e -del op -del op_list - -# Create a list of the expressions we'll use to match all of the -# preprocessor directives. These are the same as the directives -# themselves *except* that we must use a negative lookahead assertion -# when matching "if" so it doesn't match the "if" in "ifdef" or "ifndef". -override = { - 'if' : 'if(?!n?def)', -} -l = [override.get(x, x) for x in Table.keys()] - - -# Turn the list of expressions into one big honkin' regular expression -# that will match all the preprocessor lines at once. This will return -# a list of tuples, one for each preprocessor line. The preprocessor -# directive will be the first element in each tuple, and the rest of -# the line will be the second element. -e = r'^\s*#\s*(' + '|'.join(l) + ')(.*)$' - -# And last but not least, compile the expression. -CPP_Expression = re.compile(e, re.M) - -# A list with RE to cleanup CPP Expressions (tuples) -# We should remove all comments and carriage returns (\r) before evaluating -CPP_Expression_Cleaner_List = [ - r"/\*.*\*/", - r"/\*.*", - r"//.*", - r"\r" -] -CPP_Expression_Cleaner_RE = re.compile( - r"\s*(" + "|".join(CPP_Expression_Cleaner_List) + ")") - -def Cleanup_CPP_Expressions(ts): - return [(t[0], CPP_Expression_Cleaner_RE.sub("", t[1])) for t in ts] - -# -# Second "subsystem" of regular expressions that we set up: -# -# Stuff to translate a C preprocessor expression (as found on a #if or -# #elif line) into an equivalent Python expression that we can eval(). -# - -# A dictionary that maps the C representation of Boolean operators -# to their Python equivalents. -CPP_to_Python_Ops_Dict = { - '!' : ' not ', - '!=' : ' != ', - '&&' : ' and ', - '||' : ' or ', - '?' : ' and ', - ':' : ' or ', -} - -CPP_to_Python_Ops_Sub = lambda m: CPP_to_Python_Ops_Dict[m.group(0)] - -# We have to sort the keys by length so that longer expressions -# come *before* shorter expressions--in particular, "!=" must -# come before "!" in the alternation. Without this, the Python -# re module, as late as version 2.2.2, empirically matches the -# "!" in "!=" first, instead of finding the longest match. -# What's up with that? -l = sorted(list(CPP_to_Python_Ops_Dict.keys()), key=lambda a: len(a), reverse=True) - -# Turn the list of keys into one regular expression that will allow us -# to substitute all of the operators at once. -expr = '|'.join(map(re.escape, l)) - -# ...and compile the expression. -CPP_to_Python_Ops_Expression = re.compile(expr) - -# A separate list of expressions to be evaluated and substituted -# sequentially, not all at once. -CPP_to_Python_Eval_List = [ - [r'defined\s+(\w+)', '"\\1" in __dict__'], - [r'defined\s*\((\w+)\)', '"\\1" in __dict__'], - [r'(0x[0-9A-Fa-f]+)(?:L|UL)?', '\\1'], - [r'(\d+)(?:L|UL)?', '\\1'], -] - -# Replace the string representations of the regular expressions in the -# list with compiled versions. -for l in CPP_to_Python_Eval_List: - l[0] = re.compile(l[0]) - -# Wrap up all of the above into a handy function. -def CPP_to_Python(s): - """ - Converts a C pre-processor expression into an equivalent - Python expression that can be evaluated. - """ - s = CPP_to_Python_Ops_Expression.sub(CPP_to_Python_Ops_Sub, s) - for expr, repl in CPP_to_Python_Eval_List: - s = re.sub(expr, repl, s) - return s - - - -del expr -del l -del override - - - -class FunctionEvaluator: - """ - Handles delayed evaluation of a #define function call. - """ - def __init__(self, name, args, expansion): - """ - Squirrels away the arguments and expansion value of a #define - macro function for later evaluation when we must actually expand - a value that uses it. - """ - self.name = name - self.args = function_arg_separator.split(args) - try: - expansion = expansion.split('##') - except AttributeError: - pass - self.expansion = expansion - def __call__(self, *values): - """ - Evaluates the expansion of a #define macro function called - with the specified values. - """ - if len(self.args) != len(values): - raise ValueError("Incorrect number of arguments to `%s'" % self.name) - # Create a dictionary that maps the macro arguments to the - # corresponding values in this "call." We'll use this when we - # eval() the expansion so that arguments will get expanded to - # the right values. - locals = {} - for k, v in zip(self.args, values): - locals[k] = v - - parts = [] - for s in self.expansion: - if s not in self.args: - s = repr(s) - parts.append(s) - statement = ' + '.join(parts) - - return eval(statement, globals(), locals) - - - -# Find line continuations. -line_continuations = re.compile('\\\\\r?\n') - -# Search for a "function call" macro on an expansion. Returns the -# two-tuple of the "function" name itself, and a string containing the -# arguments within the call parentheses. -function_name = re.compile(r'(\S+)\(([^)]*)\)') - -# Split a string containing comma-separated function call arguments into -# the separate arguments. -function_arg_separator = re.compile(r',\s*') - - - -class PreProcessor: - - """ - The main workhorse class for handling C pre-processing. - """ - def __init__(self, current=os.curdir, cpppath=(), dict={}, all=0, depth=-1): - global Table - - cpppath = tuple(cpppath) - - self.searchpath = { - '"' : (current,) + cpppath, - '<' : cpppath + (current,), - } - - # Initialize our C preprocessor namespace for tracking the - # values of #defined keywords. We use this namespace to look - # for keywords on #ifdef/#ifndef lines, and to eval() the - # expressions on #if/#elif lines (after massaging them from C to - # Python). - self.cpp_namespace = dict.copy() - self.cpp_namespace['__dict__'] = self.cpp_namespace - - # Return all includes without resolving - if all: - self.do_include = self.all_include - - # Max depth of nested includes: - # -1 = unlimited - # 0 - disabled nesting - # >0 - number of allowed nested includes - self.depth = depth - - # For efficiency, a dispatch table maps each C preprocessor - # directive (#if, #define, etc.) to the method that should be - # called when we see it. We accomodate state changes (#if, - # #ifdef, #ifndef) by pushing the current dispatch table on a - # stack and changing what method gets called for each relevant - # directive we might see next at this level (#else, #elif). - # #endif will simply pop the stack. - d = { - 'scons_current_file' : self.scons_current_file - } - for op in Table.keys(): - d[op] = getattr(self, 'do_' + op) - self.default_table = d - - def __call__(self, file): - """ - Pre-processes a file. - - This is the main public entry point. - """ - self.current_file = file - return self.process_file(file) - - def process_file(self, file): - """ - Pre-processes a file. - - This is the main internal entry point. - """ - return self._process_tuples(self.tupleize(self.read_file(file)), file) - - def process_contents(self, contents): - """ - Pre-processes a file contents. - - Is used by tests - """ - return self._process_tuples(self.tupleize(contents)) - - def _process_tuples(self, tuples, file=None): - self.stack = [] - self.dispatch_table = self.default_table.copy() - self.current_file = file - self.tuples = tuples - - self.initialize_result(file) - while self.tuples: - t = self.tuples.pop(0) - # Uncomment to see the list of tuples being processed (e.g., - # to validate the CPP lines are being translated correctly). - # print(t) - self.dispatch_table[t[0]](t) - return self.finalize_result(file) - - def tupleize(self, contents): - """ - Turns the contents of a file into a list of easily-processed - tuples describing the CPP lines in the file. - - The first element of each tuple is the line's preprocessor - directive (#if, #include, #define, etc., minus the initial '#'). - The remaining elements are specific to the type of directive, as - pulled apart by the regular expression. - """ - return self._match_tuples(self._parse_tuples(contents)) - - def _parse_tuples(self, contents): - global CPP_Expression - contents = line_continuations.sub('', contents) - tuples = CPP_Expression.findall(contents) - return Cleanup_CPP_Expressions(tuples) - - def _match_tuples(self, tuples): - global Table - result = [] - for t in tuples: - m = Table[t[0]].match(t[1]) - if m: - result.append((t[0],) + m.groups()) - return result - - # Dispatch table stack manipulation methods. - - def save(self): - """ - Pushes the current dispatch table on the stack and re-initializes - the current dispatch table to the default. - """ - self.stack.append(self.dispatch_table) - self.dispatch_table = self.default_table.copy() - - def restore(self): - """ - Pops the previous dispatch table off the stack and makes it the - current one. - """ - try: self.dispatch_table = self.stack.pop() - except IndexError: pass - - # Utility methods. - - def do_nothing(self, t): - """ - Null method for when we explicitly want the action for a - specific preprocessor directive to do nothing. - """ - pass - - def scons_current_file(self, t): - self.current_file = t[1] - - def eval_expression(self, t): - """ - Evaluates a C preprocessor expression. - - This is done by converting it to a Python equivalent and - eval()ing it in the C preprocessor namespace we use to - track #define values. - """ - t = CPP_to_Python(' '.join(t[1:])) - try: - return eval(t, self.cpp_namespace) - except (NameError, TypeError, SyntaxError): - return 0 - - def initialize_result(self, fname): - self.result = [fname] - - def finalize_result(self, fname): - return self.result[1:] - - def find_include_file(self, t): - """ - Finds the #include file for a given preprocessor tuple. - """ - fname = t[2] - for d in self.searchpath[t[1]]: - if d == os.curdir: - f = fname - else: - f = os.path.join(d, fname) - if os.path.isfile(f): - return f - return None - - def read_file(self, file): - with open(file) as f: - return f.read() - - # Start and stop processing include lines. - - def start_handling_includes(self, t=None): - """ - Causes the PreProcessor object to start processing #import, - #include and #include_next lines. - - This method will be called when a #if, #ifdef, #ifndef or #elif - evaluates True, or when we reach the #else in a #if, #ifdef, - #ifndef or #elif block where a condition already evaluated - False. - - """ - d = self.dispatch_table - p = self.stack[-1] if self.stack else self.default_table - - for k in ('import', 'include', 'include_next', 'define', 'undef'): - d[k] = p[k] - - def stop_handling_includes(self, t=None): - """ - Causes the PreProcessor object to stop processing #import, - #include and #include_next lines. - - This method will be called when a #if, #ifdef, #ifndef or #elif - evaluates False, or when we reach the #else in a #if, #ifdef, - #ifndef or #elif block where a condition already evaluated True. - """ - d = self.dispatch_table - d['import'] = self.do_nothing - d['include'] = self.do_nothing - d['include_next'] = self.do_nothing - d['define'] = self.do_nothing - d['undef'] = self.do_nothing - - # Default methods for handling all of the preprocessor directives. - # (Note that what actually gets called for a given directive at any - # point in time is really controlled by the dispatch_table.) - - def _do_if_else_condition(self, condition): - """ - Common logic for evaluating the conditions on #if, #ifdef and - #ifndef lines. - """ - self.save() - d = self.dispatch_table - if condition: - self.start_handling_includes() - d['elif'] = self.stop_handling_includes - d['else'] = self.stop_handling_includes - else: - self.stop_handling_includes() - d['elif'] = self.do_elif - d['else'] = self.start_handling_includes - - def do_ifdef(self, t): - """ - Default handling of a #ifdef line. - """ - self._do_if_else_condition(t[1] in self.cpp_namespace) - - def do_ifndef(self, t): - """ - Default handling of a #ifndef line. - """ - self._do_if_else_condition(t[1] not in self.cpp_namespace) - - def do_if(self, t): - """ - Default handling of a #if line. - """ - self._do_if_else_condition(self.eval_expression(t)) - - def do_elif(self, t): - """ - Default handling of a #elif line. - """ - d = self.dispatch_table - if self.eval_expression(t): - self.start_handling_includes() - d['elif'] = self.stop_handling_includes - d['else'] = self.stop_handling_includes - - def do_else(self, t): - """ - Default handling of a #else line. - """ - pass - - def do_endif(self, t): - """ - Default handling of a #endif line. - """ - self.restore() - - def do_define(self, t): - """ - Default handling of a #define line. - """ - _, name, args, expansion = t - try: - expansion = int(expansion) - except (TypeError, ValueError): - # handle "defined" chain "! (defined (A) || defined (B)" ... - if "defined " in expansion: - self.cpp_namespace[name] = self.eval_expression(t[2:]) - return - - if args: - evaluator = FunctionEvaluator(name, args[1:-1], expansion) - self.cpp_namespace[name] = evaluator - else: - self.cpp_namespace[name] = expansion - - def do_undef(self, t): - """ - Default handling of a #undef line. - """ - try: del self.cpp_namespace[t[1]] - except KeyError: pass - - def do_import(self, t): - """ - Default handling of a #import line. - """ - # XXX finish this -- maybe borrow/share logic from do_include()...? - pass - - def do_include(self, t): - """ - Default handling of a #include line. - """ - t = self.resolve_include(t) - if not t: - return - include_file = self.find_include_file(t) - # avoid infinite recursion - if not include_file or include_file in self.result: - return - self.result.append(include_file) - # print include_file, len(self.tuples) - - # Handle maximum depth of nested includes - if self.depth != -1: - current_depth = 0 - for t in self.tuples: - if t[0] == "scons_current_file": - current_depth += 1 - if current_depth >= self.depth: - return - - new_tuples = [('scons_current_file', include_file)] + \ - self.tupleize(self.read_file(include_file)) + \ - [('scons_current_file', self.current_file)] - self.tuples[:] = new_tuples + self.tuples - - # Date: Tue, 22 Nov 2005 20:26:09 -0500 - # From: Stefan Seefeld - # - # By the way, #include_next is not the same as #include. The difference - # being that #include_next starts its search in the path following the - # path that let to the including file. In other words, if your system - # include paths are ['/foo', '/bar'], and you are looking at a header - # '/foo/baz.h', it might issue an '#include_next ' which would - # correctly resolve to '/bar/baz.h' (if that exists), but *not* see - # '/foo/baz.h' again. See http://www.delorie.com/gnu/docs/gcc/cpp_11.html - # for more reasoning. - # - # I have no idea in what context 'import' might be used. - - # XXX is #include_next really the same as #include ? - do_include_next = do_include - - # Utility methods for handling resolution of include files. - - def resolve_include(self, t): - """Resolve a tuple-ized #include line. - - This handles recursive expansion of values without "" or <> - surrounding the name until an initial " or < is found, to handle - #include FILE where FILE is a #define somewhere else. - """ - s = t[1].strip() - while not s[0] in '<"': - try: - s = self.cpp_namespace[s] - except KeyError: - m = function_name.search(s) - - # Date: Mon, 28 Nov 2016 17:47:13 UTC - # From: Ivan Kravets - # - # Ignore `#include` directive that depends on dynamic macro - # which is not located in state TABLE - # For example, `#include MYCONFIG_FILE` - if not m: - return None - - s = self.cpp_namespace[m.group(1)] - if callable(s): - args = function_arg_separator.split(m.group(2)) - s = s(*args) - if not s: - return None - return (t[0], s[0], s[1:-1]) - - def all_include(self, t): - """ - """ - self.result.append(self.resolve_include(t)) - - -class DumbPreProcessor(PreProcessor): - """A preprocessor that ignores all #if/#elif/#else/#endif directives - and just reports back *all* of the #include files (like the classic - SCons scanner did). - - This is functionally equivalent to using a regular expression to - find all of the #include lines, only slower. It exists mainly as - an example of how the main PreProcessor class can be sub-classed - to tailor its behavior. - """ - def __init__(self, *args, **kw): - PreProcessor.__init__(self, *args, **kw) - d = self.default_table - for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']: - d[func] = d[func] = self.do_nothing - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/dblite.py b/scons/scons-local-4.1.0/SCons/dblite.py deleted file mode 100644 index a5186caf9..000000000 --- a/scons/scons-local-4.1.0/SCons/dblite.py +++ /dev/null @@ -1,298 +0,0 @@ -# MIT License -# -# Copyright 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. - -""" -dblite.py module contributed by Ralf W. Grosse-Kunstleve. -Extended for Unicode by Steven Knight. -""" - -import os -import pickle -import shutil -import time - -from SCons.compat import PICKLE_PROTOCOL - -KEEP_ALL_FILES = False -IGNORE_CORRUPT_DBFILES = False - - -def corruption_warning(filename): - """Local warning for corrupt db. - - Used for self-tests. SCons overwrites this with a - different warning function in SConsign.py. - """ - print("Warning: Discarding corrupt database:", filename) - -DBLITE_SUFFIX = '.dblite' -TMP_SUFFIX = '.tmp' - - -class dblite: - """ - Squirrel away references to the functions in various modules - that we'll use when our __del__() method calls our sync() method - during shutdown. We might get destroyed when Python is in the midst - of tearing down the different modules we import in an essentially - arbitrary order, and some of the various modules's global attributes - may already be wiped out from under us. - - See the discussion at: - http://mail.python.org/pipermail/python-bugs-list/2003-March/016877.html - - """ - - _open = open - _pickle_dump = staticmethod(pickle.dump) - _pickle_protocol = PICKLE_PROTOCOL - - try: - _os_chown = os.chown - except AttributeError: - _os_chown = None - _os_replace = os.replace - _os_chmod = os.chmod - _shutil_copyfile = shutil.copyfile - _time_time = time.time - - def __init__(self, file_base_name, flag, mode): - assert flag in (None, "r", "w", "c", "n") - if flag is None: - flag = "r" - - base, ext = os.path.splitext(file_base_name) - if ext == DBLITE_SUFFIX: - # There's already a suffix on the file name, don't add one. - self._file_name = file_base_name - self._tmp_name = base + TMP_SUFFIX - else: - self._file_name = file_base_name + DBLITE_SUFFIX - self._tmp_name = file_base_name + TMP_SUFFIX - - self._flag = flag - self._mode = mode - self._dict = {} - self._needs_sync = False - - if self._os_chown is not None and (os.geteuid() == 0 or os.getuid() == 0): - # running as root; chown back to current owner/group when done - try: - statinfo = os.stat(self._file_name) - self._chown_to = statinfo.st_uid - self._chgrp_to = statinfo.st_gid - except OSError: - # db file doesn't exist yet. - # Check os.environ for SUDO_UID, use if set - self._chown_to = int(os.environ.get('SUDO_UID', -1)) - self._chgrp_to = int(os.environ.get('SUDO_GID', -1)) - else: - self._chown_to = -1 # don't chown - self._chgrp_to = -1 # don't chgrp - - if self._flag == "n": - with self._open(self._file_name, "wb", self._mode): - pass # just make sure it exists - else: - try: - f = self._open(self._file_name, "rb") - except IOError as e: - if self._flag != "c": - raise e - with self._open(self._file_name, "wb", self._mode): - pass # just make sure it exists - else: - p = f.read() - f.close() - if len(p) > 0: - try: - self._dict = pickle.loads(p, encoding='bytes') - except (pickle.UnpicklingError, EOFError, KeyError): - # Note how we catch KeyErrors too here, which might happen - # when we don't have cPickle available (default pickle - # throws it). - if IGNORE_CORRUPT_DBFILES: - corruption_warning(self._file_name) - else: - raise - - def close(self): - if self._needs_sync: - self.sync() - - def __del__(self): - self.close() - - def sync(self): - self._check_writable() - with self._open(self._tmp_name, "wb", self._mode) as f: - self._pickle_dump(self._dict, f, self._pickle_protocol) - - try: - self._os_replace(self._tmp_name, self._file_name) - except PermissionError: - # If we couldn't replace due to perms, try to change and retry. - # This is mainly for Windows - on POSIX the file permissions - # don't matter, the os.replace would have worked anyway. - # We're giving up if the retry fails, just let the Python - # exception abort us. - try: - self._os_chmod(self._file_name, 0o777) - except PermissionError: - pass - self._os_replace(self._tmp_name, self._file_name) - - if self._os_chown is not None and self._chown_to > 0: # don't chown to root or -1 - try: - self._os_chown(self._file_name, self._chown_to, self._chgrp_to) - except OSError: - pass - - self._needs_sync = False - if KEEP_ALL_FILES: - self._shutil_copyfile( - self._file_name, - self._file_name + "_" + str(int(self._time_time())) - ) - - def _check_writable(self): - if self._flag == "r": - raise IOError("Read-only database: %s" % self._file_name) - - def __getitem__(self, key): - return self._dict[key] - - def __setitem__(self, key, value): - self._check_writable() - - if not isinstance(key, str): - raise TypeError("key `%s' must be a string but is %s" % (key, type(key))) - - if not isinstance(value, bytes): - raise TypeError("value `%s' must be a bytes but is %s" % (value, type(value))) - - self._dict[key] = value - self._needs_sync = True - - def keys(self): - return list(self._dict.keys()) - - def has_key(self, key): - return key in self._dict - - def __contains__(self, key): - return key in self._dict - - def __iter__(self): - return iter(self._dict) - - def __len__(self): - return len(self._dict) - - -def open(file, flag=None, mode=0o666): - return dblite(file, flag, mode) - - -def _exercise(): - db = open("tmp", "n") - assert len(db) == 0 - db["foo"] = b"bar" - assert db["foo"] == b"bar" - db.sync() - - db = open("tmp", "c") - assert len(db) == 1, len(db) - assert db["foo"] == b"bar" - db["bar"] = b"foo" - assert db["bar"] == b"foo" - db.sync() - - db = open("tmp", "r") - assert len(db) == 2, len(db) - assert db["foo"] == b"bar" - assert db["bar"] == b"foo" - try: - db.sync() - except IOError as e: - assert str(e) == "Read-only database: tmp.dblite" - else: - raise RuntimeError("IOError expected.") - db = open("tmp", "w") - assert len(db) == 2, len(db) - db["ping"] = b"pong" - db.sync() - - try: - db[(1, 2)] = "tuple" - except TypeError as e: - assert str(e) == "key `(1, 2)' must be a string but is ", str(e) - else: - raise RuntimeError("TypeError exception expected") - - try: - db["list"] = [1, 2] - except TypeError as e: - assert str(e) == "value `[1, 2]' must be a bytes but is ", str(e) - else: - raise RuntimeError("TypeError exception expected") - - db = open("tmp", "r") - assert len(db) == 3, len(db) - - db = open("tmp", "n") - assert len(db) == 0, len(db) - dblite._open("tmp.dblite", "w") - - db = open("tmp", "r") - dblite._open("tmp.dblite", "w").write("x") - try: - db = open("tmp", "r") - except pickle.UnpicklingError: - pass - else: - raise RuntimeError("pickle exception expected.") - - global IGNORE_CORRUPT_DBFILES - IGNORE_CORRUPT_DBFILES = True - db = open("tmp", "r") - assert len(db) == 0, len(db) - os.unlink("tmp.dblite") - try: - db = open("tmp", "w") - except IOError as e: - assert str(e) == "[Errno 2] No such file or directory: 'tmp.dblite'", str(e) - else: - raise RuntimeError("IOError expected.") - - print("Completed _exercise()") - - -if __name__ == "__main__": - _exercise() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-local-4.1.0/SCons/exitfuncs.py b/scons/scons-local-4.1.0/SCons/exitfuncs.py deleted file mode 100644 index ba6243a7a..000000000 --- a/scons/scons-local-4.1.0/SCons/exitfuncs.py +++ /dev/null @@ -1,59 +0,0 @@ -# MIT License -# -# Copyright 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. - -"""Register functions which are executed when SCons exits for any reason.""" - -# This is obsolete now - -import atexit - -_exithandlers = [] -def _run_exitfuncs(): - """run any registered exit functions - - _exithandlers is traversed in reverse order so functions are executed - last in, first out. - """ - - while _exithandlers: - func, targs, kargs = _exithandlers.pop() - func(*targs, **kargs) - -def register(func, *targs, **kargs): - """register a function to be executed upon normal program termination - - func - function to be called at exit - targs - optional arguments to pass to func - kargs - optional keyword arguments to pass to func - """ - _exithandlers.append((func, targs, kargs)) - - -# make our exit function get run by python when it exits -atexit.register(_run_exitfuncs) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/scons-time.py b/scons/scons-time.py index a2a3e30ea..44f0775fa 100644 --- a/scons/scons-time.py +++ b/scons/scons-time.py @@ -1,15 +1,8 @@ #!/usr/bin/env python -# -# scons-time - run SCons timings and collect statistics -# -# A script for running a configuration through SCons with a standard -# set of invocations to collect timing and memory statistics and to -# capture the results in a consistent set of output files for display -# and analysis. -# +# MIT License # -# Copyright (c) 2001 - 2021 The SCons Foundation +# Copyright 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 +23,13 @@ # 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__ = "bin/scons-time.py 215860fd4f6bea67896c145660a035fad20cc41c 2021-01-19 19:32:22 bdbaddog" +""" +scons-time - run SCons timings and collect statistics + +A script for running a configuration through SCons with a standard set +of invocations to collect timing and memory statistics and to capture +the results in a consistent set of output files for display and analysis. +""" import getopt import glob diff --git a/scons/scons.py b/scons/scons.py index fd2b7eba5..a50b53444 100755 --- a/scons/scons.py +++ b/scons/scons.py @@ -2,7 +2,9 @@ # # SCons - a Software Constructor # -# Copyright (c) 2001 - 2021 The SCons Foundation +# MIT License +# +# Copyright 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,17 +23,17 @@ # 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. +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE -__revision__ = "scripts/scons.py 215860fd4f6bea67896c145660a035fad20cc41c 2021-01-19 19:32:22 bdbaddog" +__revision__ = "scripts/scons.py 49578b34582d9e92dac7d713a8e58599ae35aa63 Mon, 06 Mar 2023 23:32:38 -0400 bdbaddog" -__version__ = "4.1.0" +__version__ = "4.5.1" -__build__ = "215860fd4f6bea67896c145660a035fad20cc41c" +__build__ = "49578b34582d9e92dac7d713a8e58599ae35aa63" -__buildsys__ = "ProDog2020" +__buildsys__ = "M1DOG2021" -__date__ = "2021-01-19 19:32:22" +__date__ = "Mon, 06 Mar 2023 23:32:38 -0400" __developer__ = "bdbaddog" @@ -39,9 +41,8 @@ __developer__ = "bdbaddog" import os import sys - # Python compatibility check -if sys.version_info < (3, 5, 0): +if sys.version_info < (3, 6, 0): msg = "scons: *** SCons version %s does not run under Python version %s.\n\ Python >= 3.5 is required.\n" sys.stderr.write(msg % (__version__, sys.version.split()[0])) diff --git a/scons/sconsign.py b/scons/sconsign.py index da6d935f0..9b398dcd6 100644 --- a/scons/sconsign.py +++ b/scons/sconsign.py @@ -2,7 +2,9 @@ # # SCons - a Software Constructor # -# Copyright (c) 2001 - 2021 The SCons Foundation +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -23,15 +25,15 @@ # 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__ = "scripts/sconsign.py 215860fd4f6bea67896c145660a035fad20cc41c 2021-01-19 19:32:22 bdbaddog" +__revision__ = "scripts/sconsign.py 49578b34582d9e92dac7d713a8e58599ae35aa63 Mon, 06 Mar 2023 23:32:38 -0400 bdbaddog" -__version__ = "4.1.0" +__version__ = "4.5.1" -__build__ = "215860fd4f6bea67896c145660a035fad20cc41c" +__build__ = "49578b34582d9e92dac7d713a8e58599ae35aa63" -__buildsys__ = "ProDog2020" +__buildsys__ = "M1DOG2021" -__date__ = "2021-01-19 19:32:22" +__date__ = "Mon, 06 Mar 2023 23:32:38 -0400" __developer__ = "bdbaddog" @@ -39,7 +41,7 @@ import os import sys # python compatibility check -if sys.version_info < (3, 5, 0): +if sys.version_info < (3, 6, 0): msg = "scons: *** SCons version %s does not run under Python version %s.\n\ Python >= 3.5 is required.\n" sys.stderr.write(msg % (__version__, sys.version.split()[0]))