summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2018-10-09 20:23:51 (GMT)
committerWilliam Deegan <bill@baddogconsulting.com>2018-10-09 20:23:51 (GMT)
commitade84bc59db524fbccd670bfadefa786407c7c0b (patch)
treea3da7c7e0fa926ad41f01ae09ab709c660c67bd9
parenta1c6873e2f84240feab9a923ccc1ebcda3160339 (diff)
parente342d031c2a80cc7eb27ca139b7adee2d37a8216 (diff)
downloadSCons-ade84bc59db524fbccd670bfadefa786407c7c0b.zip
SCons-ade84bc59db524fbccd670bfadefa786407c7c0b.tar.gz
SCons-ade84bc59db524fbccd670bfadefa786407c7c0b.tar.bz2
Merge remote-tracking branch 'upstream/master' into subst_rewrite
-rw-r--r--.appveyor.yml61
-rw-r--r--.github/issue_template.md12
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml36
-rwxr-xr-x.travis/install.sh10
-rw-r--r--HOWTO/README29
-rw-r--r--HOWTO/change.txt61
-rw-r--r--HOWTO/new-platform.txt74
-rw-r--r--HOWTO/new-script.txt75
-rw-r--r--HOWTO/new-tool.txt81
-rw-r--r--HOWTO/release.txt656
-rw-r--r--HOWTO/subrelease.txt114
-rw-r--r--QMTest/test-framework.rst430
-rw-r--r--README.rst52
-rw-r--r--SConstruct14
-rw-r--r--bin/SConsExamples.py6
-rw-r--r--bin/scons-cdist272
-rw-r--r--bin/scons_dev_master.py19
-rw-r--r--bin/time-scons.py2
-rw-r--r--bin/update-release-info.py10
-rwxr-xr-xbin/xmlagenda.py6
-rw-r--r--doc/design/native.xml5
-rw-r--r--doc/generated/builders.gen12
-rw-r--r--doc/generated/examples/builderswriting_MY_EMITTER_1.xml4
-rw-r--r--doc/generated/examples/caching_ex-random_1.xml4
-rw-r--r--doc/generated/examples/troubleshoot_Dump_2.xml2
-rw-r--r--doc/generated/examples/troubleshoot_explain1_3.xml2
-rw-r--r--doc/generated/examples/troubleshoot_stacktrace_2.xml2
-rw-r--r--doc/generated/functions.gen19
-rw-r--r--doc/generated/tools.gen12
-rw-r--r--doc/generated/tools.mod4
-rw-r--r--doc/generated/variables.gen164
-rw-r--r--doc/generated/variables.mod6
-rw-r--r--doc/man/scons.xml22
-rw-r--r--doc/scons.mod3
-rw-r--r--doc/user/builders-writing.xml22
-rw-r--r--doc/user/depends.xml8
-rw-r--r--doc/user/environments.xml6
-rw-r--r--doc/user/parseflags.xml2
-rwxr-xr-xruntest.py29
-rw-r--r--src/CHANGES.txt167
-rw-r--r--src/engine/MANIFEST.in2
-rw-r--r--src/engine/SCons/Action.py20
-rw-r--r--src/engine/SCons/ActionTests.py541
-rw-r--r--src/engine/SCons/CacheDir.py4
-rw-r--r--src/engine/SCons/CacheDirTests.py12
-rw-r--r--src/engine/SCons/Conftest.py20
-rw-r--r--src/engine/SCons/Defaults.py3
-rw-r--r--src/engine/SCons/DefaultsTests.py9
-rw-r--r--src/engine/SCons/Environment.py5
-rw-r--r--src/engine/SCons/Environment.xml2
-rw-r--r--src/engine/SCons/Errors.py11
-rw-r--r--src/engine/SCons/ErrorsTests.py30
-rw-r--r--src/engine/SCons/ExecutorTests.py9
-rw-r--r--src/engine/SCons/JobTests.py101
-rw-r--r--src/engine/SCons/MemoizeTests.py12
-rw-r--r--src/engine/SCons/Node/AliasTests.py13
-rw-r--r--src/engine/SCons/Node/FS.py11
-rw-r--r--src/engine/SCons/Node/FSTests.py9
-rw-r--r--src/engine/SCons/Node/NodeTests.py12
-rw-r--r--src/engine/SCons/Node/PythonTests.py13
-rw-r--r--src/engine/SCons/Node/__init__.py4
-rw-r--r--src/engine/SCons/Platform/PlatformTests.py13
-rw-r--r--src/engine/SCons/Platform/cygwin.py9
-rw-r--r--src/engine/SCons/Platform/mingw.py39
-rw-r--r--src/engine/SCons/Platform/posix.py2
-rw-r--r--src/engine/SCons/Platform/win32.py8
-rw-r--r--src/engine/SCons/SConf.py4
-rw-r--r--src/engine/SCons/SConfTests.py26
-rw-r--r--src/engine/SCons/Scanner/CTests.py16
-rw-r--r--src/engine/SCons/Scanner/DTests.py12
-rw-r--r--src/engine/SCons/Scanner/DirTests.py9
-rw-r--r--src/engine/SCons/Scanner/Fortran.py2
-rw-r--r--src/engine/SCons/Scanner/FortranTests.py2
-rw-r--r--src/engine/SCons/Scanner/IDLTests.py8
-rw-r--r--src/engine/SCons/Scanner/LaTeX.py16
-rw-r--r--src/engine/SCons/Scanner/LaTeXTests.py13
-rw-r--r--src/engine/SCons/Scanner/ProgTests.py3
-rw-r--r--src/engine/SCons/Scanner/RCTests.py5
-rw-r--r--src/engine/SCons/Scanner/ScannerTests.py52
-rw-r--r--src/engine/SCons/Script/Main.py9
-rw-r--r--src/engine/SCons/Script/MainTests.py9
-rw-r--r--src/engine/SCons/Script/SConscript.py57
-rw-r--r--src/engine/SCons/Script/SConscript.xml19
-rw-r--r--src/engine/SCons/Script/__init__.py12
-rw-r--r--src/engine/SCons/Subst.py2
-rw-r--r--src/engine/SCons/SubstTests.py2
-rw-r--r--src/engine/SCons/Taskmaster.py9
-rw-r--r--src/engine/SCons/TaskmasterTests.py4
-rw-r--r--src/engine/SCons/Tool/GettextCommon.py8
-rw-r--r--src/engine/SCons/Tool/JavaCommon.py106
-rw-r--r--src/engine/SCons/Tool/JavaCommonTests.py52
-rw-r--r--src/engine/SCons/Tool/MSCommon/arch.py8
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py17
-rw-r--r--src/engine/SCons/Tool/__init__.py41
-rw-r--r--src/engine/SCons/Tool/applelink.py6
-rw-r--r--src/engine/SCons/Tool/clang.py11
-rw-r--r--src/engine/SCons/Tool/clangCommon/__init__.py17
-rw-r--r--src/engine/SCons/Tool/clangxx.py13
-rw-r--r--src/engine/SCons/Tool/docbook/docs/manual.xml2
-rw-r--r--src/engine/SCons/Tool/gettext_tool.py12
-rw-r--r--src/engine/SCons/Tool/gfortran.py2
-rw-r--r--src/engine/SCons/Tool/intelc.py2
-rw-r--r--src/engine/SCons/Tool/jar.py54
-rw-r--r--src/engine/SCons/Tool/javac.py3
-rw-r--r--src/engine/SCons/Tool/javacTests.py9
-rw-r--r--src/engine/SCons/Tool/mingw.py65
-rw-r--r--src/engine/SCons/Tool/msgfmt.py14
-rw-r--r--src/engine/SCons/Tool/msginit.py14
-rw-r--r--src/engine/SCons/Tool/msgmerge.py15
-rw-r--r--src/engine/SCons/Tool/msvc.py7
-rw-r--r--src/engine/SCons/Tool/msvs.py10
-rw-r--r--src/engine/SCons/Tool/packaging/__init__.py37
-rw-r--r--src/engine/SCons/Tool/packaging/__init__.xml59
-rw-r--r--src/engine/SCons/Tool/packaging/msi.py5
-rw-r--r--src/engine/SCons/Tool/packaging/rpm.py53
-rw-r--r--src/engine/SCons/Tool/packaging/src_tarbz2.py2
-rw-r--r--src/engine/SCons/Tool/packaging/src_targz.py2
-rw-r--r--src/engine/SCons/Tool/packaging/src_tarxz.py43
-rw-r--r--src/engine/SCons/Tool/packaging/tarbz2.py4
-rw-r--r--src/engine/SCons/Tool/packaging/targz.py2
-rw-r--r--src/engine/SCons/Tool/packaging/tarxz.py44
-rw-r--r--src/engine/SCons/Tool/qt.py39
-rw-r--r--src/engine/SCons/Tool/rpcgen.py2
-rw-r--r--src/engine/SCons/Tool/swig.py12
-rw-r--r--src/engine/SCons/Tool/tex.py2
-rw-r--r--src/engine/SCons/Tool/wixTests.py4
-rw-r--r--src/engine/SCons/Tool/xgettext.py14
-rw-r--r--src/engine/SCons/Tool/yacc.py11
-rw-r--r--src/engine/SCons/Util.py98
-rw-r--r--src/engine/SCons/UtilTests.py28
-rw-r--r--src/engine/SCons/Variables/BoolVariableTests.py5
-rw-r--r--src/engine/SCons/Variables/EnumVariableTests.py5
-rw-r--r--src/engine/SCons/Variables/ListVariableTests.py5
-rw-r--r--src/engine/SCons/Variables/PackageVariableTests.py5
-rw-r--r--src/engine/SCons/Variables/PathVariableTests.py5
-rw-r--r--src/engine/SCons/Variables/VariablesTests.py13
-rw-r--r--src/engine/SCons/Warnings.py7
-rw-r--r--src/engine/SCons/WarningsTests.py5
-rw-r--r--src/engine/SCons/compat/__init__.py2
-rw-r--r--src/script/scons-time.py6
-rw-r--r--src/script/sconsign.py2
-rw-r--r--src/setup.py7
-rw-r--r--src/test_strings.py10
-rw-r--r--test/AS/nasm.py14
-rw-r--r--test/Builder/TargetSubst.py3
-rw-r--r--test/Builder/add_src_builder.py3
-rw-r--r--test/Builder/different-actions.py5
-rw-r--r--test/Builder/ensure_suffix.py3
-rw-r--r--test/Builder/multi/different-actions.py3
-rw-r--r--test/Builder/multi/different-environments.py3
-rw-r--r--test/Builder/multi/different-multi.py4
-rw-r--r--test/Builder/multi/different-order.py3
-rw-r--r--test/Builder/multi/different-overrides.py3
-rw-r--r--test/Builder/multi/different-target-lists.py3
-rw-r--r--test/Builder/multi/error.py4
-rw-r--r--test/Builder/multi/lone-target-list.py4
-rw-r--r--test/Builder/multi/multi.py4
-rw-r--r--test/Builder/multi/same-actions.py4
-rw-r--r--test/Builder/multi/same-overrides.py4
-rw-r--r--test/Builder/multi/same-targets.py4
-rw-r--r--test/Builder/non-multi.py4
-rw-r--r--test/Builder/same-actions-diff-envs.py6
-rw-r--r--test/Builder/same-actions-diff-overrides.py4
-rw-r--r--test/Builder/srcdir.py2
-rw-r--r--test/Builder/wrapper.py5
-rw-r--r--test/CPPDEFINES/append.py6
-rw-r--r--test/CPPDEFINES/pkg-config.py35
-rw-r--r--test/CacheDir/CacheDir.py3
-rw-r--r--test/CacheDir/NoCache.py1
-rw-r--r--test/CacheDir/SideEffect.py3
-rw-r--r--test/CacheDir/VariantDir.py5
-rw-r--r--test/CacheDir/debug.py3
-rw-r--r--test/CacheDir/environment.py3
-rw-r--r--test/CacheDir/multi-targets.py3
-rw-r--r--test/CacheDir/multiple-targets.py3
-rw-r--r--test/CacheDir/option--cd.py3
-rw-r--r--test/CacheDir/option--cf.py2
-rw-r--r--test/CacheDir/option--cr.py3
-rw-r--r--test/CacheDir/option--cs.py4
-rwxr-xr-xtest/CacheDir/readonly-cache.py81
-rw-r--r--test/CacheDir/scanner-target.py1
-rw-r--r--test/CacheDir/source-scanner.py1
-rw-r--r--test/CacheDir/timestamp-match.py1
-rw-r--r--test/CacheDir/timestamp-newer.py1
-rw-r--r--test/CacheDir/up-to-date-q.py2
-rw-r--r--test/Case.py2
-rw-r--r--test/Clang/clang_default_environment.py5
-rw-r--r--test/Clang/clang_shared_library.py12
-rw-r--r--test/Clang/clang_specific_environment.py1
-rw-r--r--test/Clang/clang_static_library.py3
-rw-r--r--test/Clang/clangxx_default_environment.py5
-rw-r--r--test/Clang/clangxx_shared_library.py11
-rw-r--r--test/Clang/clangxx_specific_environment.py1
-rw-r--r--test/Clang/clangxx_static_library.py3
-rw-r--r--test/Clean/Option.py3
-rw-r--r--test/Clean/basic.py3
-rw-r--r--test/Clean/function.py3
-rw-r--r--test/Climb/explicit-parent--D.py3
-rw-r--r--test/Climb/filename--D.py1
-rw-r--r--test/Climb/filename--U.py1
-rw-r--r--test/Climb/filename-u.py1
-rw-r--r--test/Climb/option--D.py3
-rw-r--r--test/Climb/option--U.py5
-rw-r--r--test/Climb/option-u.py3
-rw-r--r--test/Configure/VariantDir-SConscript.py2
-rw-r--r--test/Configure/VariantDir.py2
-rw-r--r--test/Configure/VariantDir2.py2
-rw-r--r--test/Configure/basic.py2
-rw-r--r--test/Configure/build-fail.py2
-rw-r--r--test/Configure/clean.py2
-rw-r--r--test/Configure/custom-tests.py6
-rw-r--r--test/Configure/help.py2
-rw-r--r--test/D/Issues/2994/Common/D_changed_DFLAGS_not_rebuilding.py4
-rwxr-xr-xtest/D/Support/executablesSearch.py2
-rw-r--r--test/Decider/Environment.py3
-rw-r--r--test/Decider/MD5-timestamp.py3
-rw-r--r--test/Decider/Node.py1
-rw-r--r--test/Decider/default.py1
-rw-r--r--test/Decider/mixed.py5
-rw-r--r--test/Decider/switch-rebuild.py3
-rw-r--r--test/Decider/timestamp.py5
-rw-r--r--test/Decider/unknown.py1
-rw-r--r--test/Depends/Depends.py3
-rw-r--r--test/Depends/no-Builder.py5
-rw-r--r--test/Dir/Dir.py6
-rw-r--r--test/Dir/PyPackageDir/image/SConstruct8
-rw-r--r--test/Dir/mixed-targets.py3
-rw-r--r--test/Dir/source.py3
-rw-r--r--test/Docbook/basedir/htmlchunked/image/manual.xml2
-rw-r--r--test/Docbook/basedir/htmlhelp/image/manual.xml2
-rw-r--r--test/Docbook/basic/epub/image/manual.xml2
-rw-r--r--test/Docbook/basic/html/image/manual.xml2
-rw-r--r--test/Docbook/basic/htmlchunked/image/manual.xml2
-rw-r--r--test/Docbook/basic/htmlhelp/image/manual.xml2
-rw-r--r--test/Docbook/basic/xinclude/xinclude.py2
-rw-r--r--test/Docbook/dependencies/xinclude/xinclude.py2
-rw-r--r--test/Docbook/rootname/htmlchunked/image/manual.xml2
-rw-r--r--test/Docbook/rootname/htmlhelp/image/manual.xml2
-rw-r--r--test/Execute.py7
-rw-r--r--test/ExecuteInvalidateCache.py2
-rw-r--r--test/FindSourceFiles.py2
-rw-r--r--test/Fortran/FORTRANMODDIR.py76
-rw-r--r--test/Fortran/USE-MODULE-CASEINSENS.py2
-rw-r--r--test/Fortran/gfortran.py107
-rw-r--r--test/GetBuildFailures/option-k.py1
-rw-r--r--test/GetBuildFailures/parallel.py1
-rw-r--r--test/GetBuildFailures/serial.py1
-rw-r--r--test/GetOption/help.py1
-rw-r--r--test/Glob/Repository.py3
-rw-r--r--test/Glob/VariantDir.py5
-rw-r--r--test/Glob/basic.py3
-rw-r--r--test/Glob/exclude.py3
-rw-r--r--test/Glob/source.py3
-rw-r--r--test/Glob/strings.py3
-rw-r--r--test/Glob/subdir.py3
-rw-r--r--test/Glob/subst.py3
-rw-r--r--test/Install/Clone.py1
-rw-r--r--test/Install/INSTALLSTR.py3
-rw-r--r--test/Install/Install.py3
-rw-r--r--test/Install/InstallAs.py3
-rw-r--r--test/Install/dir-exists.py1
-rw-r--r--test/Install/directories.py4
-rw-r--r--test/Install/multi-dir/src/SConstruct3
-rw-r--r--test/Install/multi.py3
-rw-r--r--test/Install/no-top-relative.py3
-rw-r--r--test/Install/non-ascii-name.py1
-rw-r--r--test/Install/option--install-sandbox.py3
-rw-r--r--test/Install/tool.py1
-rw-r--r--test/Install/wrap-by-attribute.py3
-rw-r--r--test/Interactive/added-include.py4
-rw-r--r--test/Interactive/implicit-VariantDir.py4
-rw-r--r--test/Java/JAR.py17
-rw-r--r--test/Java/Java-1.4.py2
-rw-r--r--test/Java/Java-1.5.py2
-rw-r--r--test/Java/Java-1.6.py2
-rw-r--r--test/Java/RMIC.py4
-rw-r--r--test/Java/swig-dependencies.py2
-rw-r--r--test/LINK/VersionedLib-VariantDir.py2
-rw-r--r--test/LINK/VersionedLib-j2.py2
-rw-r--r--test/LINK/VersionedLib-subdir.py2
-rw-r--r--test/LINK/applelink.py69
-rw-r--r--test/Libs/Library.py2
-rw-r--r--test/Libs/SharedLibrary-update-deps.py2
-rw-r--r--test/M4/M4.py8
-rw-r--r--test/M4/M4COM.py3
-rw-r--r--test/M4/M4COMSTR.py3
-rw-r--r--test/MSVC/MSVC_BATCH-spaces-targetdir.py11
-rw-r--r--test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct8
-rw-r--r--test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c15
-rw-r--r--test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c5
-rw-r--r--test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c5
-rw-r--r--test/MSVC/PCH-source.py2
-rw-r--r--test/MSVC/batch.py12
-rw-r--r--test/MSVC/pch-basics.py2
-rw-r--r--test/MSVC/pch-spaces-subdir.py2
-rw-r--r--test/MSVS/CPPPATH-Dirs.py2
-rw-r--r--test/MSVS/vs-10.0-exec.py8
-rw-r--r--test/MSVS/vs-10.0Exp-exec.py8
-rw-r--r--test/MSVS/vs-11.0-exec.py8
-rw-r--r--test/MSVS/vs-11.0Exp-exec.py8
-rw-r--r--test/MSVS/vs-14.0-exec.py8
-rw-r--r--test/MSVS/vs-6.0-clean.py2
-rw-r--r--test/MSVS/vs-6.0-exec.py8
-rw-r--r--test/MSVS/vs-7.0-exec.py8
-rw-r--r--test/MSVS/vs-7.1-exec.py8
-rw-r--r--test/MSVS/vs-8.0-exec.py7
-rw-r--r--test/MSVS/vs-8.0Exp-exec.py8
-rw-r--r--test/MSVS/vs-9.0-exec.py8
-rw-r--r--test/MSVS/vs-9.0Exp-exec.py8
-rw-r--r--test/MinGW/MinGWSharedLibrary.py7
-rw-r--r--test/MinGW/WINDOWS_INSERT_DEF.py6
-rw-r--r--test/QT/CPPPATH-appended.py2
-rw-r--r--test/QT/CPPPATH.py2
-rw-r--r--test/QT/QTFLAGS.py4
-rw-r--r--test/QT/empty-env.py2
-rw-r--r--test/QT/generated-ui.py2
-rw-r--r--test/QT/manual.py2
-rw-r--r--test/QT/moc-from-header.py2
-rw-r--r--test/QT/reentrant.py2
-rw-r--r--test/QT/up-to-date.py2
-rw-r--r--test/README4
-rw-r--r--test/RPATH.py2
-rw-r--r--test/Repository/Java.py2
-rw-r--r--test/Repository/JavaH.py8
-rw-r--r--test/Repository/RMIC.py15
-rw-r--r--test/SConscript/must_exist.py122
-rw-r--r--test/SConstruct.py27
-rw-r--r--test/SWIG/SWIGOUTDIR-python.py6
-rw-r--r--test/SWIG/SWIGPATH.py5
-rw-r--r--test/SWIG/build-dir.py6
-rw-r--r--test/SWIG/generated_swigfile.py6
-rw-r--r--test/SWIG/implicit-dependencies.py5
-rw-r--r--test/SWIG/live.py15
-rw-r--r--test/SWIG/module-deduced-name.py6
-rw-r--r--test/SWIG/module-parens.py6
-rw-r--r--test/SWIG/module-quoted.py6
-rw-r--r--test/SWIG/module-spaces.py6
-rw-r--r--test/SWIG/noproxy.py6
-rw-r--r--test/SWIG/recursive-includes-cpp.py53
-rw-r--r--test/SWIG/remove-modules.py6
-rw-r--r--test/SWIG/subdir.py6
-rw-r--r--test/Scanner/Dir.py2
-rw-r--r--test/SideEffect/Issues/3013/files/SConscript5
-rw-r--r--test/SideEffect/Issues/3013/files/SConstruct21
-rw-r--r--test/SideEffect/Issues/3013/files/test.cpp2
-rw-r--r--test/SideEffect/Issues/3013/sideffect_with_variantdir.py49
-rw-r--r--test/Subst/Literal.py54
-rw-r--r--test/VariantDir/include-subdir.py2
-rw-r--r--test/YACC/YACC-fixture/myyacc.py6
-rw-r--r--test/YACC/YACC.py8
-rw-r--r--test/YACC/live-check-output-cleaned.py2
-rw-r--r--test/YACC/live.py16
-rw-r--r--test/explain/alias-order.py3
-rw-r--r--test/explain/basic.py3
-rw-r--r--test/explain/function-actions.py3
-rw-r--r--test/explain/get_csig.py3
-rw-r--r--test/explain/save-info.py3
-rw-r--r--test/implicit-cache/DualTargets.py3
-rw-r--r--test/implicit-cache/GetOption.py2
-rw-r--r--test/implicit-cache/RemoveImplicitDep.py3
-rw-r--r--test/implicit-cache/SetOption.py1
-rw-r--r--test/implicit-cache/basic.py1
-rw-r--r--test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py4
-rw-r--r--test/implicit/asynchronous-modification.py3
-rw-r--r--test/implicit/changed-node.py1
-rw-r--r--test/import.py9
-rw-r--r--test/long-lines/signature.py4
-rw-r--r--test/option-f.py9
-rw-r--r--test/option/d.py3
-rw-r--r--test/option/debug-count.py1
-rw-r--r--test/option/debug-duplicate.py3
-rw-r--r--test/option/debug-findlibs.py1
-rw-r--r--test/option/debug-includes.py1
-rw-r--r--test/option/debug-memoizer.py3
-rw-r--r--test/option/debug-memory.py3
-rw-r--r--test/option/debug-multiple.py1
-rw-r--r--test/option/debug-objects.py3
-rw-r--r--test/option/debug-pdb.py3
-rw-r--r--test/option/debug-prepare.py3
-rw-r--r--test/option/debug-presub.py4
-rw-r--r--test/option/debug-stacktrace.py3
-rw-r--r--test/option/debug-time.py4
-rw-r--r--test/option/environment-overrides.py2
-rw-r--r--test/option/help-options.py2
-rw-r--r--test/option/md5-chunksize.py6
-rw-r--r--test/option/no-print-directory.py2
-rw-r--r--test/option/option_profile.py1
-rw-r--r--test/option/print-directory.py2
-rw-r--r--test/option/repository.py3
-rw-r--r--test/option/srcdir.py3
-rw-r--r--test/option/stack-size.py3
-rw-r--r--test/option/taskmastertrace.py3
-rw-r--r--test/option/tree-all.py1
-rw-r--r--test/option/tree-derived.py1
-rw-r--r--test/option/tree-lib.py3
-rw-r--r--test/option/warn-dependency.py3
-rw-r--r--test/option/warn-duplicate-environment.py3
-rw-r--r--test/option/warn-misleading-keywords.py3
-rw-r--r--test/option/warn-missing-sconscript.py14
-rw-r--r--test/packaging/guess-package-name.py25
-rw-r--r--test/packaging/option--package-type.py8
-rw-r--r--test/packaging/rpm/cleanup.py10
-rw-r--r--test/packaging/rpm/explicit-target.py10
-rw-r--r--test/packaging/rpm/internationalization.py17
-rw-r--r--test/packaging/rpm/multipackage.py15
-rw-r--r--test/packaging/rpm/package.py15
-rw-r--r--test/packaging/rpm/src/main.c5
-rw-r--r--test/packaging/rpm/tagging.py17
-rw-r--r--test/packaging/strip-install-dir.py7
-rw-r--r--test/packaging/tar/bz2_packaging.py17
-rw-r--r--test/packaging/tar/gz.py13
-rw-r--r--test/packaging/tar/xz_packaging.py74
-rw-r--r--test/update-release-info/update-release-info.py2
-rw-r--r--testing/buildbot.yml2
-rw-r--r--testing/framework/.TestCommonTests.py.swpbin0 -> 16384 bytes
-rw-r--r--testing/framework/README.txt (renamed from QMTest/README.txt)0
-rw-r--r--testing/framework/SConscript (renamed from QMTest/SConscript)4
-rw-r--r--testing/framework/TestCmd.py (renamed from QMTest/TestCmd.py)8
-rw-r--r--testing/framework/TestCmdTests.py (renamed from QMTest/TestCmdTests.py)0
-rw-r--r--testing/framework/TestCommon.py (renamed from QMTest/TestCommon.py)122
-rw-r--r--testing/framework/TestCommonTests.py (renamed from QMTest/TestCommonTests.py)56
-rw-r--r--testing/framework/TestLiteral.py (renamed from QMTest/TestLiteral.py)0
-rw-r--r--testing/framework/TestRuntest.py (renamed from QMTest/TestRuntest.py)4
-rw-r--r--testing/framework/TestSCons.py (renamed from QMTest/TestSCons.py)110
-rw-r--r--testing/framework/TestSConsMSVS.py (renamed from QMTest/TestSConsMSVS.py)0
-rw-r--r--testing/framework/TestSCons_time.py (renamed from QMTest/TestSCons_time.py)0
-rw-r--r--testing/framework/TestSConsign.py (renamed from QMTest/TestSConsign.py)0
-rw-r--r--testing/framework/__init__.py (renamed from QMTest/__init__.py)0
-rw-r--r--testing/framework/test-framework.rst523
-rw-r--r--timings/README.txt4
-rw-r--r--www/bug-submission.html234
-rw-r--r--www/cn-project-pages/Administrivia/snippets/HtmlSnippet1.html1
-rw-r--r--www/cn-project-pages/Administrivia/snippets/description.txt1
-rw-r--r--www/cn-project-pages/Administrivia/snippets/page.xml10
-rw-r--r--www/cn-project-pages/snippets/page.xml16
-rw-r--r--www/cn-project-pages/structure.xml10
-rw-r--r--www/favicon.icobin1406 -> 0 bytes
-rw-r--r--www/feature-request.html99
-rwxr-xr-xwww/gen_sched_table.py51
-rw-r--r--www/index.html288
-rw-r--r--www/patch-submission.html355
-rw-r--r--www/project_highlights.html24
-rw-r--r--www/project_issues.html123
-rw-r--r--www/project_tools.html41
-rw-r--r--www/roadmap.html173
-rw-r--r--www/schedule19
447 files changed, 4022 insertions, 4872 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index a9d2dfc..edc8e55 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -2,14 +2,14 @@ image: Visual Studio 2017
shallow_clone: true
install:
- - "set PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
+ - "set PATH=%PYTHON%;%PYTHON%\\Scripts;C:\\cygwin64\\bin;C:\\msys64;%PATH%"
- python --version
- - pip install lxml
- pip install pypiwin32
- - choco install dmd
- - choco install ldc
- - choco install swig
- - choco install vswhere
+ - set STATIC_DEPS=true & pip install lxml
+ - choco install --allow-empty-checksums dmd
+ - choco install --allow-empty-checksums ldc
+ - choco install --allow-empty-checksums swig
+ - choco install --allow-empty-checksums vswhere
environment:
matrix:
@@ -40,32 +40,41 @@ environment:
- PYTHON: "C:\\Python36"
BUILD_JOB_NUM: 4
- - PYTHON: "C:\\Python27-x64"
+ - PYTHON: "C:\\Python37"
BUILD_JOB_NUM: 1
- - PYTHON: "C:\\Python27-x64"
+ - PYTHON: "C:\\Python37"
BUILD_JOB_NUM: 2
- - PYTHON: "C:\\Python27-x64"
+ - PYTHON: "C:\\Python37"
BUILD_JOB_NUM: 3
- - PYTHON: "C:\\Python27-x64"
+ - PYTHON: "C:\\Python37"
BUILD_JOB_NUM: 4
- - PYTHON: "C:\\Python35-x64"
- BUILD_JOB_NUM: 1
- - PYTHON: "C:\\Python35-x64"
- BUILD_JOB_NUM: 2
- - PYTHON: "C:\\Python35-x64"
- BUILD_JOB_NUM: 3
- - PYTHON: "C:\\Python35-x64"
- BUILD_JOB_NUM: 4
+ # - PYTHON: "C:\\Python27-x64"
+ # BUILD_JOB_NUM: 1
+ # - PYTHON: "C:\\Python27-x64"
+ # BUILD_JOB_NUM: 2
+ # - PYTHON: "C:\\Python27-x64"
+ # BUILD_JOB_NUM: 3
+ # - PYTHON: "C:\\Python27-x64"
+ # BUILD_JOB_NUM: 4
+
+ # - PYTHON: "C:\\Python35-x64"
+ # BUILD_JOB_NUM: 1
+ # - PYTHON: "C:\\Python35-x64"
+ # BUILD_JOB_NUM: 2
+ # - PYTHON: "C:\\Python35-x64"
+ # BUILD_JOB_NUM: 3
+ # - PYTHON: "C:\\Python35-x64"
+ # BUILD_JOB_NUM: 4
- - PYTHON: "C:\\Python36-x64"
- BUILD_JOB_NUM: 1
- - PYTHON: "C:\\Python36-x64"
- BUILD_JOB_NUM: 2
- - PYTHON: "C:\\Python36-x64"
- BUILD_JOB_NUM: 3
- - PYTHON: "C:\\Python36-x64"
- BUILD_JOB_NUM: 4
+ # - PYTHON: "C:\\Python36-x64"
+ # BUILD_JOB_NUM: 1
+ # - PYTHON: "C:\\Python36-x64"
+ # BUILD_JOB_NUM: 2
+ # - PYTHON: "C:\\Python36-x64"
+ # BUILD_JOB_NUM: 3
+ # - PYTHON: "C:\\Python36-x64"
+ # BUILD_JOB_NUM: 4
build: off
build_script:
diff --git a/.github/issue_template.md b/.github/issue_template.md
new file mode 100644
index 0000000..1d35486
--- /dev/null
+++ b/.github/issue_template.md
@@ -0,0 +1,12 @@
+# Please bring your issue to the SCons users mailing list before filing an issue here
+# See: http://scons.org/bugs.html
+
+# If the issue is confirmed to be a bug please include the following information
+* Link to SCons Users thread discussing your issue.
+* Version of SCons
+* Version of Python
+* Which python distribution if applicable (python.org, cygwin, anaconda, macports, brew,etc)
+* How you installed SCons
+* What Platform are you on? (Linux/Windows and which version)
+* How to reproduce your issue? Please include a small self contained reproducer. Likely a SConstruct should do for most issues.
+* How you invoke scons (The command line you're using "scons --flags some_arguments") \ No newline at end of file
diff --git a/.gitignore b/.gitignore
index ee00281..24917ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ __pycache__/
build/**
bootstrap/**
.idea/
+src/build/**
# Translations
diff --git a/.travis.yml b/.travis.yml
index 2b6049a..ea63e57 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,19 @@
dist: trusty
language: python
+notifications:
+ irc: "chat.freenode.net#scons"
+
+addons:
+ apt:
+ update: true
+
install:
- ./.travis/install.sh
-# python 3 is not fulling passing at this time
-# so allow failure so the coverage stage can be reached with python 2
+# pypy is not passing, but allow failures for coverage stage to be reached
matrix:
allow_failures:
- - python: 3.5
- - python: 3.6
- python: pypy
@@ -17,12 +21,7 @@ jobs:
include:
- &test_job
stage: Test
- script:
- # WORKAROUND: attempt to retry JobTests.py if it fails and then continue if it passes, if it fails ten times
- # then it is a real failure not related to intermittent travis failures
- - n=0; while [[ $n -lt 10 ]]; do python runtest.py src/engine/SCons/JobTests.py && break; n=$((n+1)); done; if [ "$n" -gt "9" ]; then false; fi
- - echo "src/engine/SCons/JobTests.py" > exclude_jobtest
- - python runtest.py -a --exclude-list exclude_jobtest || if [[ $? == 2 ]]; then true; else false; fi
+ script: python runtest.py -a || if [[ $? == 2 ]]; then true; else false; fi
before_script: skip
after_success: skip
python: 2.7
@@ -40,6 +39,13 @@ jobs:
sudo: required
- <<: *test_job
+ python: 3.7
+ env:
+ - PYVER=37
+ sudo: required
+ dist: xenial # required for Python 3.7 (travis-ci/travis-ci#9069)
+
+ - <<: *test_job
python: pypy
env: PYVER=pypy
sudo: required
@@ -74,14 +80,8 @@ jobs:
- echo "parallel = True" >> .coveragerc
- printf "omit =\n\t*Tests.py\n\tsrc/test_*\n\tsrc/setup.py\n\n" >> .coveragerc
- echo "[path] = $PWD" >> .coveragerc
- # Not including this workaround in the coverage report, because it will result
- # in constantly changing coverage reports depending on the number of times
- # the JobTests.py had to run to pass
- # TODO: figure out how to cover JobTests.py
- # - n=0; while [[ $n -lt 10 ]]; do coverage run --rcfile=$PWD/.coveragerc runtest.py src/engine/SCons/JobTests.py && break; n=$((n+1)); done; if [ "$n" -gt "9" ]; then false; fi
- # exclude JobTest.py becuase we already ran that
- - echo "src/engine/SCons/JobTests.py" > exclude_jobtest
- - python runtest.py -l -a --exclude-list exclude_jobtest > all_tests
+ # get a list of all the tests to split them up
+ - python runtest.py -l -a > all_tests
- let "start = ($(wc -l < all_tests) / ${TOTAL_BUILD_JOBS}) * (${BUILD_JOB_NUM} - 1)"; true;
- let "end = ($(wc -l < all_tests) / ${TOTAL_BUILD_JOBS}) * ${BUILD_JOB_NUM}"
- if (( ${BUILD_JOB_NUM} == ${TOTAL_BUILD_JOBS} )); then end=$(wc -l < all_tests); fi
diff --git a/.travis/install.sh b/.travis/install.sh
index 16f7263..6f2cfe2 100755
--- a/.travis/install.sh
+++ b/.travis/install.sh
@@ -1,14 +1,16 @@
#!/usr/bin/env bash
set -x
-# dependencies for clang tests
-sudo apt-get -y install clang
+# setup clang for clang tests using local clang installation
+sudo ln -s /usr/local/clang-5.0.0/bin/clang /usr/bin/clang
+sudo ln -s /usr/local/clang-5.0.0/bin/clang++ /usr/bin/clang++
+
# dependencies for gdc tests
sudo apt-get -y install gdc
# dependencies for docbook tests
sudo apt-get -y install docbook-xml xsltproc libxml2-dev libxslt-dev fop docbook-xsl-doc-pdf
# dependencies for latex tests
-sudo apt-get -y install texlive-full biber texmaker
+sudo apt-get -y install texlive texlive-latex3 biber texmaker ghostscript
# need some things for building dependencies for other tests
sudo apt-get -y install python-pip python-dev build-essential libpcre3-dev autoconf automake libtool bison subversion git
# dependencies for docbook tests continued
@@ -30,4 +32,4 @@ if [[ "$PYVER" == 27 ]]; then
wget https://github.com/swig/swig/archive/rel-3.0.12.tar.gz
tar xzf rel-3.0.12.tar.gz
cd swig-rel-3.0.12 && ./autogen.sh && ./configure --prefix=/usr && make && sudo make install && cd ..
-fi
+fi \ No newline at end of file
diff --git a/HOWTO/README b/HOWTO/README
deleted file mode 100644
index 951c019..0000000
--- a/HOWTO/README
+++ /dev/null
@@ -1,29 +0,0 @@
-__COPYRIGHT__
-
-Here you'll find plain text documentation of how to handle various SCons
-project procedures. Files contained herein:
-
-change.txt
- How changes are integrated, including generating and
- distributing aedist change sets, and updating the CVS repository
- on SourceForge.
-
-new-platform.txt
- Steps to add a new Platform/*.py file. This is probably out
- of date.
-
-new-script.txt
- Steps to add a new script or utility (like scons and sconsign)
- to what we ship.
-
-new-tool.txt
- Steps to add a new Tool/*.py file. This is probably out of date.
-
-release.txt
- Steps to go through when releasing a new version of SCons.
-
-subrelease.txt
- Steps to go through when releasing a new subsidiary version
- of SCons--for example, 0.95.1 after we've released 0.95.
- So far, we've only done this to get some early testing on major
- refactorings.
diff --git a/HOWTO/change.txt b/HOWTO/change.txt
deleted file mode 100644
index f295003..0000000
--- a/HOWTO/change.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-__COPYRIGHT__
-
-Handling a change set:
-
- -- Start the change:
-
- aedb {cnum} [if it's initiated locally]
- aedist -r [if it's a remote submission]
-
- -- Normal development cycle:
-
- aeb
- aet
- aet -bl
- aet -reg [optional]
- aed
- aede
-
- -- As the reviewer:
-
- aerpass {cnum}
-
- -- As the integrator:
-
- aeib {cnum}
- aeb
- aet
- aet -bl
- aet -reg
- aed
- aeipass
-
- -- Distribute the change to scons-aedist:
-
- aedist -s -p scons.0.96 {cnum} > scons.0.96.C{cnum}.ae
- pine -attach scons.0.96.C{cnum}.ae scons-aedist@lists.sourceforge.net
- Subject: scons.0.96 - {SUMMARY}
- Body: aegis -l -p scons.0.96 -c {cnum} cd
-
- rm scons.0.96.C{cnum}.ae
-
- [This will eventually be automated.]
-
- -- Update the aedist baseline on the web site:
-
- aedist -s -bl -p scons.0.96 > scons.0.96.ae
- scp scons.0.96.ae stevenknight@scons.sourceforge.net:/home/groups/s/sc/scons/htdocs/scons.0.96.ae
- rm scons.0.96.ae
-
- [This will eventually be automated.]
-
- -- Distribute the change to CVS:
-
- export CVS_RSH=ssh
- ae2cvs -n -aegis -p scons.0.96 -c {cnum} -u ~/SCons/scons
- ae2cvs -X -aegis -p scons.0.96 -c {cnum} -u ~/SCons/scons
-
- If you need the "ae2cvs" Perl script, you can find a copy
- checked in to the bin/subdirectory.
-
- [This may eventually be automated.]
diff --git a/HOWTO/new-platform.txt b/HOWTO/new-platform.txt
deleted file mode 100644
index 8aa11ec..0000000
--- a/HOWTO/new-platform.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-__COPYRIGHT__
-
-Adding a new Platform to the SCons distribution:
-
- -- Add the following files (aenf):
-
- src/engine/SCons/Platform/xxx.py
-
- Use one of the other Platform files as a template.
-
- The tool_list() function should return the list of tools
- that will be available through the default construction
- Environment.
-
- The generate() function should set construction variables:
-
- ENV
- OBJPREFIX
- OBJSUFFIX
- PROGPREFIX
- PROGSUFFIX
- LIBPREFIX
- LIBSUFFIX
- SHLIBPREFIX
- SHLIBSUFFIX
- LIBPREFIXES
- LIBSUFFIXES
-
- -- Modify the following files (aecp):
-
- doc/man/scons.1
-
- Add the new platform to the example of the platform
- keyword when instantiating an Environment.
-
- Add the list of default tools returned by tool_list()
- for this platform.
-
- rpm/scons.spec
-
- Add to the list at the bottom of the file:
-
- /usr/lib/scons/SCons/Platform/xxx.py
- /usr/lib/scons/SCons/Platform/xxx.pyc
-
- [THIS LIST SHOULD BE GENERATED FROM MANIFEST.in,
- AND WILL BE SOME DAY.]
-
- src/CHANGES.txt
-
- Add mention of the new Platform specification.
-
- src/engine/MANIFEST.in
-
- Add to the list:
-
- SCons/Platform/xxx.py
-
- src/engine/SCons/Platform/Platform/PlatformTests.py
-
- Copy and paste one of the other platform tests to verify
- the ability to initialize an environment through a call
- to the object returned by Platform('xxx')
-
- src/engine/SCons/Platform/__init__.py
-
- Add logic to platform_default() (if necessary) to return
- the appropriate platform string.
-
- test/Platform.py
-
- Add the new platform to the SConstruct and SConscript
- files. Add the expected output to the "expect"
- variable.
diff --git a/HOWTO/new-script.txt b/HOWTO/new-script.txt
deleted file mode 100644
index f859c48..0000000
--- a/HOWTO/new-script.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-__COPYRIGHT__
-
-Steps for adding a new script/utility to the SCons packages. Assume
-that you're creating a new man page, too. In the template steps
-below, "newscript" is the name of the new script/utility being added.
-
- New files:
-
- doc/man/newscript.1
-
- New man page; use an existing one as a template.
-
- src/script/newscript.py
-
- The new script itself.
-
- test/*.py
-
- Appropriate tests for the new script.
-
- Modified files:
-
- SConstruct
-
- In the "scons_script" package description:
-
- Add "newscript" : "newscript.py" to the "filemap"
- dictionary.
-
- In the "scons" package description:
-
- Add "newscript.1" to the "files" list.
-
- Add "newscript.1" : "../doc/man/newscript.1" to the
- "filemap" dictionary.
-
- Add "newscript" to the scripts[] list
-
- debian/rules
-
- Add:
-
- rm -f debian/scons/usr/bin/newscript
- cp build/scripts/newscript debian/scons/user/bin/newscript
- sed '1s|.*|#!/usr/bin/python2.1|' build/scripts/newscript > debian/scons/user/bin/newscript
- chmod +x debian/scons/user/bin/newscript
-
- rm -f debian/scons/usr/share/man/man1/newscript.1
- cp newscript.1 debian/scons/user/share/man/man1/
-
- doc/SConscript
-
- Add "newscript" to man_page_list[]
-
- gentoo/scons.ebuild.in
-
- Add "doman newscript.1"
-
- rpm/scons.spec.in
-
- Add "gzip -c newscript.1" > $RPM_BUILD_ROOT/usr/man/man1/newscript.1.gz
-
- Add "%doc /usr/man/man1/newscript.1.gz"
-
- src/CHANGES.txt
-
- Document the addition of the new script.
-
- src/script/MANIFEST.in
-
- Add a line: "newscript"
-
- src/setup.py
-
- Add "script/newscript" to the 'scripts' list.
diff --git a/HOWTO/new-tool.txt b/HOWTO/new-tool.txt
deleted file mode 100644
index 4297fe6..0000000
--- a/HOWTO/new-tool.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-__COPYRIGHT__
-
-Adding a new Tool to the SCons distribution:
-
- -- Add the following files (aenf):
-
- src/engine/SCons/Tool/xxx.py
-
- Use one of the other Tool files as a template.
-
- The tool should set and use construction variables:
-
- XXX (specific tool)
- XXXCOM (the command line)
- XXXFLAGS (flags for the command line)
-
- -- Modify the following files (aecp):
-
- doc/man/scons.1
-
- Add the new tool to the default Platform lists
- (if appropriate).
-
- If this creates object files from a new source
- file type, add the new file suffixes.
-
- Document the new construction variables.
-
- rpm/scons.spec
-
- Add to the list at the bottom of the file:
-
- /usr/lib/scons/SCons/Tool/xxx.py
- /usr/lib/scons/SCons/Tool/xxx.pyc
-
- [THIS LIST SHOULD BE GENERATED FROM MANIFEST.in,
- AND WILL BE SOME DAY.]
-
- src/CHANGES.txt
-
- Add mention of the new Tool specification.
-
- src/engine/MANIFEST.in
-
- Add to the list:
-
- SCons/Tool/xxx.py
-
- src/engine/SCons/Defaults.py
-
- If there are any new Actions for the Tool, add them
- here.
-
- src/engine/SCons/Platform/*.py
-
- Add the Tool to the list(s) returned by tool_list().
-
- -- Add the following tests (aent):
-
- test/XXX.py
-
- Use one of the other tests as a template.
-
- The first part should be a platform-independent test
- using dummy 'myxxx.py' utilities to test if $XXX is set.
-
- Remaining parts of the test can check to see if the
- specific tool is installed on the system, and test
- actually executing the tool.
-
- test/XXXFLAGS.py
-
- Use one of the other tests as a template.
-
- The first part should be a platform-independent test
- using dummy 'myxxx.py' utilities to test if $XXXFLAGS is
- set.
-
- Optionally, remaining parts of the test can check to see
- if the specific tool is installed on the system, and
- test actually executing the tool.
diff --git a/HOWTO/release.txt b/HOWTO/release.txt
deleted file mode 100644
index 5fbbfc7..0000000
--- a/HOWTO/release.txt
+++ /dev/null
@@ -1,656 +0,0 @@
-__COPYRIGHT__
-
-This document covers how to prepare major releases of SCons--that is,
-releases numbered with X.Y format, such as 0.93, 1.0, etc.
-
-If you need to prepare a specific subrelease (X.Y.Z, such as 0.94.1),
-then see the document HOWTO/subrelease.txt.
-
-Things to do to release a new X.Y version of SCons:
-
- Prepare the describe-the-release section for the announcements
-
- summarize changes from src/CHANGES.txt
-
- template is below, search for "describe-the-release"
-
- send this out for review while you get the rest of the
- release ready!
-
- Build and test candidate packages
-
- test on Linux
-
- test on Windows NT
-
- 1) tar zxf scons-src-{version}.tar.gz
- cd scons-src-{version}
- python runtest.py -a
-
- 2) tar zxf scons-{version}.tar.gz
- cd scons-{version}
- python setup.py install
- cd scons-src-{version}
- python runtest.py -a -X -x C:\Python20\scons.bat
-
- 3) scons-{verson}.win32.exe
- cd scons-src-{version}
- python runtest.py -a -X -x C:\Python20\scons.bat
-
- 4) mkdir temporary_directory
- cd temporary_directory
- tar zxf scons-local-{version}.tar.gz
- cd scons-src-{version}
- python runtest.py -a -x C:\temporary_directory\scons.py
-
- Check in any changes necessary to make everything work
-
- Update the user's guide
-
- sh bin/docdiff
-
- sh bin/docupdate
-
- END THE CURRENT DEVELOPMENT BRANCH
-
- ae_p scons.0
-
- aede {96}
-
- aerpass {96}
-
- aeib {96}
-
- aed
-
- aeb
-
- aet
-
- aet -reg
-
- aeipass
-
- START THE NEW BRANCH FOR RELEASE
-
- aenbr -p scons.0 {97}
-
- aenc -p scons.0.{97}
-
- Call it something like,
- "Initialize the new branch for release."
- Cause = internal_enhancement.
- Exempt it from all tests (*_exempt = true).
-
- ae_p scons.0.{97}
-
- aedb 100
-
- aecd
-
- # Change the hard-coded package version numbers
- # in the following files.
- aecp README
- vi README
-
- aecp SConstruct
- vi SConstruct
-
- aecp QMTest/TestSCons.py
- vi QMTest/TestSCons.py
-
- # Read through and update the README files if necessary
- [optional] aecp README
- [optional] vi README
-
- [optional] aecp src/README.txt
- [optional] vi src/README.txt
-
- # Prepare src/CHANGES.txt
- aecp src/CHANGES.txt
- vi src/CHANGES.txt
-
- date -R the latest release
-
- should be current if this has been updated
- as each change went in.
-
- # Prepare src/RELEASE.txt
- aecp src/RELEASE.txt
- vi src/RELEASE.txt
-
- date -R the latest release
-
- Read through and edit appropriately.
-
- Can probably keep most of the existing text
-
- Add any new known problems
-
- # Prepare debian/changelog
- aecp debian/changelog
- vi debian/changelog
-
- date -R the latest release
-
- # Now build and prepare the release itself.
- aeb
-
- aed
-
- aet -reg
-
- aede
-
- etc.
-
-
-
- Read through the FAQ for any updates
-
-
-
- Upload the packages to the SourceForge incoming FTP:
-
- ftp upload.sourceforge.net
- anonymous
- <your email>
- cd incoming
- bin
- put scons-0.{97}-1.noarch.rpm
- put scons-0.{97}-1.src.rpm
- put scons-0.{97}.tar.gz
- put scons-0.{97}.win32.exe
- put scons-0.{97}.zip
- put scons-local-0.{97}.tar.gz
- put scons-local-0.{97}.zip
- put scons-src-0.{97}.tar.gz
- put scons-src-0.{97}.zip
- put scons_0.{97}-1_all.deb
-
- Create the new release at the SourceForge project page:
-
- Pull down the "Admin" menu and select "File Releases"
-
- Package Name: scons
-
- => Add Release
-
- New release name: 0.{97}
-
- Upload the RELEASE.txt file.
-
- Upload the CHANGES.txt file.
-
- Check the "Preserve my pre-formatted text." box (IMPORTANT!)
-
- Click "Submit/Refresh" (IMPORTANT!)
-
- Check the SCons files you uploaded
-
- Click "Add Files and/or Refresh View"
-
- Edit the file info:
-
- scons-0.{97}-1.noarch.rpm Any .rpm
- scons-0.{97}-1.src.rpm Any Source .rpm
- scons-0.{97}.tar.gz Any .gz
- scons-0.{97}.win32.exe i386 .exe (32-bit Windows)
- scons-0.{97}.zip Any .zip
- scons_0.{97}-1_all.deb Any .deb
-
- Click "Update/Refresh" for each file; this must be done
- one at a time.
-
- Check "I'm sure." and click "Send Notice" in the Email
- Release Notice section.
-
-
- Pull down the "Admin" menu and select "File Releases"
-
- Package Name: scons-local
-
- => Add Release
-
- New release name: 0.{97}
-
- Upload the RELEASE.txt file.
-
- Upload the CHANGES.txt file.
-
- Check the "Preserve my pre-formatted text." box (IMPORTANT!)
-
- Click "Submit/Refresh" (IMPORTANT!)
-
- Check the SCons files you uploaded
-
- Click "Add Files and/or Refresh View"
-
- Edit the file info:
-
- scons-local-0.{97}.tar.gz Any .gz
- scons-local-0.{97}.zip Any .zip
-
- Click "Update/Refresh" for each file; this must be done
- one at a time.
-
- Check "I'm sure." and click "Send Notice" in the Email
- Release Notice section.
-
-
- Pull down the "Admin" menu and select "File Releases"
-
- Package Name: scons-src
-
- => Add Release
-
- New release name: 0.{97}
-
- Upload the RELEASE.txt file.
-
- Upload the CHANGES.txt file.
-
- Check the "Preserve my pre-formatted text." box (IMPORTANT!)
-
- Click "Submit/Refresh" (IMPORTANT!)
-
- Check the SCons files you uploaded
-
- Click "Add Files and/or Refresh View"
-
- Edit the file info:
-
- scons-src-0.{97}.tar.gz Any .gz
- scons-src-0.{97}.zip Any .zip
-
- Click "Update/Refresh" for each file; this must be done
- one at a time.
-
- Check "I'm sure." and click "Send Notice" in the Email
- Release Notice section.
-
-
- Hide release 0.{95} at the SourceForge download page:
-
- Pull down the "Admin" menu and select "File Releases"
-
- Package Name: scons
-
- => Edit Releases
-
- Release Name: 0.{95}
-
- => Edit This Release
-
- Status: => Hidden
-
- Click Submit/Refresh
-
-
- Pull down the "Admin" menu and select "File Releases"
-
- Package Name: scons-local
-
- => Edit Releases
-
- Release Name: 0.{95}
-
- => Edit This Release
-
- Status: => Hidden
-
- Click Submit/Refresh
-
-
- Pull down the "Admin" menu and select "File Releases"
-
- Package Name: scons-src
-
- => Edit Releases
-
- Release Name: 0.{95}
-
- => Edit This Release
-
- Status: => Hidden
-
- Click Submit/Refresh
-
-
-
- Add a new release for 0.{97} in the Issue Tracker at tigris.org:
-
- Click "Issue Tracker" on the left-hand nav bar
-
- Click "Configuration options"
-
- Click "Add/edit components"
-
- Under "scons"
- To the right of "Add ..."
- Click "Version"
-
- At the bottom of the list click "Add"
-
- Fill in the "Version:" box with 0.{97}
-
- Check "Add this version to *all* components."
-
- Click the "Add" button
-
-
-
- Update the scons.org web site:
-
- svn co http://scons.tigris.org/svn/scons/scons.org
-
- cd scons.org
-
- CHANGES.txt: copy new version from built source tree
-
- download.php: new version number
-
- includes/templates.php:
- update $latestrelease
-
- includes/versions.php:
- update $stablerelease and/or $latestrelease
- add new version number to $docversions[],
- IMPORTANT: SHIFT $docversions[] INDEX NUMBERS :-(
-
- index.php: announcement on the home page
- remove out-of-date announcements
-
- news-raw.xhtml: add announcement to list (dup from home page)
-
- RELEASE.txt: copy new version from built source tree
-
- mkdir doc/0.{97}
-
- (cd doc/0.{97} && tar zxf scons-doc-0.{97}.tar.gz)
-
- svn add doc/0.{97}
-
- svn commit
-
- ssh -l scons manam.pair.com
-
- cd public_html
-
- mkdir new
-
- svn co http://scons.tigris.org/svn/scons/scons.org new
-
- mv production previous && mv new production
-
- [point your browser to http://www.scons.org/]
-
-
- Update the project pages at tigris.org:
-
- svn co http://scons.tigris.org/svn/scons/trunk
-
- cd trunk
-
- www/project_highlights.html
-
- www/roadmap.html
-
- svn commit
-
-
-
-
- Test downloading from the SourceForge project page
-
- You may need to wait a good bit; they seem to update
- this on half-hour cycles.
-
-
- Test downloading from the web site download page
-
-
-
- Add news item to the SourceForge project page
-
- Pull down "Project => News"
-
- Click "Submit"
-
- Fill in the "Subject:" box
-
- Cut-and-paste the announcement text into the "Details:" box
-
- Click "submit"
-
-
-
- Add news item to the tigris.org project page
-
- Click "Announcements"
-
- Click "Add new announcement"
-
- Double-check the date (probably already set)
-
- Fill in the "Headline" box
-
- Fill in the "Body" box (probably short)
-
- Click "Add new announcement"
-
-
-
- Announce to the following mailing lists (template below):
-
- scons-announce@lists.sourceforge.net
- scons-users@lists.sourceforge.net
- scons-devel@lists.sourceforge.net
-
- [right away]
-
- python-announce@python.org
-
- [right away, it's moderated and will take
- some time to get through]
-
- linux-announce@news.ornl.gov
-
- [right away, it's moderated and will take
- some time to get through]
-
- [optional] cons-discuss@gnu.org
-
- [only if it's a really big announcement,
- I said we wouldn't bug this list]
-
- python-list@python.org
-
- [wait until business hours so the announcement
- hits mailboxes while U.S. workers are active]
-
- Notify Gentoo Linux of the update
-
- For now, we will do this by entering a bug report, and
- attaching the files in build/gentoo to the report. Go
- to:
-
- http://bugs.gentoo.org/
-
- This requires an account (based on your email address)
- and a certain amount of Bugzilla-based navigation,
- but nothing that's too difficult.
-
- This is just my best stab at a process that will work
- for Gentoo. This process may change if the Gentoo
- developers come back and want something submitted in
- some other form.
-
- Notify www.cmtoday.com/contribute.html
-
- [This guy wants an announcement no more frequently than
- once a month, so save it for a future release if it's
- been too soon since the previous one.]
-
- Notify freshmeat.net
-
- [Wait until the morning so the announcement hits the
- main freshmeat.net page while people in the U.S. are
- awake and working]
-
-
-
- Checkin another change to prepare for development on this branch.
-
- # Prep the following files to track the changes
- # made during the next development cycle
- aecp src/CHANGES.txt src/RELEASE.txt
- vi src/CHANGES.txt src/RELEASE.txt
-
- # Optionally, update release numbers in the following:
- [optional] aecp HOWTO/change.txt
- [optional] vi HOWTO/change.txt
-
- [optional] aecp HOWTO/release.txt
- [optional] vi HOWTO/release.txt
-
-
-
-
-=======================
-Template describe-the-release section:
-
-IMPORTANT: Release 0.95 contains the following interface changes:
-
- - XXX
-
- See the release notes for more information about these changes.
-
-This release adds the following features:
-
- - XXX
-
-This release enhances the following existing features:
-
- - XXX
-
-The following fixes have been added:
-
- - XXX
-
-Performance has been improved as follows:
-
- - XXX
-
-The following changes have been made to the SCons packaging:
-
- - XXX
-
-The documentation has been improved:
-
- - XXX
-=======================
-Template scons-devel announcement:
-
-SConspirators--
-
-SCons beta release 0.95 is now available for download.
-
-XXX Template describe-the-release section goes here XXX
-
-Special thanks to XXX, XXX, and XXX for their contributions to this
-release.
-
- --SK
-=======================
-Template scons-users + scons-announce announcement:
-
-Version 0.95 of SCons has been released and is available for download
-from the SCons web site:
-
- http://www.scons.org/
-
-Or through the download link at the SCons project page at SourceForge:
-
- http://sourceforge.net/projects/scons/
-
-RPM and Debian packages and a Win32 installer are all available, in
-addition to the traditional .tar.gz and .zip files.
-
-
-WHAT'S NEW IN THIS RELEASE?
-
-XXX Template describe-the-release section goes here XXX
-
-
-ACKNOWLEDGEMENTS
-
-Special thanks to XXX, XXX, and XXX for their contributions to this
-release.
-
-On behalf of the SCons team,
-
- --SK
-=======================
-Template python-announce, linux-announce and python-list announcement:
-
-SCons is a software construction tool (build tool, or make tool) written
-in Python. It is based on the design which won the Software Carpentry
-build tool competition in August 2000.
-
-Version 0.95 of SCons has been released and is available for download
-from the SCons web site:
-
- http://www.scons.org/
-
-Or through the download link at the SCons project page at SourceForge:
-
- http://sourceforge.net/projects/scons/
-
-RPM and Debian packages and a Win32 installer are all available, in
-addition to the traditional .tar.gz and .zip files.
-
-
-WHAT'S NEW IN THIS RELEASE?
-
-XXX Template describe-the-release section goes here XXX
-
-
-ABOUT SCONS
-
-Distinctive features of SCons include:
-
- - a global view of all dependencies; no multiple passes to get
- everything built properly
- - configuration files are Python scripts, allowing the full use of a
- real scripting language to solve difficult build problems
- - a modular architecture allows the SCons Build Engine to be
- embedded in other Python software
- - the ability to scan files for implicit dependencies (#include files);
- - improved parallel build (-j) support that provides consistent
- build speedup regardless of source tree layout
- - use of MD5 signatures to decide if a file has really changed; no
- need to "touch" files to fool make that something is up-to-date
- - easily extensible through user-defined Builder and Scanner objects
- - build actions can be Python code, as well as external commands
-
-An scons-users mailing list is available for those interested in getting
-started using SCons. You can subscribe at:
-
- http://lists.sourceforge.net/lists/listinfo/scons-users
-
-Alternatively, we invite you to subscribe to the low-volume
-scons-announce mailing list to receive notification when new versions of
-SCons become available:
-
- http://lists.sourceforge.net/lists/listinfo/scons-announce
-
-
-ACKNOWLEDGEMENTS
-
-Special thanks to XXX, XXX, and XXX for their contributions to this
-release.
-
-On behalf of the SCons team,
-
- --SK
diff --git a/HOWTO/subrelease.txt b/HOWTO/subrelease.txt
deleted file mode 100644
index 06b757a..0000000
--- a/HOWTO/subrelease.txt
+++ /dev/null
@@ -1,114 +0,0 @@
-__COPYRIGHT__
-
-This document covers how to prepare subreleases of SCons--that is,
-releases numbered with X.Y.Z format, such as 0.94.1, 1.0.1, etc.
-
-If you need to prepare a release (X.Y, such as 0.93, 1.0, etc.), then
-see the document HOWTO/release.txt.
-
-Things to do to release a new X.Y.Z version of SCons:
-
- BEFORE STARTING THE SUB-BRANCH:
-
- Update the user's guide on the parent
-
- sh bin/docdiff
-
- sh bin/docupdate
-
- START THE NEW SUB-BRANCH FOR SUBRELEASE
-
- aenbr -p scons.0.{94} {1}
-
- aenc -p scons.0.{94}.{1}
-
- Call it something like,
- "Prepare a new sub-release for XYZ."
- Cause = internal_enhancement.
- Exempt it from all tests (*_exempt = true).
-
- ae_p scons.0.{94}.{1}
-
- aedb 100
-
- aecd
-
- # Change the hard-coded package version numbers
- # in the following files.
- aecp README
- vi README
-
- aecp SConstruct
- vi SConstruct
-
- aecp QMTest/TestSCons.py
- vi QMTest/TestSCons.py
-
- # Read through and update the README files if necessary
- [optional] aecp README
- [optional] vi README
-
- [optional] aecp src/README.txt
- [optional] vi src/README.txt
-
- # Prepare src/CHANGES.txt
- aecp src/CHANGES.txt
- vi src/CHANGES.txt
-
- change the release line to reflect
- the new subrelease
-
- date -R the new subrelease
-
- add an explanatory not after the subrelease line:
-
- NOTE: This is a pre-release of 0.{95}
- for testing purposes. When 0.{95} is
- released, all these changes will show
- up as 0.95 changes.
-
- # Prepare src/RELEASE.txt
- aecp src/RELEASE.txt
- vi src/RELEASE.txt
-
- date -R the release only if necessary
-
- Read through and edit appropriately.
-
- Can probably keep most of the existing text
-
- Add any new known problems
-
- # Prepare debian/changelog
- aecp debian/changelog
- vi debian/changelog
-
- add the new subrelease
-
- date -R the new subrelease
-
- # Now build and prepare the release itself.
- aeb
-
- aet -reg
-
- aed
-
- aede
-
- etc.
-
-
-
- Make the relevant packages available for by-hand pickup directly
- off the web site:
-
- scp scons-0.{94}.{1}.tar.gz stevenknight@scons.sourceforge.net:/home/groups/s/sc/scons/htdocs
- scp scons-0.{94}.{1}.zip stevenknight@scons.sourceforge.net:/home/groups/s/sc/scons/htdocs
-
-
- Test downloading from the web site.
-
-
-
- Announce to scons-dev@scons.org
diff --git a/QMTest/test-framework.rst b/QMTest/test-framework.rst
deleted file mode 100644
index 844d99b..0000000
--- a/QMTest/test-framework.rst
+++ /dev/null
@@ -1,430 +0,0 @@
-=======================
-SCons Testing Framework
-=======================
-
-SCons uses extensive automated tests to try to ensure quality. The primary goal
-is that users should be able to upgrade from version to version without any surprise
-changes in behavior.
-
-In general, no change goes into SCons unless it has one or more new or modified
-tests that demonstrably exercise the bug being fixed or the feature being added.
-There are exceptions to this guideline, but they should be just that, ''exceptions''.
-When in doubt, make sure it's tested.
-
-Test Organization
-=================
-
-There are three types of SCons tests:
-
-*End-to-End Tests*
- End-to-end tests of SCons are all Python scripts (``*.py``) underneath
- the ``test/`` subdirectory. They use the test infrastructure modules in the
- ``QMTest`` subdirectory.
-
-*Unit Tests*
- Unit tests for individual SCons modules live underneath the
- ``src/engine/`` subdirectory and are the same base name as the module
- with ``Tests.py`` appended--for example, the unit tests for the
- ``Builder.py`` module are in the ``BuilderTests.py`` script.
-
-*External Tests*
- For the support of external Tools (in the form of packages, preferably), the
- testing framework got extended, such that it can run in standalone mode.
- You can start it from the top-level folder of your Tool's source tree,
- where it then finds all Python scripts (``*.py``) underneath the
- local ``test/`` directory.
- This implies that Tool tests have to be kept in a folder named ``test``,
- like for the SCons core.
-
-
-Contrasting End-to-End and Unit Tests
-#####################################
-
-In general, anything that we've put into an end-to-end test script should
-be considered a hardened part of the interface (that is, it's something
-that a user might do) and should not be broken. Unit tests are now
-considered more malleable, more for testing internal interfaces that
-can change so long as we don't break users' ``SConscript`` files. (This
-wasn't always the case, and there's a lot of meaty code in many of the
-unit test scripts that does, in fact, capture external interface
-behavior. In general, we should try to move those things to end-to-end
-scripts as we find them.)
-
-It's more difficult to debug end-to-end tests. You can actually go
-straight into the Python debugger on the unit test scripts by using the
-``runtest.py --pdb`` option, but the end-to-end tests treat an SCons
-invocation as a "black box" and just look for external effects.
-Simple ``print`` statements within the SCons code itself often don't help
-debug end-to-end because they end up in SCons output that gets compared
-against expected output and cause a test failure. Probably the most
-effective technique is to use the internal ``SCons.Debug.Trace()`` function,
-which prints output to ``/dev/tty`` on Linux/UNIX systems and ``con`` on
-Windows systems, so you can see what's going on.
-
-Naming conventions
-##################
-
-The end-to-end tests, more or less, stick to the following naming conventions:
-
-1. All tests end with a .py suffix.
-
-2. In the *General* form we use
-
- ``Feature.py``
- for the test of a specified feature; try to
- keep this description reasonably short
-
- ``Feature-x.py``
- for the test of a specified feature using
- option ``x``
-
-3. The *command line option* tests take the form
-
- ``option-x.py``
- for a lower-case single-letter option
-
- ``option--X.py``
- upper-case single-letter option
- (with an extra hyphen, so the file names will
- be unique on case-insensitive systems)
-
- ``option--lo.py``
- long option; abbreviate the long
- option name to a few characters
-
-
-Running Tests
-=============
-
-The standard set of SCons tests are run from the top-level source directory
-by the ``runtest.py`` script.
-There is a ``--qmtest`` option that checks whether the ``QMTest`` package
-is installed on your system. If it can be found, then the ``runtest.py`` script
-will use it to carry out the tests.
-
-Help is available through the ``-h`` option:
-
-::
-
- $ python runtest.py -h
-
-To simply run all the tests, use the ``-a`` option:
-
-::
-
- $ python runtest.py -a
-
-By default, ``runtest.py`` prints a count and percentage message for each test
-case, along with the name of the test file.
-If you need the output to be more silent, have a look at the ``-q``, ``-s`` and
-``-k`` options.
-
-You may specifically list one or more tests to be run:
-
-::
-
- $ python runtest.py src/engine/SCons/BuilderTests.py
- $ python runtest.py test/option-j.py test/Program.py
-
-Folder names are allowed arguments as well, so you can do a
-
-::
-
- $ python runtest.py test/SWIG
-
-to run all SWIG tests only.
-
-You can also use the ``-f`` option to execute just the tests listed in a specified
-text file:
-
-::
-
- $ cat testlist.txt
- test/option-j.py
- test/Program.py
- $ python runtest.py -f testlist.txt
-
-
-One test must be listed per line, and any lines that begin with '#'
-will be ignored (the intent being to allow you, for example,
-to comment out tests that
-are currently passing and then uncomment all of the tests in the file
-for a final validation run).
-
-If more than one test is run, the ``runtest.py`` script prints a summary
-of how many tests passed, failed, or yielded no result, and lists any
-unsuccessful tests.
-
-The above invocations all test directly the files underneath the ``src/``
-subdirectory, and do not require that a packaging build be performed first.
-The ``runtest.py`` script supports additional options to run tests against
-unpacked packages in the ``build/test-*/`` subdirectories.
-
-If you are testing a separate Tool outside of the SCons source tree, you have
-to call the ``runtest.py`` script in *external* (stand-alone) mode::
-
- $ python ~/scons/runtest.py -e -a
-
-. This ensures that the testing framework doesn't try to access SCons classes
-needed for some of the *internal* test cases.
-
-Note, that the actual tests are carried out in a temporary folder each, which gets
-deleted afterwards. This ensures that your source directories don't get clobbered
-with temporary files from the test runs. It also means that you can't simply change
-into a folder to "debug things" after a test has gone wrong. For a way around this,
-check out the ``PRESERVE`` environment variable. It can be seen in action in
-`How to convert old tests`_ below.
-
-Not Running Tests
-=================
-
-If you simply want to check which tests would get executed, you can call the
-``runtest.py`` script with the ``-l`` option::
-
- $ python runtest.py -l
-
-Then there is also the ``-n`` option, which prints the command line for each
-single test, but doesn't actually execute them::
-
- $ python runtest.py -n
-
-Finding Tests
-=============
-
-When started in *standard* mode
-
-::
-
- $ python runtest.py -a
-
-
-, ``runtest.py`` assumes that it is run from the SCons top-level source directory.
-It then dives into the ``src`` and ``test`` folders, where it tries to find filenames
-
- ``*Test.py``
- for the ``src`` directory, and
-
- ``*.py``
- for the ``test`` folder.
-
-When using fixtures, you may quickly end up in a position where you have supporting
-Python script files in a subfolder, but they shouldn't get picked up as test scripts.
-In this case you have two options:
-
-1. Add a file with the name ``sconstest.skip`` to your subfolder. This lets
- ``runtest.py`` skip the contents of the directory completely.
-2. Create a file ``.exclude_tests`` in each folder in question, and in it list
- line-by-line the files to get excluded from testing.
-
-The same rules apply when testing external Tools by using the ``-e`` option.
-
-
-"Hello, world!" SCons Test Script
-=================================
-
-To illustrate how the end-to-end test scripts work,
-let's walk through a simple "Hello, world!" example:
-
-::
-
- #!python
- import TestSCons
-
- test = TestSCons.TestSCons()
-
- test.write('SConstruct', """\
- Program('hello.c')
- """)
-
- test.write('hello.c', """\
- int
- main(int argc, char *argv[])
- {
- printf("Hello, world!\\n");
- exit (0);
- }
- """)
-
- test.run()
-
- test.run(program='./hello', stdout="Hello, world!\n")
-
- test.pass_test()
-
-
-``import TestSCons``
- Imports the main infrastructure for writing SCons tests. This is normally the only part of the infrastructure that needs importing. Sometimes other Python modules are necessary or helpful, and get imported before this line.
-
-``test = TestSCons.TestSCons()``
- This initializes an object for testing. A fair amount happens under the covers when the object is created, including:
-
- * A temporary directory is created for all the in-line files that will get created.
- * The temporary directory's removal is arranged for when the test is finished.
- * We ``os.chdir()`` to the temporary directory.
-
-``test.write('SConstruct', ...``
- This line creates an ``SConstruct`` file in the temporary directory, to be used as input to the ``scons`` run(s) that we're testing. Note the use of the Python triple-quote syntax for the contents of the ``SConstruct`` file. Because input files for tests are all created from in-line data like this, the tests can sometimes get a little confusing to read, because some of the Python code is found
-
-``test.write('hello.c', ...``
- This lines creates an ``hello.c`` file in the temporary directory. Note that we have to escape the ``\\n`` in the ``"Hello, world!\\n"`` string so that it ends up as a single backslash in the ``hello.c`` file on disk.
-
-``test.run()``
- This actually runs SCons. Like the object initialization, things happen under the covers:
-
- * The exit status is verified; the test exits with a failure if the exit status is not zero.
- * The error output is examined, and the test exits with a failure if there is any
-
-``test.run(program='./hello', stdout="Hello, world!\n")``
- This shows use of the ``TestSCons.run()`` method to execute a program other than ``scons``, in this case the ``hello`` program we just presumably built. The ``stdout=`` keyword argument also tells the ``TestSCons.run()`` method to fail if the program output does not match the expected string ``"Hello, world!\n"``. Like the previous ``test.run()`` line, it will also fail the test if the exit status is non-zero, or there is any error output.
-
-``test.pass_test()``
- This is always the last line in a test script. It prints ``PASSED`` on the screen and makes sure we exit with a ``0`` status to indicate the test passed. As a side effect of destroying the ``test`` object, the created temporary directory will be removed.
-
-Working with fixtures
-=====================
-
-In the simple example above, we have seen how to create files in the temporary test directory.
-We give a filename to the ``TestSCons.write()`` method, together with its contents, and it gets
-written to the test folder right before its start.
-
-This technique can still be seen throughout most of the end-to-end tests, but there is a better
-way. It's much easier to edit, create and maintain real files, instead of copy/pasting
-content to/from a Python script. If the test files get longer, the test script
-gets longer and is harder to read.
-
-Against this, we now have the possibility to copy single files or the contents of a
-local folder to the test directory. Since we can reuse these files/folders to setup
-several tests, we call them *fixtures* in the following.
-
-Directory fixtures
-##################
-
-The function ``dir_fixture(self, srcdir, dstdir=None)`` in the ``TestCmd`` class
-copies the contents of the specified folder ``srcdir`` from
-the directory of the called test script, to the current
-temporary test directory.
-The ``srcdir`` name may be a list, in which case the elements are
-concatenated with the ``os.path.join()`` method. The ``dstdir`` is
-assumed to be under the temporary working directory, it gets
-created automatically, if it does not already exist.
-
-A short syntax example::
-
- test = TestSCons.TestSCons()
- test.dir_fixture('image')
- test.run()
-
-would copy all files and subfolders from the local ``image`` folder, to
-the temporary directory for the current test.
-
-If you'd like to see a real example for this in action, refer to the test
-named ``test/packaging/convenience-functions/convenience-functions.py``.
-
-File fixtures
-#############
-
-Like for directory fixtures, ``file_fixture(self, srcfile, dstfile=None)``
-copies the file ``srcfile`` from the directory of
-the called script, to the temporary test directory.
-The ``dstfile`` is assumed to be under the temporary working
-directory, unless it is an absolute path name.
-If ``dstfile`` is specified, its target directory gets created
-automatically if it doesn't already exist.
-
-With a::
-
- test = TestSCons.TestSCons()
- test.file_fixture('SConstruct')
- test.file_fixture(['src','main.cpp'],['src','main.cpp'])
- test.run()
-
-you would copy the files ``SConstruct`` and ``src/main.cpp`` to the temporary
-test folder, prior to running the test itself.
-
-Again, a reference example can be found in the current *default* revision of
-SCons, it is ``test/packaging/sandbox-test/sandbox-test.py``.
-
-For even more examples you should check out one of the external Tools, e.g. the
-*Qt4* Tool at https://bitbucket.org/dirkbaechle/scons_qt4. Also visit the SCons
-Tools Index at http://www.scons.org/wiki/ToolsIndex for a complete
-list of available Tools, though not all may have tests yet.
-
-How to convert old tests
-########################
-
-We now show how to convert a test, still using the ``TestSCons.write()`` method, to
-the fixture based approach. For this, we need to get at the files as they
-are written to each temporary test folder.
-
-Luckily, ``runtest.py`` checks for the existence of an environment variable named
-``PRESERVE``. If it is set to a non-zero value, the testing framework doesn't delete
-the test folder as ususal, but prints its name to the screen.
-
-So, you should be able to give the commands
-
-::
-
- $ export PRESERVE=1
- $ python runtest.py test/packaging/sandbox-test.py
-
-, assuming Linux and a bash-like shell.
-
-The output should then look something like this::
-
- 1/1 (100.00%) /usr/bin/python -tt test/packaging/sandbox-test.py
- PASSED
- Preserved directory /tmp/testcmd.4060.twlYNI
-
-and you see that the test files have been kept in the folder ``/tmp/testcmd.4060.twlYNI``,
-where you can now copy them from to your new *fixture* folder. Then, in the test
-script you simply remove all the tedious ``TestSCons.write()`` statements and
-replace them by a single ``TestSCons.dir_fixture()``.
-
-Finally, you shouldn't forget to clean up and remove the temporary test directory. ``;)``
-
-Test Infrastructure
-===================
-
-The test API is in ``QMTest/TestSCons.py``. ``TestSCons`` is a subclass of
-``TestCommon``, which is a subclass of ``TestCmd``; all those python files are
-in ``QMTest``. Start in ``QMTest/TestCmd.py`` for the base API definitions,
-like how to create files (``test.write()``) and run commands (``test.run()``).
-
-You want to use ``TestSCons`` for the end-to-end tests in ``test``, but ``TestCmd``
-for the unit tests in the ``src`` folder.
-
-The match functions work like this:
-
-TestSCons.match_re:: match each line with a RE
- * Splits the lines into a list (unless they already are)
- * splits the REs at newlines (unless already a list) and puts ^..$ around each
- * then each RE must match each line. This means there must be as many REs as lines.
-
-TestSCons.match_re_dotall:: match all the lines against a single RE
- * Joins the lines with newline (unless already a string)
- * joins the REs with newline (unless it's a string) and puts ^..$ around the whole thing
- * then whole thing must match with python re.DOTALL.
-
-Use them in a test like this::
-
- test.run(..., match=TestSCons.match_re, ...)
-
-or::
-
- test.must_match(..., match=TestSCons.match_re, ...)
-
-Avoiding Tests based on Tool existence
-======================================
-
-Here's an easy sample::
-
- #!python
- intelc = test.detect_tool('intelc', prog='icpc')
- if not intelc:
- test.skip_test("Could not load 'intelc' Tool; skipping test(s).\n")
-
-See ``QMTest/TestSCons.py`` for the ``detect_tool`` method. It calls the tool's
-``generate()`` method, and then looks for the given prog (tool name by default) in
-``env['ENV']['PATH']``.
-
-
diff --git a/README.rst b/README.rst
index 8eb5af1..d63c8a4 100644
--- a/README.rst
+++ b/README.rst
@@ -72,9 +72,8 @@ version at the SCons download page:
Execution Requirements
======================
-Running SCons requires Python version 2.7 or later (Python 3 is not
-yet supported). There should be no other dependencies or requirements
-to run SCons.
+Running SCons requires Python version 2.7.* and Python 3.5 or higher.
+There should be no other dependencies or requirements to run SCons.
The default SCons configuration assumes use of the Microsoft Visual C++
compiler suite on WIN32 systems, and assumes a C compiler named 'cc', a C++
@@ -105,13 +104,11 @@ populate the build/scons/ subdirectory. You would do this as follows on a
Linux or UNIX system (using sh or a derivative like bash or ksh)::
$ setenv MYSCONS=`pwd`/src
- $ setenv SCONS_LIB_DIR=$MYSCONS/engine
$ python $MYSCONS/script/scons.py [arguments]
Or on Windows::
C:\scons>set MYSCONS=%cd%\src
- C:\scons>set SCONS_LIB_DIR=%MYSCONS%\engine
C:\scons>python %MYSCONS%\script\scons.py [arguments]
An alternative approach is to skip the above and use::
@@ -181,7 +178,7 @@ Or on Windows::
By default, the above commands will do the following:
-- Install the version-numbered "scons-3.0.0" and "sconsign-3.0.0" scripts in
+- Install the version-numbered "scons-3.1.0" and "sconsign-3.1.0" scripts in
the default system script directory (/usr/bin or C:\\Python\*\\Scripts, for
example). This can be disabled by specifying the "--no-version-script"
option on the command line.
@@ -193,23 +190,23 @@ By default, the above commands will do the following:
before making it the default on your system.
On UNIX or Linux systems, you can have the "scons" and "sconsign" scripts be
- hard links or symbolic links to the "scons-3.0.0" and "sconsign-3.0.0"
+ hard links or symbolic links to the "scons-3.1.0" and "sconsign-3.1.0"
scripts by specifying the "--hardlink-scons" or "--symlink-scons" options on
the command line.
-- Install "scons-3.0.0.bat" and "scons.bat" wrapper scripts in the Python
+- Install "scons-3.1.0.bat" and "scons.bat" wrapper scripts in the Python
prefix directory on Windows (C:\\Python\*, for example). This can be disabled
by specifying the "--no-install-bat" option on the command line.
On UNIX or Linux systems, the "--install-bat" option may be specified to
- have "scons-3.0.0.bat" and "scons.bat" files installed in the default system
+ have "scons-3.1.0.bat" and "scons.bat" files installed in the default system
script directory, which is useful if you want to install SCons in a shared
file system directory that can be used to execute SCons from both UNIX/Linux
and Windows systems.
- Install the SCons build engine (a Python module) in an appropriate
- version-numbered SCons library directory (/usr/lib/scons-3.0.0 or
- C:\\Python\*\\scons-3.0.0, for example). See below for more options related to
+ version-numbered SCons library directory (/usr/lib/scons-3.1.0 or
+ C:\\Python\*\\scons-3.1.0, for example). See below for more options related to
installing the build engine library.
- Install the troff-format man pages in an appropriate directory on UNIX or
@@ -487,7 +484,7 @@ running all of "runtest.py -a".
Building Packages
=================
-We use SCons (version 3.0.0 or later) to build its own packages. If you
+We use SCons (version 3.1.0 or later) to build its own packages. If you
already have an appropriate version of SCons installed on your system, you can
build everything by simply running it::
@@ -502,9 +499,7 @@ about `Executing SCons Without Installing`_)::
Depending on the utilities installed on your system, any or all of the
following packages will be built::
- build/dist/scons-3.0.0-1.noarch.rpm
- build/dist/scons-3.0.0-1.src.rpm
- build/dist/scons-3.0.0.linux-i686.tar.gz
+ build/dist/scons-3.1.0.linux-i686.tar.gz
build/dist/scons-3.1.0.alpha.yyyymmdd.tar.gz
build/dist/scons-3.1.0.alpha.yyyymmdd.win32.exe
build/dist/scons-3.1.0.alpha.yyyymmdd.zip
@@ -513,7 +508,6 @@ following packages will be built::
build/dist/scons-local-3.1.0.alpha.yyyymmdd.zip
build/dist/scons-src-3.1.0.alpha.yyyymmdd.tar.gz
build/dist/scons-src-3.1.0.alpha.yyyymmdd.zip
- build/dist/scons_3.0.0-1_all.deb
The SConstruct file is supposed to be smart enough to avoid trying to build
packages for which you don't have the proper utilities installed. For
@@ -537,10 +531,6 @@ system, it should not try to install it.) The runtest.py script supports a -p
option that will run the specified tests (individually or collectively via
the -a option) against the unpacked build/test-/\* subdirectory::
- $ python runtest.py -p deb
-
- $ python runtest.py -p rpm
-
$ python runtest.py -p local-tar-gz
$ python runtest.py -p local-zip
@@ -690,18 +680,22 @@ in the LICENSE file.
Reporting Bugs
==============
-Please report bugs by following the detailed instructions on our Bug
-Submission page:
+The SCons project welcomes bug reports and feature requests.
- http://scons.tigris.org/bug-submission.html
+Please make sure you send email with the problem or feature request to the SCons user's mailing list,
+which you can join via the link below:
-You can also send mail to the SCons developers' mailing list:
+ http://two.pairlist.net/mailman/listinfo/scons-users
- scons-dev@scons.org
+Once you have discussed your issue on the users mailing list and the community has confirmed that
+it is either a new bug or a duplicate of an existing bug, then please follow the instructions the c
+ommunity provides to file a new bug or to add yourself to the CC list for an existing bug
+
+You can explore the list of existing bugs, which may include workarounds for the problem you've
+run into on GitHub Issues:
+
+ https://github.com/SCons/scons/issues
-But even if you send email to the mailing list please make sure that you ALSO
-submit a bug report to the project page bug tracker, because bug reports in
-email often get overlooked in the general flood of messages.
Mailing Lists
@@ -773,5 +767,5 @@ many contributors, including but not at all limited to:
\... and many others.
-Copyright (c) 2001 - 2017 The SCons Foundation
+Copyright (c) 2001 - 2018 The SCons Foundation
diff --git a/SConstruct b/SConstruct
index 1a0deb3..f644d6d 100644
--- a/SConstruct
+++ b/SConstruct
@@ -132,7 +132,7 @@ python_ver = sys.version[0:3]
# for the doc toolchain.
#
addpaths = [os.path.abspath(os.path.join(os.getcwd(), 'bin')),
- os.path.abspath(os.path.join(os.getcwd(), 'QMTest'))]
+ os.path.abspath(os.path.join(os.getcwd(), 'testing/framework'))]
for a in addpaths:
if a not in sys.path:
sys.path.append(a)
@@ -634,7 +634,7 @@ for p in [ scons ]:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under QMTest (for the testing modules TestCmd.py, TestSCons.py,
+ # and under testing/framework (for the testing modules TestCmd.py, TestSCons.py,
# etc.). This makes sure that our tests pass with what
# we really packaged, not because of something hanging around in
# the development directory.
@@ -704,7 +704,7 @@ for p in [ scons ]:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under QMTest (for the testing modules TestCmd.py, TestSCons.py,
+ # and under testing/framework (for the testing modules TestCmd.py, TestSCons.py,
# etc.). This makes sure that our tests pass with what
# we really packaged, not because of something hanging around in
# the development directory.
@@ -825,7 +825,7 @@ for p in [ scons ]:
#
Export('build_dir', 'env')
-SConscript('QMTest/SConscript')
+SConscript('testing/framework/SConscript')
#
#
@@ -926,7 +926,7 @@ if sfiles:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under QMTest (for the testing modules TestCmd.py,
+ # and under testing/framework (for the testing modules TestCmd.py,
# TestSCons.py, etc.). This makes sure that our tests pass with
# what we really packaged, not because of something hanging around
# in the development directory.
@@ -980,7 +980,7 @@ if sfiles:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under QMTest (for the testing modules TestCmd.py,
+ # and under testing/framework (for the testing modules TestCmd.py,
# TestSCons.py, etc.). This makes sure that our tests pass with
# what we really packaged, not because of something hanging
# around in the development directory.
@@ -1018,7 +1018,7 @@ if sfiles:
for pf, help_text in packaging_flavors:
Alias(pf, [
os.path.join(build_dir, 'test-'+pf),
- os.path.join(build_dir, 'QMTest'),
+ os.path.join(build_dir, 'testing/framework'),
os.path.join(build_dir, 'runtest.py'),
])
diff --git a/bin/SConsExamples.py b/bin/SConsExamples.py
index 722e50a..7491c58 100644
--- a/bin/SConsExamples.py
+++ b/bin/SConsExamples.py
@@ -39,7 +39,7 @@
# env.Program('foo')
# </file>
# <file name="foo.c">
-# int main() { printf("foo.c\n"); }
+# int main(void) { printf("foo.c\n"); }
# </file>
# </scons_example>
#
@@ -416,8 +416,8 @@ def exampleNamesAreUnique(dpath):
#
# ###############################################################
-sys.path.append(os.path.join(os.getcwd(), 'QMTest'))
-sys.path.append(os.path.join(os.getcwd(), 'build', 'QMTest'))
+sys.path.append(os.path.join(os.getcwd(), 'testing/framework'))
+sys.path.append(os.path.join(os.getcwd(), 'build', 'testing/framework'))
scons_py = os.path.join('bootstrap', 'src', 'script', 'scons.py')
if not os.path.exists(scons_py):
diff --git a/bin/scons-cdist b/bin/scons-cdist
deleted file mode 100644
index 58b1bae..0000000
--- a/bin/scons-cdist
+++ /dev/null
@@ -1,272 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 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.
-
-PROG=`basename $0`
-NOARGFLAGS="afhlnqrstz"
-ARGFLAGS="p:"
-ALLFLAGS="${NOARGFLAGS}${ARGFLAGS}"
-USAGE="Usage: ${PROG} [-${NOARGFLAGS}] [-p project] change"
-
-HELP="$USAGE
-
- -a Update the latest Aegis baseline (aedist) file.
- -f Force update, skipping up-front sanity check.
- -h Print this help message and exit.
- -l Update the local CVS repository.
- -n Don't execute, just echo commands.
- -p project Set the Aegis project.
- -q Quiet, don't print commands before executing them.
- -r Rsync the Aegis repository to SourceForge.
- -s Update the sourceforge.net CVS repository.
- -t Update the tigris.org CVS repository.
- -z Update the latest .tar.gz and .zip files.
-"
-
-DO=""
-PRINT="echo"
-EXECUTE="eval"
-SANITY_CHECK="yes"
-
-while getopts $ALLFLAGS FLAG; do
- case $FLAG in
- a | l | r | s | t | z )
- DO="${DO}${FLAG}"
- ;;
- f )
- SANITY_CHECK="no"
- ;;
- h )
- echo "${HELP}"
- exit 0
- ;;
- n )
- EXECUTE=":"
- ;;
- p )
- AEGIS_PROJECT="${OPTARG}"
- ;;
- q )
- PRINT=":"
- ;;
- * )
- echo "FLAG = ${FLAG}" >&2
- echo "${USAGE}" >&2
- exit 1
- ;;
- esac
-done
-
-shift `expr ${OPTIND} - 1`
-
-if test "X$1" = "X"; then
- echo "${USAGE}" >&2
- exit 1
-fi
-
-if test "X${AEGIS_PROJECT}" = "X"; then
- echo "$PROG: No AEGIS_PROJECT set." >&2
- echo "${USAGE}" >&2
- exit 1
-fi
-
-if test "X$DO" = "X"; then
- DO="alrstz"
-fi
-
-cmd()
-{
- $PRINT "$*"
- $EXECUTE "$*"
-}
-
-CHANGE=$1
-
-if test "X${SANITY_CHECK}" = "Xyes"; then
- SCM="cvs"
- SCMROOT="/home/scons/CVSROOT/scons"
- DELTA=`aegis -l -ter cd ${CHANGE} | sed -n 's/.*, Delta \([0-9]*\)\./\1/p'`
- if test "x${DELTA}" = "x"; then
- echo "${PROG}: Could not find delta for change ${CHANGE}." >&2
- echo "Has this finished integrating? Change ${CHANGE} not distributed." >&2
- exit 1
- fi
- PREV_DELTA=`expr ${DELTA} - 1`
- COMMAND="scons-scmcheck -D ${PREV_DELTA} -d q -p ${AEGIS_PROJECT} -s ${SCM} ${SCMROOT}"
- $PRINT "${COMMAND}"
- OUTPUT=`${COMMAND}`
- if test "X${OUTPUT}" != "X"; then
- echo "${PROG}: ${SCMROOT} is not up to date:" >&2
- echo "${OUTPUT}" >& 2
- echo "Did you skip any changes? Change ${CHANGE} not distributed." >&2
- exit 1
- fi
-fi
-
-if test X$EXECUTE != "X:" -a "X$SSH_AGENT_PID" = "X"; then
- eval `ssh-agent`
- ssh-add
- trap 'eval `ssh-agent -k`; exit' 0 1 2 3 15
-fi
-
-cd
-
-BASELINE=`aesub -p ${AEGIS_PROJECT} -c ${CHANGE} '${Project trunk_name}'`
-
-TMPBLAE="/tmp/${BASELINE}.ae"
-TMPCAE="/tmp/${AEGIS_PROJECT}.C${CHANGE}.ae"
-
-# Original values for SourceForge.
-#SFLOGIN="stevenknight"
-#SFHOST="scons.sourceforge.net"
-#SFDEST="/home/groups/s/sc/scons/htdocs"
-
-SCONSLOGIN="scons"
-SCONSHOST="manam.pair.com"
-#SCONSDEST="public_html/production"
-SCONSDEST="public_ftp"
-
-#
-# Copy the baseline .ae to the constant location on SourceForge.
-#
-case "${DO}" in
-*a* )
- cmd "aedist -s -bl -p ${AEGIS_PROJECT} > ${TMPBLAE}"
- cmd "scp ${TMPBLAE} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/${BASELINE}.ae"
- cmd "rm ${TMPBLAE}"
- ;;
-esac
-
-#
-# Copy the latest .tar.gz and .zip files to the constant location on
-# SourceForge.
-#
-case "${DO}" in
-*z* )
- BUILD_DIST=`aegis -p ${AEGIS_PROJECT} -cd -bl`/build/dist
- SCONS_SRC_TAR_GZ=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.tar.gz
- SCONS_SRC_ZIP=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.zip
- cmd "scp ${BUILD_DIST}/${SCONS_SRC_TAR_GZ} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.tar.gz"
- cmd "scp ${BUILD_DIST}/${SCONS_SRC_ZIP} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.zip"
-esac
-
-#
-# Sync Aegis tree with SourceForge.
-#
-# Cribbed and modified from Peter Miller's same-named script in
-# /home/groups/a/ae/aegis/aegis at SourceForge.
-#
-# Guide to what this does with rsync:
-#
-# --rsh=ssh use ssh for the transfer
-# -l copy symlinks as symlinks
-# -p preserve permissions
-# -r recursive
-# -t preserve times
-# -z compress data
-# --stats file transfer statistics
-# --exclude exclude files matching the pattern
-# --delete delete files that don't exist locally
-# --delete-excluded delete files that match the --exclude patterns
-# --progress show progress during the transfer
-# -v verbose
-#
-# We no longer use the --stats option.
-#
-case "${DO}" in
-*r* )
- LOCAL=/home/scons/scons
- REMOTE=/home/groups/s/sc/scons/scons
- cmd "/usr/bin/rsync --rsh='ssh -l stevenknight' \
- -l -p -r -t -z \
- --exclude build \
- --exclude '*,D' \
- --exclude '*.pyc' \
- --exclude aegis.log \
- --exclude '.sconsign*' \
- --delete --delete-excluded \
- --progress -v \
- ${LOCAL}/. scons.sourceforge.net:${REMOTE}/."
- ;;
-esac
-
-#
-# Sync the CVS tree with the local repository.
-#
-case "${DO}" in
-*l* )
- (
- export CVSROOT=/home/scons/CVSROOT/scons
- #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/baldmt.com/scons"
- cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}"
- )
- ;;
-esac
-
-#
-# Sync the Subversion tree with Tigris.org.
-#
-case "${DO}" in
-*t* )
- (
- SVN=http://scons.tigris.org/svn/scons
- case ${AEGIS_PROJECT} in
- scons.0.96 )
- SVN_URL=${SVN}/branches/core
- ;;
- scons.0.96.513 )
- SVN_URL=${SVN}/branches/sigrefactor
- ;;
- * )
- echo "$PROG: Don't know SVN branch for '${AEGIS_PROJECT}'" >&2
- exit 1
- ;;
- esac
- SVN_CO_FLAGS="--username stevenknight"
- #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/tigris.org/scons"
- cmd "ae-svn-ci ${AEGIS_PROJECT} ${CHANGE} ${SVN_URL} ${SVN_CO_FLAGS}"
- )
- ;;
-esac
-
-#
-# Sync the CVS tree with SourceForge.
-#
-case "${DO}" in
-*s* )
- (
- export CVS_RSH=ssh
- export CVSROOT=:ext:stevenknight@scons.cvs.sourceforge.net:/cvsroot/scons
- #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/sourceforge.net/scons"
- cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}"
- )
- ;;
-esac
-
-#
-# Send the change .ae to the scons-aedist mailing list
-#
-# The subject requires editing by hand...
-#
-#aedist -s -p ${AEGIS_PROJECT} ${CHANGE} > ${TMPCAE}
-#aegis -l -p ${AEGIS_PROJECT} -c ${CHANGE} cd |
-# pine -attach_and_delete ${TMPCAE} scons-aedist@lists.sourceforge.net
diff --git a/bin/scons_dev_master.py b/bin/scons_dev_master.py
index 3d67cb5..4fa5899 100644
--- a/bin/scons_dev_master.py
+++ b/bin/scons_dev_master.py
@@ -11,11 +11,12 @@ import sys
from Command import CommandRunner, Usage
INITIAL_PACKAGES = [
- 'mercurial',
+ 'git',
]
INSTALL_PACKAGES = [
'wget',
+ 'xz-utils',
]
PYTHON_PACKAGES = [
@@ -60,8 +61,7 @@ DOCUMENTATION_PACKAGES = [
'gcc-doc',
'pkg-config',
'python-doc',
- 'sun-java5-doc',
- 'sun-java6-doc',
+ 'openjdk-8-doc',
'swig-doc',
'texlive-doc',
]
@@ -70,21 +70,22 @@ TESTING_PACKAGES = [
'bison',
'cssc',
'cvs',
+ 'hg',
'flex',
'g++',
'gcc',
'gcj',
'ghostscript',
-# 'libgcj7-dev',
'm4',
'openssh-client',
'openssh-server',
'python-profiler',
'python-all-dev',
+ 'python3-all-dev',
+ 'pypy-dev',
'rcs',
'rpm',
-# 'sun-java5-jdk',
- 'sun-java6-jdk',
+ 'openjdk-8-jdk',
'swig',
'texlive-base-bin',
'texlive-extra-utils',
@@ -131,7 +132,7 @@ Usage: scons_dev_master.py [-hnqy] [--password PASSWORD] [--username USER]
buildbot Install packages for running BuildBot
"""
- scons_url = 'https://bdbaddog@bitbucket.org/scons/scons'
+ scons_url = 'https://github.com/SCons/scons.git'
sudo = 'sudo'
password = '""'
username = 'guest'
@@ -180,13 +181,15 @@ Usage: scons_dev_master.py [-hnqy] [--password PASSWORD] [--username USER]
cmd.run('%(sudo)s apt-get %(yesflag)s upgrade')
elif arg == 'checkout':
cmd.run('%(sudo)s apt-get %(yesflag)s install %(initial_packages)s')
- cmd.run('hg clone" %(scons_url)s')
+ cmd.run('git clone" %(scons_url)s')
elif arg == 'building':
cmd.run('%(sudo)s apt-get %(yesflag)s install %(building_packages)s')
elif arg == 'docs':
cmd.run('%(sudo)s apt-get %(yesflag)s install %(doc_packages)s')
elif arg == 'testing':
cmd.run('%(sudo)s apt-get %(yesflag)s install %(testing_packages)s')
+ #TODO: maybe copy ipkg-build from openwrt git
+ #cmd.run('%(sudo)s wget https://raw.githubusercontent.com/openwrt/openwrt/master/scripts/ipkg-build SOMEWHERE')
elif arg == 'buildbot':
cmd.run('%(sudo)s apt-get %(yesflag)s install %(buildbot_packages)s')
elif arg == 'python-versions':
diff --git a/bin/time-scons.py b/bin/time-scons.py
index b7d8ef1..c5cd0cc 100644
--- a/bin/time-scons.py
+++ b/bin/time-scons.py
@@ -43,7 +43,7 @@ TimeSCons_revision = 4569
# The pieces of the TimeSCons infrastructure that are necessary to
# produce consistent timings, even when the rest of the tree is from
# an earlier revision that doesn't have these pieces.
-TimeSCons_pieces = ['QMTest', 'timings', 'runtest.py']
+TimeSCons_pieces = ['testing/framework', 'timings', 'runtest.py']
class CommandRunner(object):
diff --git a/bin/update-release-info.py b/bin/update-release-info.py
index 81e0df5..5b871cb 100644
--- a/bin/update-release-info.py
+++ b/bin/update-release-info.py
@@ -20,10 +20,10 @@ in various files:
- The RELEASE header line in src/CHANGES.txt and src/Announce.txt.
- The version string at the top of src/RELEASE.txt.
- The version string in the 'default_version' variable in SConstruct
- and QMTest/TestSCons.py.
- - The copyright years in SConstruct and QMTest/TestSCons.py.
+ and testing/framework/TestSCons.py.
+ - The copyright years in SConstruct and testing/framework/TestSCons.py.
- The month and year (used for documentation) in SConstruct.
- - The unsupported and deprecated Python floors in QMTest/TestSCons.py
+ - The unsupported and deprecated Python floors in testing/framework/TestSCons.py
and src/engine/SCons/Script/Main.py
- The version string in the filenames in README.
@@ -315,9 +315,9 @@ for suf in ['tar', 'win32', 'zip', 'rpm', 'exe', 'deb']:
'-%s.%s' % (version_string, suf),
count = 0)
-# Update QMTest/TestSCons.py
+# Update testing/framework/TestSCons.py
-t = UpdateFile(os.path.join('QMTest', 'TestSCons.py'))
+t = UpdateFile(os.path.join('testing','framework', 'TestSCons.py'))
if DEBUG: t.file = '/tmp/TestSCons.py'
t.replace_assign('copyright_years', repr(copyright_years))
t.replace_assign('default_version', repr(version_string))
diff --git a/bin/xmlagenda.py b/bin/xmlagenda.py
index fcfe53e..7091ee5 100755
--- a/bin/xmlagenda.py
+++ b/bin/xmlagenda.py
@@ -1,7 +1,9 @@
#!/usr/bin/env python
-# Query the scons.tigris.org database for the issues of interest.
-# The typical triage query is found on http://www.scons.org/wiki/BugParty
+# Query gihub issue tracker for the issues of interest.
+# The typical triage query is found on
+# https://github.com/scons/scons/wiki/BugParty
+# FIXME: this needs reworking for github, and wiki needs updating
# Download the issues from Issuezilla as XML; this creates a file
# named 'issues.xml'. Run this script in the dir containing
diff --git a/doc/design/native.xml b/doc/design/native.xml
index cd4edaf..0ea4074 100644
--- a/doc/design/native.xml
+++ b/doc/design/native.xml
@@ -64,8 +64,9 @@
<para>
By default, the &SCons; utility searches for a file named
- &SConstruct;, &Sconstruct; or &sconstruct; (in that order) in the
- current directory, and reads its configuration from the first file
+ &SConstruct;, &Sconstruct;, &sconstruct;, &SConstruct.py;, &Sconstruct.py;
+ or &sconstruct.py; (in that order) in the current directory,
+ and reads its configuration from the first file
found. A <option>-f</option> command-line option exists to read a
different file name.
diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen
index d851c93..ada4e43 100644
--- a/doc/generated/builders.gen
+++ b/doc/generated/builders.gen
@@ -1206,13 +1206,15 @@ the following packagers available:
<para xmlns="http://www.scons.org/dbxsd/v1.0">
* msi - Microsoft Installer
- * rpm - Redhat Package Manger
+ * rpm - RPM Package Manger
* ipkg - Itsy Package Management System
- * tarbz2 - compressed tar
- * targz - compressed tar
+ * tarbz2 - bzip2 compressed tar
+ * targz - gzip compressed tar
+ * tarxz - xz compressed tar
* zip - zip file
- * src_tarbz2 - compressed tar source
- * src_targz - compressed tar source
+ * src_tarbz2 - bzip2 compressed tar source
+ * src_targz - gzip compressed tar source
+ * src_tarxz - xz compressed tar source
* src_zip - zip file source
</para>
diff --git a/doc/generated/examples/builderswriting_MY_EMITTER_1.xml b/doc/generated/examples/builderswriting_MY_EMITTER_1.xml
index 440b105..0c17d0e 100644
--- a/doc/generated/examples/builderswriting_MY_EMITTER_1.xml
+++ b/doc/generated/examples/builderswriting_MY_EMITTER_1.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<screen xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">% <userinput>scons -Q</userinput>
-my_command file1.input modify1.in &gt; file1.foo
-my_command file2.input modify2.in &gt; file2.foo
+./my_command file1.input modify1.in &gt; file1.foo
+./my_command file2.input modify2.in &gt; file2.foo
</screen>
diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml
index 81cbc5d..18b04eb 100644
--- a/doc/generated/examples/caching_ex-random_1.xml
+++ b/doc/generated/examples/caching_ex-random_1.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<screen xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">% <userinput>scons -Q</userinput>
+cc -o f3.o -c f3.c
cc -o f5.o -c f5.c
cc -o f4.o -c f4.c
-cc -o f1.o -c f1.c
-cc -o f3.o -c f3.c
cc -o f2.o -c f2.c
+cc -o f1.o -c f1.c
cc -o prog f1.o f2.o f3.o f4.o f5.o
</screen>
diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml
index 08c6f04..a621422 100644
--- a/doc/generated/examples/troubleshoot_Dump_2.xml
+++ b/doc/generated/examples/troubleshoot_Dump_2.xml
@@ -79,7 +79,7 @@ scons: Reading SConscript files ...
'SHCXX': '$CXX',
'SHCXXCOM': '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCXXCOMSTR")}',
'SHCXXFLAGS': ['$CXXFLAGS'],
- 'SHELL': 'command',
+ 'SHELL': None,
'SHLIBPREFIX': '',
'SHLIBSUFFIX': '.dll',
'SHOBJPREFIX': '$OBJPREFIX',
diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml
index 32adb2f..064fdcb 100644
--- a/doc/generated/examples/troubleshoot_explain1_3.xml
+++ b/doc/generated/examples/troubleshoot_explain1_3.xml
@@ -3,5 +3,5 @@
cp file.in file.oout
scons: warning: Cannot find target file.out after building
-File "/Users/bdbaddog/devel/scons/git/as_scons/bootstrap/src/script/scons.py", line 201, in &lt;module&gt;
+File "/home/bdbaddog/scons/git/scons/bootstrap/src/script/scons.py", line 201, in &lt;module&gt;
</screen>
diff --git a/doc/generated/examples/troubleshoot_stacktrace_2.xml b/doc/generated/examples/troubleshoot_stacktrace_2.xml
index 4b55f0d..52bfa43 100644
--- a/doc/generated/examples/troubleshoot_stacktrace_2.xml
+++ b/doc/generated/examples/troubleshoot_stacktrace_2.xml
@@ -4,7 +4,7 @@ scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'.
scons: internal stack trace:
File "bootstrap/src/engine/SCons/Job.py", line 199, in start
task.prepare()
- File "bootstrap/src/engine/SCons/Script/Main.py", line 175, in prepare
+ File "bootstrap/src/engine/SCons/Script/Main.py", line 176, in prepare
return SCons.Taskmaster.OutOfDateTask.prepare(self)
File "bootstrap/src/engine/SCons/Taskmaster.py", line 198, in prepare
executor.prepare()
diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen
index 79a83c6..617a0a4 100644
--- a/doc/generated/functions.gen
+++ b/doc/generated/functions.gen
@@ -3523,16 +3523,16 @@ below, for a complete explanation of the arguments and behavior.
</varlistentry>
<varlistentry id="f-SConscript">
<term>
- <literal>SConscript(scripts, [exports, variant_dir, duplicate])</literal>
+ <literal>SConscript(scripts, [exports, variant_dir, duplicate, must_exist])</literal>
</term>
<term>
- <literal>env.SConscript(scripts, [exports, variant_dir, duplicate])</literal>
+ <literal>env.SConscript(scripts, [exports, variant_dir, duplicate, must_exist])</literal>
</term>
<term>
- <literal>SConscript(dirs=subdirs, [name=script, exports, variant_dir, duplicate])</literal>
+ <literal>SConscript(dirs=subdirs, [name=script, exports, variant_dir, duplicate, must_exist])</literal>
</term>
<term>
- <literal>env.SConscript(dirs=subdirs, [name=script, exports, variant_dir, duplicate])</literal>
+ <literal>env.SConscript(dirs=subdirs, [name=script, exports, variant_dir, duplicate, must_exist])</literal>
</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
@@ -3734,6 +3734,17 @@ TODO??? SConscript('build/SConscript', src_dir='src')
</para>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
+The optional
+<varname>must_exist</varname>
+argument, if true, causes an exception to be raised if a requested
+<filename xmlns="http://www.scons.org/dbxsd/v1.0">SConscript</filename> file is not found. The current default is false,
+causing only a warning to be omitted, but this behavior is deprecated.
+For scripts which truly intend to be optional, transition to
+explicty supplying
+<literal>must_exist=False</literal> to the call.
+</para>
+
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Here are some composite examples:
</para>
diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen
index 26b7e22..f858aa4 100644
--- a/doc/generated/tools.gen
+++ b/doc/generated/tools.gen
@@ -778,19 +778,19 @@ Sets construction variables for the
</para>
<para>Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.</para><para>Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;.</para></listitem>
</varlistentry>
- <varlistentry id="t-packaging">
- <term>packaging</term>
+ <varlistentry id="t-Packaging">
+ <term>Packaging</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
-A framework for building binary and source packages.
+Sets construction variables for the <function xmlns="http://www.scons.org/dbxsd/v1.0">Package</function> Builder.
</para>
</listitem>
</varlistentry>
- <varlistentry id="t-Packaging">
- <term>Packaging</term>
+ <varlistentry id="t-packaging">
+ <term>packaging</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
-Sets construction variables for the <function xmlns="http://www.scons.org/dbxsd/v1.0">Package</function> Builder.
+A framework for building binary and source packages.
</para>
</listitem>
</varlistentry>
diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod
index f9bc1d7..1209d74 100644
--- a/doc/generated/tools.mod
+++ b/doc/generated/tools.mod
@@ -78,8 +78,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY t-mwcc "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>mwcc</literal>">
<!ENTITY t-mwld "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>mwld</literal>">
<!ENTITY t-nasm "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>nasm</literal>">
-<!ENTITY t-packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>packaging</literal>">
<!ENTITY t-Packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>Packaging</literal>">
+<!ENTITY t-packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>packaging</literal>">
<!ENTITY t-pdf "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdf</literal>">
<!ENTITY t-pdflatex "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdflatex</literal>">
<!ENTITY t-pdftex "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdftex</literal>">
@@ -186,8 +186,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY t-link-mwcc "<link linkend='t-mwcc' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>mwcc</literal></link>">
<!ENTITY t-link-mwld "<link linkend='t-mwld' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>mwld</literal></link>">
<!ENTITY t-link-nasm "<link linkend='t-nasm' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>nasm</literal></link>">
-<!ENTITY t-link-packaging "<link linkend='t-packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>packaging</literal></link>">
<!ENTITY t-link-Packaging "<link linkend='t-Packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>Packaging</literal></link>">
+<!ENTITY t-link-packaging "<link linkend='t-packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>packaging</literal></link>">
<!ENTITY t-link-pdf "<link linkend='t-pdf' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdf</literal></link>">
<!ENTITY t-link-pdflatex "<link linkend='t-pdflatex' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdflatex</literal></link>">
<!ENTITY t-link-pdftex "<link linkend='t-pdftex' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdftex</literal></link>">
diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen
index b86690a..9246249 100644
--- a/doc/generated/variables.gen
+++ b/doc/generated/variables.gen
@@ -51,7 +51,9 @@ This is used to fill in the
<literal>Architecture:</literal>
field in an Ipkg
<filename>control</filename> file,
-and as part of the name of a generated RPM file.
+and the <literal>BuildArch:</literal> field
+in the RPM <filename>.spec</filename> file,
+as well as forming part of the name of a generated RPM package file.
</para>
</listitem>
</varlistentry>
@@ -240,7 +242,7 @@ or this:
<example_commands xmlns="http://www.scons.org/dbxsd/v1.0">
env = Environment()
-env['BUILDERS]['NewBuilder'] = foo
+env['BUILDERS']['NewBuilder'] = foo
</example_commands>
</listitem>
</varlistentry>
@@ -389,7 +391,6 @@ the <filename>control</filename> for Ipkg,
the <filename>.wxs</filename> for MSI).
If set, the function will be called
after the SCons template for the file has been written.
-XXX
</para>
</listitem>
</varlistentry>
@@ -480,7 +481,8 @@ An automatically-generated construction variable
containing the C preprocessor command-line options
to define values.
The value of <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_CPPDEFFLAGS</envar> is created
-by appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFSUFFIX</envar>
+by respectively prepending and appending
+<envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFSUFFIX</envar>
to the beginning and end
of each definition in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFINES</envar>.
</para>
@@ -503,7 +505,8 @@ If <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFINES</envar> is a strin
the values of the
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFSUFFIX</envar>
construction variables
-will be added to the beginning and end.
+will be respectively prepended and appended to the beginning and end
+of each definition in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFINES</envar>.
</para>
<example_commands xmlns="http://www.scons.org/dbxsd/v1.0">
@@ -517,7 +520,7 @@ If <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFINES</envar> is a list,
the values of the
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFSUFFIX</envar>
construction variables
-will be appended to the beginning and end
+will be respectively prepended and appended to the beginning and end
of each element in the list.
If any element is a list or tuple,
then the first item is the name being
@@ -535,7 +538,7 @@ If <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFINES</envar> is a dicti
the values of the
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFSUFFIX</envar>
construction variables
-will be appended to the beginning and end
+will be respectively prepended and appended to the beginning and end
of each item from the dictionary.
The key of each dictionary item
is a name being defined
@@ -563,7 +566,7 @@ env = Environment(CPPDEFINES={'B':2, 'A':None})
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix used to specify preprocessor definitions
on the C compiler command line.
-This will be appended to the beginning of each definition
+This will be prepended to the beginning of each definition
in the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPDEFINES</envar> construction variable
when the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_CPPDEFFLAGS</envar> variable is automatically generated.
</para>
@@ -619,7 +622,7 @@ An automatically-generated construction variable
containing the C preprocessor command-line options
for specifying directories to be searched for include files.
The value of <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_CPPINCFLAGS</envar> is created
-by appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$INCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$INCSUFFIX</envar>
+by respectively prepending and appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$INCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$INCSUFFIX</envar>
to the beginning and end
of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPPATH</envar>.
</para>
@@ -661,7 +664,7 @@ through the automatically-generated
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$_CPPINCFLAGS</envar>
construction variable,
which is constructed by
-appending the values of the
+respectively prepending and appending the value of the
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$INCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$INCSUFFIX</envar>
construction variables
to the beginning and end
@@ -2602,7 +2605,8 @@ containing the Fortran compiler command-line options
for specifying directories to be searched for include
files and module files.
The value of <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-_FORTRANINCFLAGS"><envar>$_FORTRANINCFLAGS</envar></link> is created
-by prepending/appending <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-INCPREFIX"><envar>$INCPREFIX</envar></link> and <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-INCSUFFIX"><envar>$INCSUFFIX</envar></link>
+by respectively prepending and appending
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-INCPREFIX"><envar>$INCPREFIX</envar></link> and <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-INCSUFFIX"><envar>$INCSUFFIX</envar></link>
to the beginning and end
of each directory in <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANPATH"><envar>$FORTRANPATH</envar></link>.
</para>
@@ -2625,7 +2629,7 @@ for module files, as well.
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix used to specify a module directory on the Fortran compiler command
line.
-This will be appended to the beginning of the directory
+This will be prepended to the beginning of the directory
in the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANMODDIR"><envar>$FORTRANMODDIR</envar></link> construction variables
when the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-_FORTRANMODFLAG"><envar>$_FORTRANMODFLAG</envar></link> variables is automatically generated.
</para>
@@ -2637,7 +2641,7 @@ when the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-_FORTRANMODFL
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The suffix used to specify a module directory on the Fortran compiler command
line.
-This will be appended to the beginning of the directory
+This will be appended to the end of the directory
in the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANMODDIR"><envar>$FORTRANMODDIR</envar></link> construction variables
when the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-_FORTRANMODFLAG"><envar>$_FORTRANMODFLAG</envar></link> variables is automatically generated.
</para>
@@ -2653,8 +2657,8 @@ for specifying the directory location where the Fortran
compiler should place any module files that happen to get
generated during compilation.
The value of <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-_FORTRANMODFLAG"><envar>$_FORTRANMODFLAG</envar></link> is created
-by prepending/appending <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANMODDIRPREFIX"><envar>$FORTRANMODDIRPREFIX</envar></link> and
-<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANMODDIRSUFFIX"><envar>$FORTRANMODDIRSUFFIX</envar></link>
+by respectively prepending and appending
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANMODDIRPREFIX"><envar>$FORTRANMODDIRPREFIX</envar></link> and <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANMODDIRSUFFIX"><envar>$FORTRANMODDIRSUFFIX</envar></link>
to the beginning and end of the directory in <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-FORTRANMODDIR"><envar>$FORTRANMODDIR</envar></link>.
</para>
</listitem>
@@ -2727,7 +2731,7 @@ through the automatically-generated
<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-_FORTRANINCFLAGS"><envar>$_FORTRANINCFLAGS</envar></link>
construction variable,
which is constructed by
-appending the values of the
+respectively prepending and appending the values of the
<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-INCPREFIX"><envar>$INCPREFIX</envar></link> and <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-INCSUFFIX"><envar>$INCSUFFIX</envar></link>
construction variables
to the beginning and end
@@ -2940,15 +2944,6 @@ is <quote><literal>-dNOPAUSE -dBATCH -sDEVICE=pdfwrite</literal></quote>
<term>HOST_ARCH</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
- The name of the host hardware architecture used to create the Environment.
- If a platform is specified when creating the Environment, then
- that Platform's logic will handle setting this value.
- This value is immutable, and should not be changed by the user after
- the Environment is initialized.
- Currently only set for Win32.
-</para>
-
-<para xmlns="http://www.scons.org/dbxsd/v1.0">
Sets the host architecture for Visual Studio compiler. If not set,
default to the detected host architecture: note that this may depend
on the python you are using.
@@ -2964,7 +2959,16 @@ Valid values are the same as for <envar xmlns="http://www.scons.org/dbxsd/v1.0">
This is currently only used on Windows, but in the future it will be
used on other OSes as well.
</para>
-</listitem>
+
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+ The name of the host hardware architecture used to create the Environment.
+ If a platform is specified when creating the Environment, then
+ that Platform's logic will handle setting this value.
+ This value is immutable, and should not be changed by the user after
+ the Environment is initialized.
+ Currently only set for Win32.
+</para>
+ </listitem>
</varlistentry>
<varlistentry id="cv-HOST_OS">
<term>HOST_OS</term>
@@ -3087,7 +3091,7 @@ env = Environment(IMPLICIT_COMMAND_DEPENDENCIES = 0)
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix used to specify an include directory on the C compiler command
line.
-This will be appended to the beginning of each directory
+This will be prepended to the beginning of each directory
in the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPPATH</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$FORTRANPATH</envar> construction variables
when the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_CPPINCFLAGS</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_FORTRANINCFLAGS</envar>
variables are automatically generated.
@@ -3698,7 +3702,7 @@ An automatically-generated construction variable
containing the linker command-line options
for specifying directories to be searched for library.
The value of <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_LIBDIRFLAGS</envar> is created
-by appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBDIRPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBDIRSUFFIX</envar>
+by respectively prepending and appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBDIRPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBDIRSUFFIX</envar>
to the beginning and end
of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBPATH</envar>.
</para>
@@ -3709,7 +3713,7 @@ of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBPATH</en
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix used to specify a library directory on the linker command line.
-This will be appended to the beginning of each directory
+This will be prepended to the beginning of each directory
in the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBPATH</envar> construction variable
when the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_LIBDIRFLAGS</envar> variable is automatically generated.
</para>
@@ -3742,7 +3746,7 @@ An automatically-generated construction variable
containing the linker command-line options
for specifying libraries to be linked with the resulting target.
The value of <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_LIBFLAGS</envar> is created
-by appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBLINKPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBLINKSUFFIX</envar>
+by respectively prepending and appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBLINKPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBLINKSUFFIX</envar>
to the beginning and end
of each filename in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBS</envar>.
</para>
@@ -3753,7 +3757,7 @@ of each filename in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBS</envar>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix used to specify a library to link on the linker command line.
-This will be appended to the beginning of each library
+This will be prepended to the beginning of each library
in the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBS</envar> construction variable
when the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_LIBFLAGS</envar> variable is automatically generated.
</para>
@@ -3807,7 +3811,7 @@ through the automatically-generated
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$_LIBDIRFLAGS</envar>
construction variable,
which is constructed by
-appending the values of the
+respectively prepending and appending the values of the
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBDIRPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBDIRSUFFIX</envar>
construction variables
to the beginning and end
@@ -3863,7 +3867,7 @@ through the automatically-generated
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$_LIBFLAGS</envar>
construction variable,
which is constructed by
-appending the values of the
+respectively prepending and appending the values of the
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBLINKPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$LIBLINKSUFFIX</envar>
construction variables
to the beginning and end
@@ -3930,10 +3934,10 @@ and these suffixes.
<term>LICENSE</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
-The abbreviated name of the license under which
-this project is released (gpl, lpgl, bsd etc.).
+The abbreviated name, preferably the SPDX code, of the license under which
+this project is released (GPL-3.0, LGPL-2.1, BSD-2-Clause etc.).
See http://www.opensource.org/licenses/alphabetical
-for a list of license names.
+for a list of license names and SPDX codes.
</para>
</listitem>
</varlistentry>
@@ -5601,7 +5605,8 @@ containing the command-line options
for specifying directories to be searched
by the resource compiler.
The value of <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RCINCFLAGS</envar> is created
-by appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RCINCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RCINCSUFFIX</envar>
+by respectively prepending and appending
+<envar xmlns="http://www.scons.org/dbxsd/v1.0">$RCINCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RCINCSUFFIX</envar>
to the beginning and end
of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPPATH</envar>.
</para>
@@ -5613,7 +5618,7 @@ of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPPATH</en
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix (flag) used to specify an include directory
on the resource compiler command line.
-This will be appended to the beginning of each directory
+This will be prepended to the beginning of each directory
in the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$CPPPATH</envar> construction variable
when the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RCINCFLAGS</envar> variable is expanded.
</para>
@@ -5735,7 +5740,7 @@ An automatically-generated construction variable
containing the rpath flags to be used when linking
a program with shared libraries.
The value of <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_RPATH</envar> is created
-by appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RPATHPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RPATHSUFFIX</envar>
+by respectively prepending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RPATHPREFIX</envar> and appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RPATHSUFFIX</envar>
to the beginning and end
of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RPATH</envar>.
</para>
@@ -5763,7 +5768,7 @@ path, you must make it absolute yourself.
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix used to specify a directory to be searched for
shared libraries when running programs.
-This will be appended to the beginning of each directory
+This will be prepended to the beginning of each directory
in the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$RPATH</envar> construction variable
when the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_RPATH</envar> variable is automatically generated.
</para>
@@ -6610,6 +6615,16 @@ Example <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION">
</para>
</listitem>
</varlistentry>
+ <varlistentry id="cv-SHLIBVERSIONFLAGS">
+ <term>SHLIBVERSIONFLAGS</term>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+Extra flags added to <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> when building versioned
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-SharedLibrary"><function>SharedLibrary</function></link>. These flags are only used when <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> is
+set.
+</para>
+</listitem>
+ </varlistentry>
<varlistentry id="cv-_SHLIBVERSIONFLAGS">
<term>_SHLIBVERSIONFLAGS</term>
<listitem>
@@ -6623,16 +6638,6 @@ and some extra dynamically generated options (such as
</para>
</listitem>
</varlistentry>
- <varlistentry id="cv-SHLIBVERSIONFLAGS">
- <term>SHLIBVERSIONFLAGS</term>
- <listitem>
-<para xmlns="http://www.scons.org/dbxsd/v1.0">
-Extra flags added to <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> when building versioned
-<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-SharedLibrary"><function>SharedLibrary</function></link>. These flags are only used when <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> is
-set.
-</para>
-</listitem>
- </varlistentry>
<varlistentry id="cv-SHLINK">
<term>SHLINK</term>
<listitem>
@@ -6935,7 +6940,8 @@ An automatically-generated construction variable
containing the SWIG command-line options
for specifying directories to be searched for included files.
The value of <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_SWIGINCFLAGS</envar> is created
-by appending <envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGINCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGINCSUFFIX</envar>
+by respectively prepending and appending
+<envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGINCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGINCSUFFIX</envar>
to the beginning and end
of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGPATH</envar>.
</para>
@@ -6946,7 +6952,7 @@ of each directory in <envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGPATH</e
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix used to specify an include directory on the SWIG command line.
-This will be appended to the beginning of each directory
+This will be prepended to the beginning of each directory
in the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGPATH</envar> construction variable
when the <envar xmlns="http://www.scons.org/dbxsd/v1.0">$_SWIGINCFLAGS</envar> variable is automatically generated.
</para>
@@ -7020,7 +7026,7 @@ through the automatically-generated
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$_SWIGINCFLAGS</envar>
construction variable,
which is constructed by
-appending the values of the
+respectively prepending and appending the values of the
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGINCPREFIX</envar> and <envar xmlns="http://www.scons.org/dbxsd/v1.0">$SWIGINCSUFFIX</envar>
construction variables
to the beginning and end
@@ -7095,13 +7101,6 @@ that may not be set or used in a construction environment.
<term>TARGET_ARCH</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
- The name of the target hardware architecture for the compiled objects
- created by this Environment.
- This defaults to the value of HOST_ARCH, and the user can override it.
- Currently only set for Win32.
-</para>
-
-<para xmlns="http://www.scons.org/dbxsd/v1.0">
Sets the target architecture for Visual Studio compiler (i.e. the arch
of the binaries generated by the compiler). If not set, default to
<envar xmlns="http://www.scons.org/dbxsd/v1.0">$HOST_ARCH</envar>, or, if that is unset, to the architecture of the
@@ -7126,7 +7125,14 @@ and <literal>ia64</literal> (Itanium).
For example, if you want to compile 64-bit binaries, you would set
<literal>TARGET_ARCH='x86_64'</literal> in your SCons environment.
</para>
-</listitem>
+
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+ The name of the target hardware architecture for the compiled objects
+ created by this Environment.
+ This defaults to the value of HOST_ARCH, and the user can override it.
+ Currently only set for Win32.
+</para>
+ </listitem>
</varlistentry>
<varlistentry id="cv-TARGET_OS">
<term>TARGET_OS</term>
@@ -7542,6 +7548,7 @@ This is used to fill in the
<literal>BuildRequires:</literal>
field in the RPM
<filename>.spec</filename> file.
+Note this should only be used on a host managed by rpm as the dependencies will not be resolvable at build time otherwise.
</para>
</listitem>
</varlistentry>
@@ -7600,7 +7607,8 @@ field in the RPM
<para xmlns="http://www.scons.org/dbxsd/v1.0">
This is used to fill in the
<literal>Epoch:</literal>
-field in the controlling information for RPM packages.
+field in the RPM
+<filename>.spec</filename> file.
</para>
</listitem>
</varlistentry>
@@ -7626,6 +7634,38 @@ field in the RPM
</para>
</listitem>
</varlistentry>
+ <varlistentry id="cv-X_RPM_EXTRADEFS">
+ <term>X_RPM_EXTRADEFS</term>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+A list used to supply extra defintions or flags
+to be added to the RPM <filename>.spec</filename> file.
+Each item is added as-is with a carriage return appended.
+This is useful if some specific RPM feature not otherwise
+anticipated by SCons needs to be turned on or off.
+Note if this variable is omitted, SCons will by
+default supply the value
+<literal>'%global debug_package %{nil}'</literal>
+to disable debug package generation.
+To enable debug package generation, include this
+variable set either to None, or to a custom
+list that does not include the default line.
+Added in version 3.1.
+</para>
+
+<example_commands xmlns="http://www.scons.org/dbxsd/v1.0">
+env.Package(
+ NAME = 'foo',
+...
+ X_RPM_EXTRADEFS = [
+ '%define _unpackaged_files_terminate_build 0'
+ '%define _missing_doc_files_terminate_build 0'
+ ],
+... )
+</example_commands>
+
+</listitem>
+ </varlistentry>
<varlistentry id="cv-X_RPM_GROUP">
<term>X_RPM_GROUP</term>
<listitem>
diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod
index 460724e..52ee4e1 100644
--- a/doc/generated/variables.mod
+++ b/doc/generated/variables.mod
@@ -496,8 +496,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-_SHLIBSONAME "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBSONAME</envar>">
<!ENTITY cv-SHLIBSUFFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBSUFFIX</envar>">
<!ENTITY cv-SHLIBVERSION "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBVERSION</envar>">
-<!ENTITY cv-_SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBVERSIONFLAGS</envar>">
<!ENTITY cv-SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBVERSIONFLAGS</envar>">
+<!ENTITY cv-_SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBVERSIONFLAGS</envar>">
<!ENTITY cv-SHLINK "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINK</envar>">
<!ENTITY cv-SHLINKCOM "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINKCOM</envar>">
<!ENTITY cv-SHLINKCOMSTR "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINKCOMSTR</envar>">
@@ -584,6 +584,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-X_RPM_EPOCH "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$X_RPM_EPOCH</envar>">
<!ENTITY cv-X_RPM_EXCLUDEARCH "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$X_RPM_EXCLUDEARCH</envar>">
<!ENTITY cv-X_RPM_EXLUSIVEARCH "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$X_RPM_EXLUSIVEARCH</envar>">
+<!ENTITY cv-X_RPM_EXTRADEFS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$X_RPM_EXTRADEFS</envar>">
<!ENTITY cv-X_RPM_GROUP "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$X_RPM_GROUP</envar>">
<!ENTITY cv-X_RPM_GROUP_lang "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$X_RPM_GROUP_lang</envar>">
<!ENTITY cv-X_RPM_ICON "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$X_RPM_ICON</envar>">
@@ -1125,8 +1126,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-link-_SHLIBSONAME "<link linkend='cv-_SHLIBSONAME' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBSONAME</envar></link>">
<!ENTITY cv-link-SHLIBSUFFIX "<link linkend='cv-SHLIBSUFFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBSUFFIX</envar></link>">
<!ENTITY cv-link-SHLIBVERSION "<link linkend='cv-SHLIBVERSION' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBVERSION</envar></link>">
-<!ENTITY cv-link-_SHLIBVERSIONFLAGS "<link linkend='cv-_SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBVERSIONFLAGS</envar></link>">
<!ENTITY cv-link-SHLIBVERSIONFLAGS "<link linkend='cv-SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBVERSIONFLAGS</envar></link>">
+<!ENTITY cv-link-_SHLIBVERSIONFLAGS "<link linkend='cv-_SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBVERSIONFLAGS</envar></link>">
<!ENTITY cv-link-SHLINK "<link linkend='cv-SHLINK' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINK</envar></link>">
<!ENTITY cv-link-SHLINKCOM "<link linkend='cv-SHLINKCOM' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINKCOM</envar></link>">
<!ENTITY cv-link-SHLINKCOMSTR "<link linkend='cv-SHLINKCOMSTR' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINKCOMSTR</envar></link>">
@@ -1213,6 +1214,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-link-X_RPM_EPOCH "<link linkend='cv-X_RPM_EPOCH' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$X_RPM_EPOCH</envar></link>">
<!ENTITY cv-link-X_RPM_EXCLUDEARCH "<link linkend='cv-X_RPM_EXCLUDEARCH' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$X_RPM_EXCLUDEARCH</envar></link>">
<!ENTITY cv-link-X_RPM_EXLUSIVEARCH "<link linkend='cv-X_RPM_EXLUSIVEARCH' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$X_RPM_EXLUSIVEARCH</envar></link>">
+<!ENTITY cv-link-X_RPM_EXTRADEFS "<link linkend='cv-X_RPM_EXTRADEFS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$X_RPM_EXTRADEFS</envar></link>">
<!ENTITY cv-link-X_RPM_GROUP "<link linkend='cv-X_RPM_GROUP' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$X_RPM_GROUP</envar></link>">
<!ENTITY cv-link-X_RPM_GROUP_lang "<link linkend='cv-X_RPM_GROUP_lang' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$X_RPM_GROUP_lang</envar></link>">
<!ENTITY cv-link-X_RPM_ICON "<link linkend='cv-X_RPM_ICON' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$X_RPM_ICON</envar></link>">
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index 03a3478..abbed4f 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -105,8 +105,11 @@ rebuild them.</para>
searches for a file named
<emphasis>SConstruct</emphasis>,
<emphasis>Sconstruct</emphasis>,
+<emphasis>sconstruct</emphasis>,
+<emphasis>SConstruct.py</emphasis>
+<emphasis>Sconstruct.py</emphasis>
or
-<emphasis>sconstruct</emphasis>
+<emphasis>sconstruct.py</emphasis>
(in that order) in the current directory and reads its
configuration from the first file found.
An alternate file name may be
@@ -635,8 +638,11 @@ yet have any results in the cache.</para>
before searching for the
<emphasis>SConstruct</emphasis>,
<emphasis>Sconstruct</emphasis>,
+<emphasis>sconstruct</emphasis>,
+<emphasis>SConstruct.py</emphasis>
+<emphasis>Sconstruct.py</emphasis>
or
-<emphasis>sconstruct</emphasis>
+<emphasis>sconstruct.py</emphasis>
file, or doing anything
else. Multiple
<option>-C</option>
@@ -649,8 +655,11 @@ equivalent to
except that it will search for
<emphasis>SConstruct</emphasis>,
<emphasis>Sconstruct</emphasis>,
+<emphasis>sconstruct</emphasis>,
+<emphasis>SConstruct.py</emphasis>
+<emphasis>Sconstruct.py</emphasis>
or
-<emphasis>sconstruct</emphasis>
+<emphasis>sconstruct.py</emphasis>
in the specified directory.)</para>
<!-- .TP -->
@@ -1658,9 +1667,12 @@ scons --tree=all,prune,status target
<listitem>
<para>Walks up the directory structure until an
<emphasis>SConstruct ,</emphasis>
-<emphasis>Sconstruct</emphasis>
+<emphasis>Sconstruct ,</emphasis>
+<emphasis>sconstruct ,</emphasis>
+<emphasis>SConstruct.py</emphasis>
+<emphasis>Sconstruct.py</emphasis>
or
-<emphasis>sconstruct</emphasis>
+<emphasis>sconstruct.py</emphasis>
file is found, and uses that
as the top of the directory tree.
If no targets are specified on the command line,
diff --git a/doc/scons.mod b/doc/scons.mod
index 448a212..974ec02 100644
--- a/doc/scons.mod
+++ b/doc/scons.mod
@@ -137,6 +137,9 @@
<!ENTITY SConstruct "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>SConstruct</filename>">
<!ENTITY Sconstruct "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>Sconstruct</filename>">
<!ENTITY sconstruct "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>sconstruct</filename>">
+<!ENTITY SConstruct.py "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>SConstruct.py</filename>">
+<!ENTITY Sconstruct.py "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>Sconstruct.py</filename>">
+<!ENTITY sconstruct.py "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>sconstruct.py</filename>">
<!ENTITY sconsign "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>.sconsign</filename>">
<!ENTITY src "<filename xmlns='http://www.scons.org/dbxsd/v1.0'>src</filename>">
diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml
index 07f2dec..ce95128 100644
--- a/doc/user/builders-writing.xml
+++ b/doc/user/builders-writing.xml
@@ -812,7 +812,7 @@ env.Foo('file')
<scons_example name="builderswriting_MY_EMITTER">
<file name="SConstruct" printme="1">
-bld = Builder(action = 'my_command $SOURCES &gt; $TARGET',
+bld = Builder(action = './my_command $SOURCES &gt; $TARGET',
suffix = '.foo',
src_suffix = '.input',
emitter = '$MY_EMITTER')
@@ -826,9 +826,6 @@ env2 = Environment(BUILDERS = {'Foo' : bld},
MY_EMITTER = modify2)
env1.Foo('file1')
env2.Foo('file2')
-import os
-env1['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd()
-env2['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd()
</file>
<file name="file1.input">
file1.input
@@ -848,23 +845,6 @@ cat
</scons_example>
- <sconstruct>
-bld = Builder(action = 'my_command $SOURCES &gt; $TARGET',
- suffix = '.foo',
- src_suffix = '.input',
- emitter = '$MY_EMITTER')
-def modify1(target, source, env):
- return target, source + ['modify1.in']
-def modify2(target, source, env):
- return target, source + ['modify2.in']
-env1 = Environment(BUILDERS = {'Foo' : bld},
- MY_EMITTER = modify1)
-env2 = Environment(BUILDERS = {'Foo' : bld},
- MY_EMITTER = modify2)
-env1.Foo('file1')
-env2.Foo('file2')
- </sconstruct>
-
<para>
In this example, the <filename>modify1.in</filename>
diff --git a/doc/user/depends.xml b/doc/user/depends.xml
index f5f2270..297eaa2 100644
--- a/doc/user/depends.xml
+++ b/doc/user/depends.xml
@@ -518,7 +518,7 @@ cc -o hello hello.o
<file name="SConstruct" printme="1">
Program('hello.c')
def decide_if_changed(dependency, target, prev_ni):
- if self.get_timestamp() != prev_ni.timestamp:
+ if dependency.get_timestamp() != prev_ni.timestamp:
dep = str(dependency)
tgt = str(target)
if specific_part_of_file_has_changed(dep, tgt):
@@ -571,7 +571,7 @@ int main() { printf("Hello, world!\n"); }
The <emphasis>content signature</emphasis>,
or MD5 checksum, of the contents of the
<varname>dependency</varname>
- file the list time the &target; was built.
+ file the last time the &target; was built.
</para>
</listitem>
@@ -583,7 +583,7 @@ int main() { printf("Hello, world!\n"); }
<listitem>
<para>
The size in bytes of the <varname>dependency</varname>
- file the list time the target was built.
+ file the last time the target was built.
</para>
</listitem>
@@ -595,7 +595,7 @@ int main() { printf("Hello, world!\n"); }
<listitem>
<para>
The modification time of the <varname>dependency</varname>
- file the list time the &target; was built.
+ file the last time the &target; was built.
</para>
</listitem>
diff --git a/doc/user/environments.xml b/doc/user/environments.xml
index 2089dfe..65eed72 100644
--- a/doc/user/environments.xml
+++ b/doc/user/environments.xml
@@ -385,9 +385,9 @@ environment, of directory names, suffixes, etc.
<para>
A &consenv;
- is a distinct object creating within
+ is a distinct object created within
a &SConscript; file and
- and which contains values that
+ which contains values that
affect how &SCons; decides
what action to use to build a target,
and even to define which targets
@@ -1630,7 +1630,7 @@ env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'
But doing so makes your &SConscript; file less portable,
(although in this case that may not be a huge concern
- since the directories you list are likley system-specific, anyway).
+ since the directories you list are likely system-specific, anyway).
</para>
diff --git a/doc/user/parseflags.xml b/doc/user/parseflags.xml
index fa35d49..46d6866 100644
--- a/doc/user/parseflags.xml
+++ b/doc/user/parseflags.xml
@@ -57,7 +57,7 @@
&SCons; construction environments have a &ParseFlags; method
that takes a set of typical command-line options
- and distrbutes them into the appropriate construction variables.
+ and distributes them into the appropriate construction variables.
Historically, it was created to support the &ParseConfig; method,
so it focuses on options used by the GNU Compiler Collection (GCC)
for the C and C++ toolchains.
diff --git a/runtest.py b/runtest.py
index cf8925c..9ffe374 100755
--- a/runtest.py
+++ b/runtest.py
@@ -8,9 +8,9 @@
#
# - unit tests - included in *Tests.py files from src/ dir
# - end-to-end tests - these are *.py files in test/ directory that
-# require custom SCons framework from QMTest/
+# require custom SCons framework from testing/
#
-# This script adds src/ and QMTest/ directories to PYTHONPATH,
+# This script adds src/ and testing/ directories to PYTHONPATH,
# performs test discovery and processes them according to options.
#
# With -p (--package) option, script tests specified package from
@@ -99,7 +99,6 @@ except ImportError as e: # python2
from Queue import Queue
import subprocess
-
cwd = os.getcwd()
baseline = 0
@@ -619,16 +618,18 @@ os.environ['SCONS_VERSION'] = version
old_pythonpath = os.environ.get('PYTHONPATH')
+# Clear _JAVA_OPTIONS which java tools output to stderr when run breaking tests
+if '_JAVA_OPTIONS' in os.environ:
+ del os.environ['_JAVA_OPTIONS']
+
# FIXME: the following is necessary to pull in half of the testing
# harness from $srcdir/etc. Those modules should be transfered
# to testing/, in which case this manipulation of PYTHONPATH
# should be able to go away.
pythonpaths = [ pythonpath_dir ]
-# Add path of the QMTest folder to PYTHONPATH
-# [ ] move used parts from QMTest to testing/framework/
scriptpath = os.path.dirname(os.path.realpath(__file__))
-pythonpaths.append(os.path.join(scriptpath, 'QMTest'))
+
# Add path for testing framework to PYTHONPATH
pythonpaths.append(os.path.join(scriptpath, 'testing', 'framework'))
@@ -772,10 +773,14 @@ os.environ["python_executable"] = python
# but time.time() does a better job on Linux systems, so let that be
# the non-Windows default.
-if sys.platform == 'win32':
- time_func = time.clock
-else:
- time_func = time.time
+#TODO: clean up when py2 support is dropped
+try:
+ time_func = time.perf_counter
+except AttributeError:
+ if sys.platform == 'win32':
+ time_func = time.clock
+ else:
+ time_func = time.time
if print_times:
print_time_func = lambda fmt, time: sys.stdout.write(fmt % time)
@@ -789,7 +794,7 @@ tests_passing = 0
tests_failing = 0
-def run_test(t, io_lock, async=True):
+def run_test(t, io_lock, run_async=True):
global tests_completed, tests_passing, tests_failing
header = ""
command_args = ['-tt']
@@ -932,4 +937,4 @@ else:
# tab-width:4
# indent-tabs-mode:nil
# End:
-# vim: set expandtab tabstop=4 shiftwidth=4: \ No newline at end of file
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 0ad7520..f0369e0 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -7,6 +7,17 @@
RELEASE 3.1.0.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE
+ From Daniel Moody:
+ - Updated FS.py to handle removal of splitunc function from python 3.7
+ - Updated the vc.py to ignore MSVS versions where not compiler could be found
+
+ From Matthew Marinets:
+ - Fixed an issue that caused the Java emitter to incorrectly parse arguments to constructors that
+ implemented a class.
+
+ From Bernard Blackham:
+ - Fixed handling of side-effects in task master (fixes #3013).
+
From Ray Donnelly:
- Fix the PATH created by scons.bat (and other .bat files) to provide a normalized
PATH. Some pythons in the 3.6 series are no longer able to handle paths which
@@ -20,22 +31,142 @@ RELEASE 3.1.0.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE
From William Deegan:
- Remove long deprecated SCons.Options code and tests. This removes BoolOption,EnumOption,
ListOption,PackageOption, and PathOption which have been replaced by *Variable() many years ago.
+ - Fix issue # 3106 MSVC if using MSVC_BATCH and target dir had a space would fail due to quirk in
+ MSVC's handling of escaped targetdirs when batch compiling.
+ - Re-Enable parallel SCons (-j) when running via Pypy
+ - Move SCons test framework files to testing/framework and remove all references to QMtest.
+ QMTest has not been used by SCons for some time now.
+ - Updated logic for mingw and clang on win32 to search default tool install paths if not
+ found in normal SCons PATH. If the user specifies PATH or tool specific paths they
+ will be used and the default paths below will be ignored.
+ - Default path for clang/clangxx : C:\Program Files\LLVM\bin
+ - Default path for mingw : C:\MinGW\bin and/or C:\mingw-w64\*\mingw64\bin
+ - Key program to locate mingw : mingw32-make (as the gcc with mingw prefix has no fixed name)
+ - Fix GH Issue #3141 unicode string in a TryAction() with python 2.7 crashes.
+ - Fixed issue causing stack trace when python Action function contains a unicode string when being
+ run with Python 2.7
+ - Add alternate path to QT install for Centos in qt tool: /usr/lib64/qt-3.3/bin
+ - Fix GH Issue #2580 - # in FRAMEWORKPATH doesn't get properly expanded. The # is left in the
+ command line.
From Andrew Featherstone
- Removed unused --warn options from the man page and source code.
+ From Philipp Maierhöfer
+ - Added a __hash__ method to the class Scons.Subst.Literal. Required when substituting Literal
+ objects when SCons runs with Python 3.
+ - Added missing FORTRANMODDIRPREFIX to the gfortran tool.
+
+ From Fredrik Medley:
+ - Fix exception when printing of EnviromentError messages.
+ Specifically, this fixes error reporting of the race condition when
+ initializing the cache which error previously was hidden.
+
From Daniel Moody:
- Updated Jar builder to handle nodes and directories better
- Updated Jar builder to flatten source list which could contain embedded lists
- Removed some magic numbers from jar.py on behalf of Mats Wichmann (mats@linux.com)
+ - Set the pickling protocal back to highest which was causing issues
+ with variant dir tests. This will cause issues if reading sconsigns
+ pickled with the previous lower protocal.
+ - Updated swig to setup default paths for windows
+ - Updated gettext tools to setup default paths for windows with Cygwin/MinGW setups
+ - Add common location for default paths for cygwin and mingw in Platform modules
+ - Updated YACC tool to work on windows with Cygwin/MinGW setups
+ - Set the pickling protocal back to highest which was causing issues
+ with variant dir tests. This will cause issues if reading sconsigns
+ pickled with the previous lower protocal.
+
+
+ From William Deegan:
+ - Updated logic for mingw and clang on win32 to search default tool install paths if not
+ found in normal SCons PATH. If the user specifies PATH or tool specific paths they
+ will be used and the default paths below will be ignored.
+ - Default path for clang/clangxx : C:\Program Files\LLVM\bin
+ - Default path for mingw : c:\MinGW\bin
From Gary Oberbrunner:
- Fix bug when Installing multiple subdirs outside the source tree
- fix to_str to handle None without raising exception
+ - Fix -jN for python 3.7
+
+ From Jonathon Reinhart:
+ - Replace all instances of `int main()` in C code with `int main(void)`.
+ Specifically, this fixes the test cases use by Configure.CheckCC() which
+ would fail when using -Wstrict-prototypes.
+
+ From Paweł Tomulik:
+ - In the testing framework, module TestCommon, fixed must_contain(),
+ must_not_contain(), and related methods of TestCommon class to work with
+ substrings located at zero offset.
+
+ From Richard West:
+ - Add SConstruct.py, Sconstruct.py, sconstruct.py to the search path for the root SConstruct file.
+ Allows easier debugging within Visual Studio
+ - Change setup.py to change the install directory (via pip, or setup.py install) from scons-#.#.#
+ to scons (Yielding <pythondir>/lib/scons/SCons/ instead of <pythondir>/lib/scons/SCons-#.#.#/).
+ This changes SCons to better comply with normal Python installation practices.
From Mats Wichmann:
+ - Recognize new java 9, 10, 11 (as 9.0 and 10.0, 11.0)
- Updated manpage scons.xml to fix a nested list problem
- - Updated doc terminionly: use prepend instead of append as appropriate
+ - Updated doc terminiology: use prepend instead of append as appropriate
+ - XML validity fixes from SConstruct.py change
+ - Update wiki links to new github location
+ - Update bug links to new github location
+ - Make it easier for SConscript() call to fail on missing script.
+ It was possible to call SCons.Warnings.warningAsException
+ (not documented as a user API) to make all warnings fail. Now
+ SConscript can take an optional must_exist flag which if true fails
+ if the script does not exist. Not failing on missing script is
+ now considered deprecated, and the first instance will print a
+ deprecation message. It is now also possible to flip the scons
+ behavior (which still defaults to warn, not fail) by calling
+ SCons.Script.set_missing_sconscript_error, which is also not a
+ documented interface at the moment.
+ - Convert TestCmd.read to use with statement on open (quiets 17 py3 warnings)
+ - Quiet py3 warning in UtilTests.py
+ - Fix tests specifying octal constants for py3
+ - Fix must_contain tests for py3
+ - RPM package generation:
+ - Fix supplying a build architecture
+ - Disable auto debug package generation on certain rpmbuild versions
+ - Adjust some tests to only supply build-id file on certain rpmbuild versions
+ - Tests now use a file fixture for the repeated (trivial) main.c program.
+ - Document and comment cleanup.
+ - Added new Environment Value X_RPM_EXTRADEFS to supply custom settings
+ to the specfile without adding specific logic for each one to scons.
+ - The test for Python.h needed by swig tests is moved to get_python_platform
+ so it does not have to be repeated in every test; picks up one failure
+ which did not make the (previously needed) check.
+ - If test opens os.devnull, register with atexit so file opens do not leak.
+ - Fix bugs in Win32 process spawn logic to handle OSError exception correctly.
+ - Use time.perf_counter instead of time.clock if it exists.
+ time.clock deprecated since py3.3, due to remove in 3.8. deprecation
+ warnings from py3.7 were failing a bunch of tests on Windows since they
+ mess up expected stderr.
+ - Prefer Py3's inspect.getfullargspec over deprecated inspect.getargspec.
+ Switched to "new" (standard in Py2.7) usage of receiving a namedtuple -
+ we were unpacking to a four-tuple, two of the items of which were unused;
+ getfullargspec returns a named tuple with seven elements so it is a
+ cleaner drop-in replacement using the namedtuple.
+ - Updated the test-framework.rst documentation.
+ - Remove obsoleted internal implementaiton of OrderedDict.
+ - Test for tar packaging fixups
+ - Stop using deprecated unittest asserts
+ - messages in strip-install-dir test now os-neutral
+ - Add xz compression format to packaging choices.
+ - Syntax cleanups - trailing blanks, use "is" to compare with None, etc.
+ Three uses of variables not defined are changed.
+
+ From Hao Wu
+ - typo in customized decider example in user guide
+
+ From Hao Wu
+ - Replace usage of unittest.TestSuite with unittest.main() (fix #3113)
+
+
+
RELEASE 3.0.1 - Mon, 12 Nov 2017 15:31:33 -0700
@@ -43,27 +174,43 @@ RELEASE 3.0.1 - Mon, 12 Nov 2017 15:31:33 -0700
- Jar can take multiple targets, and will make a duplicate jar from the sources for each target
- Added some warnings in case the Jar builder makes an implicit target
- Added Jar method and changed jar build to be more specific. Jar method will take in
- directories or classes as source. Added more tests to JAR to ensure the jar was
+ directories or classes as source. Added more tests to JAR to ensure the jar was
packaged with the correct compiled class files.
- - Added a No result test case to handle bug which seems unrelated to java in the
+ - Added a No result test case to handle bug which seems unrelated to java in the
swig-dependencies.py test, more info here: http://scons.tigris.org/issues/show_bug.cgi?id=2907
- Added a travis script to test on ubuntu trusty now that the project is on github
- so that Continuus Integration tests can be run automatically. It tests most case and considers
- no result a pass as well. Improving this script can install more dependincies allowing for more
+ so that Continuus Integration tests can be run automatically. It tests most case and considers
+ no result a pass as well. Improving this script can install more dependincies allowing for more
tests to be run.
-
+
From Daniel Moody:
- Updated the Jar Builder tool in Tool/__init__.py so that is doesn't force class files as
sources, allowing directories to be passed, which was causing test/Java/JAR.py to fail.
From William Deegan:
-
+ - Fix issue where code in utility routine to_String_for_subst() had code whose result was never
+ properly returned.
+ (Found by: James Rinkevich https://pairlist4.pair.net/pipermail/scons-users/2017-October/006358.html )
+ - Fixed Variables.GenerateHelpText() to now use the sort parameter. Due to incorrect 2to3 fixer changes
+ 8 years ago it was being used as a boolean parameter. Now you can specify sort to be a callable, or boolean
+ value. (True = normal sort). Manpage also updated.
+ - Fixed Tool loading logic from exploding sys.path with many site_scons/site_tools prepended on py3.
+ - Added additional output with time to process each SConscript file when using --debug=time.
- Rename internal function subst_dict() to create_subst_target_source_dict()
+ - Fix broken subst logic where a string with "$$(abc)" was being treated as "$(abc) and the
+ logic for removing the signature escapes was then failing because there was no closing "$)".
+ This was introduced by a pull request to allow recursive variable evaluations to yield a string
+ such as "$( $( some stuff $) $)".
+
+ From Thomas Berg:
+ - Fixed a regression in scons-3.0.0 where "from __future__ import print_function" was imposed
+ on the scope where SConstruct is executed, breaking existing builds using PY 2.7.
+
From Zachary Tessler:
- Fix incorrect warning for repeated identical builder calls that use overrides
-
+
RELEASE 3.0.0 - Mon, 18 Sep 2017 08:32:04 -0700
NOTE: This is a major release. You should expect that some targets may rebuild when upgrading.
@@ -136,9 +283,9 @@ will cause rebuilds.
- Add support for Visual Studio 2017. This support requires vswhere.exe a helper
tool installed with newer installs of 2017. SCons expects it to be located at
"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
- It can be downloaded separately at
+ It can be downloaded separately at
https://github.com/Microsoft/vswhere
-
+
From Tom Tanner:
- Allow nested $( ... $) sections
diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in
index f8e02a8..ac1dab2 100644
--- a/src/engine/MANIFEST.in
+++ b/src/engine/MANIFEST.in
@@ -19,7 +19,6 @@ SCons/Node/__init__.py
SCons/Node/Alias.py
SCons/Node/FS.py
SCons/Node/Python.py
-SCons/Options/*.py
SCons/PathList.py
SCons/Platform/__init__.py
SCons/Platform/aix.py
@@ -28,6 +27,7 @@ SCons/Platform/darwin.py
SCons/Platform/hpux.py
SCons/Platform/irix.py
SCons/Platform/os2.py
+SCons/Platform/mingw.py
SCons/Platform/posix.py
SCons/Platform/sunos.py
SCons/Platform/win32.py
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index a40229e..89ab366 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -107,6 +107,7 @@ import sys
import subprocess
import itertools
import inspect
+from collections import OrderedDict
import SCons.Debug
from SCons.Debug import logInstanceCreation
@@ -120,8 +121,7 @@ SUBST_CMD = SCons.Subst.SUBST_CMD
SUBST_SIG = SCons.Subst.SUBST_SIG
# we use these a lot, so try to optimize them
-is_String = SCons.Util.is_String
-is_List = SCons.Util.is_List
+from SCons.Util import is_String, is_List
class _null(object):
pass
@@ -807,7 +807,7 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw):
kw['env'] = new_env
try:
- return subprocess.Popen(cmd, **kw)
+ pobj = subprocess.Popen(cmd, **kw)
except EnvironmentError as e:
if error == 'raise': raise
# return a dummy Popen instance that only returns error
@@ -821,7 +821,13 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw):
def readline(self): return ''
def __iter__(self): return iter(())
stdout = stderr = f()
- return dummyPopen(e)
+ pobj = dummyPopen(e)
+ finally:
+ # clean up open file handles stored in parent's kw
+ for k, v in kw.items():
+ if hasattr(v, 'close'):
+ v.close()
+ return pobj
class CommandAction(_ActionAction):
@@ -841,8 +847,8 @@ class CommandAction(_ActionAction):
_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")
+ raise TypeError("CommandAction should be given only "
+ "a single command")
self.cmd_list = cmd
def __str__(self):
@@ -1289,7 +1295,7 @@ class ListAction(ActionBase):
return result
def get_varlist(self, target, source, env, executor=None):
- result = SCons.Util.OrderedDict()
+ result = OrderedDict()
for act in self.list:
for var in act.get_varlist(target, source, env, executor):
result[var] = True
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py
index 1f3e018..b9cc00b 100644
--- a/src/engine/SCons/ActionTests.py
+++ b/src/engine/SCons/ActionTests.py
@@ -23,6 +23,7 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
# Define a null function and a null class for use as builder actions.
# Where these are defined in the file seems to affect their byte-code
# contents, so try to minimize changes by defining them here, before we
@@ -30,10 +31,12 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
def GlobalFunc():
pass
+
class GlobalActFunc(object):
def __call__(self):
pass
+
import collections
import io
import os
@@ -47,7 +50,6 @@ import SCons.Environment
import SCons.Errors
import TestCmd
-import TestUnit
# Initial setup of the common environment for all tests,
# a temporary working directory containing a
@@ -56,7 +58,7 @@ import TestUnit
# We don't do this as a setUp() method because it's
# unnecessary to create a separate directory and script
# for each test, they can just use the one.
-test = TestCmd.TestCmd(workdir = '')
+test = TestCmd.TestCmd(workdir='')
test.write('act.py', """\
import os, string, sys
@@ -100,6 +102,7 @@ scons_env = SCons.Environment.Environment()
# so it doesn't clutter the output.
sys.stdout = io.StringIO()
+
class CmdStringHolder(object):
def __init__(self, cmd, literal=None):
self.data = str(cmd)
@@ -125,6 +128,7 @@ class CmdStringHolder(object):
else:
return self.data
+
class Environment(object):
def __init__(self, **kw):
self.d = {}
@@ -134,26 +138,36 @@ class Environment(object):
self.d['ESCAPE'] = scons_env['ESCAPE']
for k, v in kw.items():
self.d[k] = v
+
# Just use the underlying scons_subst*() utility methods.
def subst(self, strSubst, raw=0, target=[], source=[], conv=None):
return SCons.Subst.scons_subst(strSubst, self, raw,
target, source, self.d, conv=conv)
+
subst_target_source = subst
+
def subst_list(self, strSubst, raw=0, target=[], source=[], conv=None):
return SCons.Subst.scons_subst_list(strSubst, self, raw,
- target, source, self.d, conv=conv)
+ target, source, self.d, conv=conv)
+
def __getitem__(self, item):
return self.d[item]
+
def __setitem__(self, item, value):
self.d[item] = value
+
def has_key(self, item):
return item in self.d
+
def get(self, key, value=None):
return self.d.get(key, value)
+
def items(self):
return list(self.d.items())
+
def Dictionary(self):
return self.d
+
def Clone(self, **kw):
res = Environment()
res.d = SCons.Util.semi_deepcopy(self.d)
@@ -161,18 +175,33 @@ class Environment(object):
res.d[k] = v
return res
+ def sig_dict(self):
+ d = {}
+ for k, v in self.items(): d[k] = v
+ d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__']
+ d['TARGET'] = d['TARGETS'][0]
+ d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__']
+ d['SOURCE'] = d['SOURCES'][0]
+ return d
+
+
class DummyNode(object):
def __init__(self, name):
self.name = name
+
def str_for_display(self):
return '"' + self.name + '"'
+
def __str__(self):
return self.name
+
def rfile(self):
return self
+
def get_subst_proxy(self):
return self
+
if os.name == 'java':
python = os.path.join(sys.prefix, 'jython')
else:
@@ -181,6 +210,7 @@ _python_ = test.escape(python)
_null = SCons.Action._null
+
def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw):
def call_action(a, pos_call=pos_call, str_call=str_call, kw=kw):
a = SCons.Action.Action(*a, **kw)
@@ -218,6 +248,7 @@ def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw):
a = call_action((cmd, cmdstrfunc, 'a', 'b', 'c'))
assert a.varlist == ('a', 'b', 'c', 'x', 'y', 'z'), a.varlist
+
def test_positional_args(pos_callback, cmd, **kw):
"""Test that Action() returns the expected type and that positional args work.
"""
@@ -227,7 +258,9 @@ def test_positional_args(pos_callback, cmd, **kw):
if not isinstance(act, SCons.Action._ActionAction):
# only valid cmdstrfunc is None
- def none(a): pass
+ def none(a):
+ pass
+
test_varlist(pos_callback, none, cmd, None, **kw)
else:
# _ActionAction should have set these
@@ -236,22 +269,27 @@ def test_positional_args(pos_callback, cmd, **kw):
assert act.presub is _null, act.presub
assert act.chdir is None, act.chdir
assert act.exitstatfunc is SCons.Action.default_exitstatfunc, \
- act.exitstatfunc
+ act.exitstatfunc
def cmdstr(a):
assert hasattr(a, 'strfunction')
assert a.cmdstr == 'cmdstr', a.cmdstr
+
test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw)
- def fun(): pass
+ def fun():
+ pass
+
def strfun(a, fun=fun):
assert a.strfunction is fun, a.strfunction
assert a.cmdstr == _null, a.cmdstr
+
test_varlist(pos_callback, strfun, cmd, fun, **kw)
def none(a):
assert hasattr(a, 'strfunction')
assert a.cmdstr is None, a.cmdstr
+
test_varlist(pos_callback, none, cmd, None, **kw)
"""Test handling of bad cmdstrfunc arguments """
@@ -266,18 +304,21 @@ def test_positional_args(pos_callback, cmd, **kw):
return act
+
class ActionTestCase(unittest.TestCase):
"""Test the Action() factory function"""
def test_FunctionAction(self):
"""Test the Action() factory's creation of FunctionAction objects
"""
+
def foo():
pass
def func_action(a, foo=foo):
assert isinstance(a, SCons.Action.FunctionAction), a
assert a.execfunction == foo, a.execfunction
+
test_positional_args(func_action, foo)
# a singleton list returns the contained action
test_positional_args(func_action, [foo])
@@ -285,28 +326,33 @@ class ActionTestCase(unittest.TestCase):
def test_CommandAction(self):
"""Test the Action() factory's creation of CommandAction objects
"""
+
def cmd_action(a):
assert isinstance(a, SCons.Action.CommandAction), a
assert a.cmd_list == "string", a.cmd_list
+
test_positional_args(cmd_action, "string")
# a singleton list returns the contained action
test_positional_args(cmd_action, ["string"])
- try: unicode
- except NameError: pass
+ try:
+ unicode
+ except NameError:
+ pass
else:
a2 = eval("SCons.Action.Action(u'string')")
assert isinstance(a2, SCons.Action.CommandAction), a2
def line_action(a):
assert isinstance(a, SCons.Action.CommandAction), a
- assert a.cmd_list == [ "explicit", "command", "line" ], a.cmd_list
- test_positional_args(line_action, [[ "explicit", "command", "line" ]])
+ assert a.cmd_list == ["explicit", "command", "line"], a.cmd_list
+
+ test_positional_args(line_action, [["explicit", "command", "line"]])
def test_ListAction(self):
"""Test the Action() factory's creation of ListAction objects
"""
- a1 = SCons.Action.Action(["x", "y", "z", [ "a", "b", "c"]])
+ a1 = SCons.Action.Action(["x", "y", "z", ["a", "b", "c"]])
assert isinstance(a1, SCons.Action.ListAction), a1
assert a1.varlist == (), a1.varlist
assert isinstance(a1.list[0], SCons.Action.CommandAction), a1.list[0]
@@ -316,7 +362,7 @@ class ActionTestCase(unittest.TestCase):
assert isinstance(a1.list[2], SCons.Action.CommandAction), a1.list[2]
assert a1.list[2].cmd_list == "z", a1.list[2].cmd_list
assert isinstance(a1.list[3], SCons.Action.CommandAction), a1.list[3]
- assert a1.list[3].cmd_list == [ "a", "b", "c" ], a1.list[3].cmd_list
+ assert a1.list[3].cmd_list == ["a", "b", "c"], a1.list[3].cmd_list
a2 = SCons.Action.Action("x\ny\nz")
assert isinstance(a2, SCons.Action.ListAction), a2
@@ -364,20 +410,24 @@ class ActionTestCase(unittest.TestCase):
def test_CommandGeneratorAction(self):
"""Test the Action() factory's creation of CommandGeneratorAction objects
"""
+
def foo(): pass
def gen_action(a, foo=foo):
assert isinstance(a, SCons.Action.CommandGeneratorAction), a
assert a.generator is foo, a.generator
+
test_positional_args(gen_action, foo, generator=1)
def test_LazyCmdGeneratorAction(self):
"""Test the Action() factory's creation of lazy CommandGeneratorAction objects
"""
+
def lazy_action(a):
assert isinstance(a, SCons.Action.LazyAction), a
assert a.var == "FOO", a.var
assert a.cmd_list == "${FOO}", a.cmd_list
+
test_positional_args(lazy_action, "$FOO")
test_positional_args(lazy_action, "${FOO}")
@@ -398,6 +448,7 @@ class ActionTestCase(unittest.TestCase):
a2 = SCons.Action.Action(a1)
assert a2 is a1, a2
+
class _ActionActionTestCase(unittest.TestCase):
def test__init__(self):
@@ -421,7 +472,7 @@ class _ActionActionTestCase(unittest.TestCase):
assert a.chdir is None, a.chdir
assert a.exitstatfunc is SCons.Action.default_exitstatfunc, a.exitstatfunc
- assert SCons.Action._ActionAction(kwarg = 1)
+ assert SCons.Action._ActionAction(kwarg=1)
assert not hasattr(a, 'kwarg')
assert not hasattr(a, 'strfunction')
assert a.cmdstr is _null, a.cmdstr
@@ -445,7 +496,7 @@ class _ActionActionTestCase(unittest.TestCase):
assert not hasattr(a, 'strfunction')
assert a.cmdstr is None, a.cmdstr
- t = ('a','b','c')
+ t = ('a', 'b', 'c')
a = SCons.Action._ActionAction(varlist=t)
assert a.varlist == t, a.varlist
@@ -459,14 +510,14 @@ class _ActionActionTestCase(unittest.TestCase):
assert a.exitstatfunc is func1, a.exitstatfunc
a = SCons.Action._ActionAction(
- # alphabetical order ...
- chdir='x',
- cmdstr='cmdstr',
- exitstatfunc=func3,
- presub=func2,
- strfunction=func1,
- varlist=t,
- )
+ # alphabetical order ...
+ chdir='x',
+ cmdstr='cmdstr',
+ exitstatfunc=func3,
+ presub=func2,
+ strfunction=func1,
+ varlist=t,
+ )
assert a.chdir is 'x', a.chdir
assert a.cmdstr is 'cmdstr', a.cmdstr
assert a.exitstatfunc is func3, a.exitstatfunc
@@ -477,7 +528,10 @@ class _ActionActionTestCase(unittest.TestCase):
def test_dup_keywords(self):
"""Test handling of both cmdstr and strfunction arguments
"""
- def func(): pass
+
+ def func():
+ pass
+
try:
a = SCons.Action.Action('foo', cmdstr='string', strfunction=func)
except SCons.Errors.UserError as e:
@@ -505,6 +559,7 @@ class _ActionActionTestCase(unittest.TestCase):
try:
def execfunc(target, source, env):
pass
+
a = SCons.Action.Action(execfunc)
sio = io.StringIO()
@@ -524,9 +579,9 @@ class _ActionActionTestCase(unittest.TestCase):
save_print_actions = SCons.Action.print_actions
save_print_actions_presub = SCons.Action.print_actions_presub
save_execute_actions = SCons.Action.execute_actions
- #SCons.Action.print_actions = 0
+ # SCons.Action.print_actions = 0
- test = TestCmd.TestCmd(workdir = '')
+ test = TestCmd.TestCmd(workdir='')
test.subdir('sub', 'xyz')
os.chdir(test.workpath())
@@ -537,16 +592,19 @@ class _ActionActionTestCase(unittest.TestCase):
assert isinstance(target, list), type(target)
assert isinstance(source, list), type(source)
return 7
+
a = SCons.Action.Action(execfunc)
def firstfunc(target, source, env):
assert isinstance(target, list), type(target)
assert isinstance(source, list), type(source)
return 0
+
def lastfunc(target, source, env):
assert isinstance(target, list), type(target)
assert isinstance(source, list), type(source)
return 9
+
b = SCons.Action.Action([firstfunc, execfunc, lastfunc])
sio = io.StringIO()
@@ -686,8 +744,10 @@ class _ActionActionTestCase(unittest.TestCase):
SCons.Action.execute_actions = 1
result = []
+
def my_print_cmd_line(s, target, source, env, result=result):
result.append(s)
+
env['PRINT_CMD_LINE_FUNC'] = my_print_cmd_line
a("output", "input", env)
assert result == ["execfunc(['output'], ['input'])"], result
@@ -713,39 +773,43 @@ class _ActionActionTestCase(unittest.TestCase):
def func():
pass
+
a = SCons.Action.Action(func)
s = a.presub_lines(env)
assert s == ["func(target, source, env)"], s
def gen(target, source, env, for_signature):
return 'generat' + env.get('GEN', 'or')
+
a = SCons.Action.Action(gen, generator=1)
s = a.presub_lines(env)
assert s == ["generator"], s
- s = a.presub_lines(Environment(GEN = 'ed'))
+ s = a.presub_lines(Environment(GEN='ed'))
assert s == ["generated"], s
a = SCons.Action.Action("$ACT")
s = a.presub_lines(env)
assert s == [''], s
- s = a.presub_lines(Environment(ACT = 'expanded action'))
+ s = a.presub_lines(Environment(ACT='expanded action'))
assert s == ['expanded action'], s
def test_add(self):
"""Test adding Actions to stuff."""
+
# Adding actions to other Actions or to stuff that can
# be converted into an Action should produce a ListAction
# containing all the Actions.
def bar():
return None
+
baz = SCons.Action.Action(bar, generator=1)
act1 = SCons.Action.Action('foo bar')
- act2 = SCons.Action.Action([ 'foo', bar ])
+ act2 = SCons.Action.Action(['foo', bar])
sum = act1 + act2
assert isinstance(sum, SCons.Action.ListAction), str(sum)
assert len(sum.list) == 3, len(sum.list)
- assert [isinstance(x, SCons.Action.ActionBase) for x in sum.list] == [ 1, 1, 1 ]
+ assert [isinstance(x, SCons.Action.ActionBase) for x in sum.list] == [1, 1, 1]
sum = act1 + act1
assert isinstance(sum, SCons.Action.ListAction), str(sum)
@@ -781,13 +845,13 @@ class _ActionActionTestCase(unittest.TestCase):
assert len(sum.list) == 3, len(sum.list)
assert isinstance(sum.list[0], SCons.Action.CommandAction)
- sum = [ 'foo', 'bar' ] + act1
+ sum = ['foo', 'bar'] + act1
assert isinstance(sum, SCons.Action.ListAction), str(sum)
assert len(sum.list) == 3, sum.list
assert isinstance(sum.list[0], SCons.Action.CommandAction)
assert isinstance(sum.list[1], SCons.Action.CommandAction)
- sum = act2 + [ baz, bar ]
+ sum = act2 + [baz, bar]
assert isinstance(sum, SCons.Action.ListAction), str(sum)
assert len(sum.list) == 4, len(sum.list)
assert isinstance(sum.list[2], SCons.Action.CommandGeneratorAction)
@@ -814,17 +878,18 @@ class _ActionActionTestCase(unittest.TestCase):
else:
assert 0, "Should have thrown a TypeError adding to an int."
+
class CommandActionTestCase(unittest.TestCase):
def test___init__(self):
"""Test creation of a command Action
"""
a = SCons.Action.CommandAction(["xyzzy"])
- assert a.cmd_list == [ "xyzzy" ], a.cmd_list
+ assert a.cmd_list == ["xyzzy"], a.cmd_list
assert a.cmdstr is _null, a.cmdstr
a = SCons.Action.CommandAction(["abra"], cmdstr="cadabra")
- assert a.cmd_list == [ "abra" ], a.cmd_list
+ assert a.cmd_list == ["abra"], a.cmd_list
assert a.cmdstr == "cadabra", a.cmdstr
def test___str__(self):
@@ -944,6 +1009,7 @@ class CommandActionTestCase(unittest.TestCase):
def sf(target, source, env):
return "sf was called"
+
act = SCons.Action.CommandAction('foo', strfunction=sf)
s = act.strfunction([], [], env)
assert s == "sf was called", s
@@ -951,26 +1017,35 @@ class CommandActionTestCase(unittest.TestCase):
class actclass1(object):
def __init__(self, targets, sources, env):
pass
+
def __call__(self):
return 1
+
class actclass2(object):
def __init__(self, targets, sources, env):
self.strfunction = 5
+
def __call__(self):
return 2
+
class actclass3(object):
def __init__(self, targets, sources, env):
pass
+
def __call__(self):
return 3
+
def strfunction(self, targets, sources, env):
- return 'actclass3 on %s to get %s'%(str(sources[0]),
- str(targets[0]))
+ return 'actclass3 on %s to get %s' % (str(sources[0]),
+ str(targets[0]))
+
class actclass4(object):
def __init__(self, targets, sources, env):
pass
+
def __call__(self):
return 4
+
strfunction = None
act1 = SCons.Action.Action(actclass1([t1], [s1], env))
@@ -1067,7 +1142,7 @@ class CommandActionTestCase(unittest.TestCase):
act = SCons.Action.CommandAction(cmd4)
sources = [DummyNode('three'), DummyNode('four'), DummyNode('five')]
env2 = env.Clone()
- r = act([], source = sources, env = env2)
+ r = act([], source=sources, env=env2)
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'three' 'four'\n", c
@@ -1084,13 +1159,13 @@ class CommandActionTestCase(unittest.TestCase):
PATH = ''
env5['ENV']['XYZZY'] = 'xyzzy'
- r = act(target = DummyNode('out5'), source = [], env = env5)
+ r = act(target=DummyNode('out5'), source=[], env=env5)
act = SCons.Action.CommandAction(cmd5)
- r = act(target = DummyNode('out5'),
- source = [],
- env = env.Clone(ENV = {'XYZZY' : 'xyzzy5',
- 'PATH' : PATH}))
+ r = act(target=DummyNode('out5'),
+ source=[],
+ env=env.Clone(ENV={'XYZZY': 'xyzzy5',
+ 'PATH': PATH}))
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'out5' 'XYZZY'\nact.py: 'xyzzy5'\n", c
@@ -1098,19 +1173,22 @@ class CommandActionTestCase(unittest.TestCase):
class Obj(object):
def __init__(self, str):
self._str = str
+
def __str__(self):
return self._str
+
def rfile(self):
return self
+
def get_subst_proxy(self):
return self
cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd6)
- r = act(target = [Obj('111'), Obj('222')],
- source = [Obj('333'), Obj('444'), Obj('555')],
- env = env.Clone())
+ r = act(target=[Obj('111'), Obj('222')],
+ source=[Obj('333'), Obj('444'), Obj('555')],
+ env=env.Clone())
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: '222' '111' '333' '444'\n", c
@@ -1125,7 +1203,7 @@ class CommandActionTestCase(unittest.TestCase):
expect_nonexistent = 127
# Newer cygwin seems to return 126 for following
expect_nonexecutable_file = 126
- expect_nonexecutable_dir = 127
+ expect_nonexecutable_dir = 127
elif sys.platform.find('sunos') != -1:
expect_nonexistent = 1
expect_nonexecutable_file = 1
@@ -1133,22 +1211,22 @@ class CommandActionTestCase(unittest.TestCase):
else:
expect_nonexistent = 127
expect_nonexecutable_file = 126
- expect_nonexecutable_dir = 126
+ expect_nonexecutable_dir = 126
# Test that a nonexistent command returns 127
act = SCons.Action.CommandAction(python + "_no_such_command_")
- r = act([], [], env.Clone(out = outfile))
+ r = act([], [], env.Clone(out=outfile))
assert r.status == expect_nonexistent, r.status
# Test that trying to execute a directory returns 126
dir, tail = os.path.split(python)
act = SCons.Action.CommandAction(dir)
- r = act([], [], env.Clone(out = outfile))
+ r = act([], [], env.Clone(out=outfile))
assert r.status == expect_nonexecutable_file, r.status
# Test that trying to execute a non-executable file returns 126
act = SCons.Action.CommandAction(outfile)
- r = act([], [], env.Clone(out = outfile))
+ r = act([], [], env.Clone(out=outfile))
assert r.status == expect_nonexecutable_dir, r.status
act = SCons.Action.CommandAction('%s %s 1' % (_python_, exit_py))
@@ -1182,51 +1260,59 @@ class CommandActionTestCase(unittest.TestCase):
def test_set_handler(self):
"""Test setting the command handler...
"""
+
class Test(object):
def __init__(self):
self.executed = 0
- t=Test()
+
+ t = Test()
+
def func(sh, escape, cmd, args, env, test=t):
test.executed = args
test.shell = sh
return 0
+
def escape_func(cmd):
return '**' + cmd + '**'
class LiteralStr(object):
def __init__(self, x):
self.data = x
+
def __str__(self):
return self.data
+
def escape(self, escape_func):
return escape_func(self.data)
+
def is_literal(self):
return 1
a = SCons.Action.CommandAction(["xyzzy"])
- e = Environment(SPAWN = func)
+ e = Environment(SPAWN=func)
a([], [], e)
- assert t.executed == [ 'xyzzy' ], t.executed
+ assert t.executed == ['xyzzy'], t.executed
a = SCons.Action.CommandAction(["xyzzy"])
- e = Environment(SPAWN = '$FUNC', FUNC = func)
+ e = Environment(SPAWN='$FUNC', FUNC=func)
a([], [], e)
- assert t.executed == [ 'xyzzy' ], t.executed
+ assert t.executed == ['xyzzy'], t.executed
a = SCons.Action.CommandAction(["xyzzy"])
- e = Environment(SPAWN = func, SHELL = 'fake shell')
+ e = Environment(SPAWN=func, SHELL='fake shell')
a([], [], e)
- assert t.executed == [ 'xyzzy' ], t.executed
+ assert t.executed == ['xyzzy'], t.executed
assert t.shell == 'fake shell', t.shell
- a = SCons.Action.CommandAction([ LiteralStr("xyzzy") ])
- e = Environment(SPAWN = func, ESCAPE = escape_func)
+ a = SCons.Action.CommandAction([LiteralStr("xyzzy")])
+ e = Environment(SPAWN=func, ESCAPE=escape_func)
a([], [], e)
- assert t.executed == [ '**xyzzy**' ], t.executed
+ assert t.executed == ['**xyzzy**'], t.executed
def test_get_contents(self):
"""Test fetching the contents of a command Action
"""
+
def CmdGen(target, source, env, for_signature):
assert for_signature
return "%s %s" % \
@@ -1234,10 +1320,10 @@ class CommandActionTestCase(unittest.TestCase):
# The number 1 is there to make sure all args get converted to strings.
a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$(", "$bar",
- "$)", "stuff", "$)", "|", "$baz", 1])
+ "$)", "stuff", "$)", "|", "$baz", 1])
c = a.get_contents(target=[], source=[],
- env=Environment(foo = 'FFF', bar = 'BBB',
- baz = CmdGen))
+ env=Environment(foo='FFF', bar='BBB',
+ baz=CmdGen))
assert c == b"| | FFF BBB 1", c
# Make sure that CommandActions use an Environment's
@@ -1246,9 +1332,9 @@ class CommandActionTestCase(unittest.TestCase):
def subst_target_source(self, strSubst, raw=0, target=[], source=[]):
return 'subst_target_source: ' + strSubst
- c = a.get_contents(target=DummyNode('ttt'), source = DummyNode('sss'),
- env=SpecialEnvironment(foo = 'GGG', bar = 'CCC',
- baz = 'ZZZ'))
+ c = a.get_contents(target=DummyNode('ttt'), source=DummyNode('sss'),
+ env=SpecialEnvironment(foo='GGG', bar='CCC',
+ baz='ZZZ'))
assert c == b'subst_target_source: | $( $foo | $( $bar $) stuff $) | $baz 1', c
# We've discussed using the real target and source names in a
@@ -1296,6 +1382,7 @@ class CommandActionTestCase(unittest.TestCase):
c = a.get_contents(target=t, source=s, env=env)
assert c == b"s4 s5", c
+
class CommandGeneratorActionTestCase(unittest.TestCase):
def factory(self, act, **kw):
@@ -1305,16 +1392,18 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
def test___init__(self):
"""Test creation of a command generator Action
"""
+
def f(target, source, env):
pass
+
a = self.factory(f)
assert a.generator == f
def test___str__(self):
"""Test the pre-substitution strings for command generator Actions
"""
- def f(target, source, env, for_signature, self=self):
+ def f(target, source, env, for_signature, self=self):
# See if "env" is really a construction environment (or
# looks like one) by accessing the FindIxes attribute.
# (The Tool/mingw.py module has a generator that uses this,
@@ -1323,6 +1412,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
env.FindIxes
return "FOO"
+
a = self.factory(f)
s = str(a)
assert s == 'FOO', s
@@ -1330,10 +1420,12 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
def test_genstring(self):
"""Test the command generator Action genstring() method
"""
+
def f(target, source, env, for_signature, self=self):
dummy = env['dummy']
self.dummy = dummy
return "$FOO $TARGET $SOURCE $TARGETS $SOURCES"
+
a = self.factory(f)
self.dummy = 0
s = a.genstring([], [], env=Environment(FOO='xyzzy', dummy=1))
@@ -1350,13 +1442,16 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
s = env.subst("$FOO")
assert s == 'foo baz\nbar ack', s
return "$FOO"
+
def func_action(target, source, env, self=self):
- dummy=env['dummy']
+ dummy = env['dummy']
s = env.subst('$foo')
assert s == 'bar', s
- self.dummy=dummy
+ self.dummy = dummy
+
def f2(target, source, env, for_signature, f=func_action):
return f
+
def ch(sh, escape, cmd, args, env, self=self):
self.cmd.append(cmd)
self.args.append(args)
@@ -1365,30 +1460,34 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
self.dummy = 0
self.cmd = []
self.args = []
- a([], [], env=Environment(FOO = 'foo baz\nbar ack',
- dummy = 1,
- SPAWN = ch))
+ a([], [], env=Environment(FOO='foo baz\nbar ack',
+ dummy=1,
+ SPAWN=ch))
assert self.dummy == 1, self.dummy
assert self.cmd == ['foo', 'bar'], self.cmd
- assert self.args == [[ 'foo', 'baz' ], [ 'bar', 'ack' ]], self.args
+ assert self.args == [['foo', 'baz'], ['bar', 'ack']], self.args
b = self.factory(f2)
self.dummy = 0
- b(target=[], source=[], env=Environment(foo = 'bar',
- dummy = 2 ))
- assert self.dummy==2, self.dummy
+ b(target=[], source=[], env=Environment(foo='bar',
+ dummy=2))
+ assert self.dummy == 2, self.dummy
del self.dummy
class DummyFile(object):
def __init__(self, t):
self.t = t
+
def rfile(self):
self.t.rfile_called = 1
return self
+
def get_subst_proxy(self):
return self
+
def f3(target, source, env, for_signature):
return ''
+
c = self.factory(f3)
c(target=[], source=DummyFile(self), env=Environment())
assert self.rfile_called
@@ -1396,19 +1495,20 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
def test_get_contents(self):
"""Test fetching the contents of a command generator Action
"""
+
def f(target, source, env, for_signature):
foo = env['foo']
bar = env['bar']
assert for_signature, for_signature
return [["guux", foo, "$(", "$ignore", "$)", bar,
- '${test("$( foo $bar $)")}' ]]
+ '${test("$( foo $bar $)")}']]
def test(mystr):
assert mystr == "$( foo $bar $)", mystr
return "test"
- env = Environment(foo = 'FFF', bar = 'BBB',
- ignore = 'foo', test=test)
+ env = Environment(foo='FFF', bar='BBB',
+ ignore='foo', test=test)
a = self.factory(f)
c = a.get_contents(target=[], source=[], env=env)
assert c == b"guux FFF BBB test", c
@@ -1422,9 +1522,10 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
# Since the python bytecode has per version differences, we need different expected results per version
func_matches = {
- (2,7) : bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,5) : bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,6) : bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (2, 7): bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 5): bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 6): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (3, 7): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
}
meth_matches = [
@@ -1438,15 +1539,17 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
def f_local(target, source, env, for_signature):
return SCons.Action.Action(LocalFunc)
- env = Environment(XYZ = 'foo')
+ env = Environment(XYZ='foo')
a = self.factory(f_global)
c = a.get_contents(target=[], source=[], env=env)
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+repr(func_matches[sys.version_info[:2]])
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected \n" + repr(
+ func_matches[sys.version_info[:2]])
a = self.factory(f_local)
c = a.get_contents(target=[], source=[], env=env)
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+repr(func_matches[sys.version_info[:2]])
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected \n" + repr(
+ func_matches[sys.version_info[:2]])
def f_global(target, source, env, for_signature):
return SCons.Action.Action(GlobalFunc, varlist=['XYZ'])
@@ -1470,12 +1573,16 @@ class FunctionActionTestCase(unittest.TestCase):
def test___init__(self):
"""Test creation of a function Action
"""
+
def func1():
pass
+
def func2():
pass
+
def func3():
pass
+
def func4():
pass
@@ -1483,15 +1590,17 @@ class FunctionActionTestCase(unittest.TestCase):
assert a.execfunction == func1, a.execfunction
assert isinstance(a.strfunction, types.MethodType), type(a.strfunction)
- a = SCons.Action.FunctionAction(func2, { 'strfunction' : func3 })
+ a = SCons.Action.FunctionAction(func2, {'strfunction': func3})
assert a.execfunction == func2, a.execfunction
assert a.strfunction == func3, a.strfunction
def test___str__(self):
"""Test the __str__() method for function Actions
"""
+
def func1():
pass
+
a = SCons.Action.FunctionAction(func1, {})
s = str(a)
assert s == "func1(target, source, env)", s
@@ -1499,6 +1608,7 @@ class FunctionActionTestCase(unittest.TestCase):
class class1(object):
def __call__(self):
pass
+
a = SCons.Action.FunctionAction(class1(), {})
s = str(a)
assert s == "class1(target, source, env)", s
@@ -1507,22 +1617,25 @@ class FunctionActionTestCase(unittest.TestCase):
"""Test executing a function Action
"""
self.inc = 0
+
def f(target, source, env):
s = env['s']
s.inc = s.inc + 1
s.target = target
- s.source=source
+ s.source = source
assert env.subst("$BAR") == 'foo bar', env.subst("$BAR")
return 0
+
a = SCons.Action.FunctionAction(f, {})
- a(target=1, source=2, env=Environment(BAR = 'foo bar',
- s = self))
+ a(target=1, source=2, env=Environment(BAR='foo bar',
+ s=self))
assert self.inc == 1, self.inc
assert self.source == [2], self.source
assert self.target == [1], self.target
global count
count = 0
+
def function1(target, source, env):
global count
count = count + 1
@@ -1532,7 +1645,7 @@ class FunctionActionTestCase(unittest.TestCase):
return 1
act = SCons.Action.FunctionAction(function1, {})
- r = act(target = [outfile, outfile2], source=[], env=Environment())
+ r = act(target=[outfile, outfile2], source=[], env=Environment())
assert r.status == 1, r.status
assert count == 1, count
@@ -1547,7 +1660,7 @@ class FunctionActionTestCase(unittest.TestCase):
f.write("class1a\n")
act = SCons.Action.FunctionAction(class1a, {})
- r = act([], [], Environment(out = outfile))
+ r = act([], [], Environment(out=outfile))
assert isinstance(r.status, class1a), r.status
c = test.read(outfile, 'r')
assert c == "class1a\n", c
@@ -1559,7 +1672,7 @@ class FunctionActionTestCase(unittest.TestCase):
return 2
act = SCons.Action.FunctionAction(class1b(), {})
- r = act([], [], Environment(out = outfile))
+ r = act([], [], Environment(out=outfile))
assert r.status == 2, r.status
c = test.read(outfile, 'r')
assert c == "class1b\n", c
@@ -1567,11 +1680,13 @@ class FunctionActionTestCase(unittest.TestCase):
def build_it(target, source, env, executor=None, self=self):
self.build_it = 1
return 0
+
def string_it(target, source, env, executor=None, self=self):
self.string_it = 1
return None
+
act = SCons.Action.FunctionAction(build_it,
- { 'strfunction' : string_it })
+ {'strfunction': string_it})
r = act([], [], Environment())
assert r == 0, r
assert self.build_it
@@ -1585,15 +1700,18 @@ class FunctionActionTestCase(unittest.TestCase):
pass
func_matches = {
- (2,7) : bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,5) : bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,6) : bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (2, 7): bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 5): bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 6): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (3, 7): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
+
}
meth_matches = {
- (2,7) : bytearray(b'1, 1, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,5) : bytearray(b'1, 1, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,6) : bytearray(b'1, 1, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (2, 7): bytearray(b'1, 1, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 5): bytearray(b'1, 1, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 6): bytearray(b'1, 1, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (3, 7): bytearray(b'1, 1, 0, 0,(),(),(d\x00S\x00),(),()'),
}
def factory(act, **kw):
@@ -1601,18 +1719,20 @@ class FunctionActionTestCase(unittest.TestCase):
a = factory(GlobalFunc)
c = a.get_contents(target=[], source=[], env=Environment())
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
-
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ func_matches[sys.version_info[:2]])
a = factory(LocalFunc)
c = a.get_contents(target=[], source=[], env=Environment())
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ func_matches[sys.version_info[:2]])
matches_foo = func_matches[sys.version_info[:2]] + b'foo'
a = factory(GlobalFunc, varlist=['XYZ'])
c = a.get_contents(target=[], source=[], env=Environment())
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ func_matches[sys.version_info[:2]])
# assert c in func_matches, repr(c)
c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo'))
@@ -1623,8 +1743,8 @@ class FunctionActionTestCase(unittest.TestCase):
a = factory(GlobalFunc, varlist='XYZ')
c = a.get_contents(target=[], source=[], env=Environment())
# assert c in func_matches, repr(c)
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
-
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ func_matches[sys.version_info[:2]])
c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo'))
assert c in matches_foo, repr(c)
@@ -1632,6 +1752,7 @@ class FunctionActionTestCase(unittest.TestCase):
class Foo(object):
def get_contents(self, target, source, env):
return b'xyzzy'
+
a = factory(Foo())
c = a.get_contents(target=[], source=[], env=Environment())
assert c == b'xyzzy', repr(c)
@@ -1639,14 +1760,17 @@ class FunctionActionTestCase(unittest.TestCase):
class LocalClass(object):
def LocalMethod(self):
pass
+
lc = LocalClass()
a = factory(lc.LocalMethod)
c = a.get_contents(target=[], source=[], env=Environment())
- assert c == meth_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(meth_matches[sys.version_info[:2]])
+ assert c == meth_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ meth_matches[sys.version_info[:2]])
def test_strfunction(self):
"""Test the FunctionAction.strfunction() method
"""
+
def func():
pass
@@ -1665,13 +1789,16 @@ class FunctionActionTestCase(unittest.TestCase):
s = a.strfunction(target=[], source=[], env=Environment())
assert s == 'function', s
+
class ListActionTestCase(unittest.TestCase):
def test___init__(self):
"""Test creation of a list of subsidiary Actions
"""
+
def func():
pass
+
a = SCons.Action.ListAction(["x", func, ["y", "z"]])
assert isinstance(a.list[0], SCons.Action.CommandAction)
assert isinstance(a.list[1], SCons.Action.FunctionAction)
@@ -1681,10 +1808,13 @@ class ListActionTestCase(unittest.TestCase):
def test___str__(self):
"""Test the __str__() method for a list of subsidiary Actions
"""
- def f(target,source,env):
+
+ def f(target, source, env):
pass
- def g(target,source,env):
+
+ def g(target, source, env):
pass
+
a = SCons.Action.ListAction([f, g, "XXX", f])
s = str(a)
assert s == "f(target, source, env)\ng(target, source, env)\nXXX\nf(target, source, env)", s
@@ -1692,10 +1822,13 @@ class ListActionTestCase(unittest.TestCase):
def test_genstring(self):
"""Test the genstring() method for a list of subsidiary Actions
"""
- def f(target,source,env):
+
+ def f(target, source, env):
pass
- def g(target,source,env,for_signature):
+
+ def g(target, source, env, for_signature):
return 'generated %s %s' % (target[0], source[0])
+
g = SCons.Action.Action(g, generator=1)
a = SCons.Action.ListAction([f, g, "XXX", f])
s = a.genstring(['foo.x'], ['bar.y'], Environment())
@@ -1705,11 +1838,13 @@ class ListActionTestCase(unittest.TestCase):
"""Test executing a list of subsidiary Actions
"""
self.inc = 0
- def f(target,source,env):
+
+ def f(target, source, env):
s = env['s']
s.inc = s.inc + 1
+
a = SCons.Action.ListAction([f, f, f])
- a([], [], Environment(s = self))
+ a([], [], Environment(s=self))
assert self.inc == 3, self.inc
cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile)
@@ -1729,8 +1864,9 @@ class ListActionTestCase(unittest.TestCase):
def __init__(self, target, source, env):
with open(env['out'], 'a') as f:
f.write("class2b\n")
+
act = SCons.Action.ListAction([cmd2, function2, class2a(), class2b])
- r = act([], [], Environment(out = outfile))
+ r = act([], [], Environment(out=outfile))
assert isinstance(r.status, class2b), r.status
c = test.read(outfile, 'r')
assert c == "act.py: 'syzygy'\nfunction2\nclass2a\nclass2b\n", c
@@ -1738,18 +1874,21 @@ class ListActionTestCase(unittest.TestCase):
def test_get_contents(self):
"""Test fetching the contents of a list of subsidiary Actions
"""
- self.foo=0
+ self.foo = 0
+
def gen(target, source, env, for_signature):
s = env['s']
- s.foo=1
+ s.foo = 1
return "y"
+
a = SCons.Action.ListAction(["x",
SCons.Action.Action(gen, generator=1),
"z"])
- c = a.get_contents(target=[], source=[], env=Environment(s = self))
- assert self.foo==1, self.foo
+ c = a.get_contents(target=[], source=[], env=Environment(s=self))
+ assert self.foo == 1, self.foo
assert c == b"xyz", c
+
class LazyActionTestCase(unittest.TestCase):
def test___init__(self):
"""Test creation of a lazy-evaluation Action
@@ -1768,8 +1907,10 @@ class LazyActionTestCase(unittest.TestCase):
def test_genstring(self):
"""Test the lazy-evaluation Action genstring() method
"""
+
def f(target, source, env):
pass
+
a = SCons.Action.Action('$BAR')
env1 = Environment(BAR=f, s=self)
env2 = Environment(BAR='xxx', s=self)
@@ -1781,15 +1922,17 @@ class LazyActionTestCase(unittest.TestCase):
def test_execute(self):
"""Test executing a lazy-evaluation Action
"""
+
def f(target, source, env):
s = env['s']
- s.test=1
+ s.test = 1
return 0
+
a = SCons.Action.Action('$BAR')
- a([], [], env=Environment(BAR = f, s = self))
+ a([], [], env=Environment(BAR=f, s=self))
assert self.test == 1, self.test
cmd = r'%s %s %s lazy' % (_python_, act_py, outfile)
- a([], [], env=Environment(BAR = cmd, s = self))
+ a([], [], env=Environment(BAR=cmd, s=self))
c = test.read(outfile, 'r')
assert c == "act.py: 'lazy'\n", c
@@ -1797,7 +1940,7 @@ class LazyActionTestCase(unittest.TestCase):
"""Test fetching the contents of a lazy-evaluation Action
"""
a = SCons.Action.Action("${FOO}")
- env = Environment(FOO = [["This", "is", "a", "test"]])
+ env = Environment(FOO=[["This", "is", "a", "test"]])
c = a.get_contents(target=[], source=[], env=env)
assert c == b"This is a test", c
@@ -1808,11 +1951,11 @@ class LazyActionTestCase(unittest.TestCase):
def LocalFunc():
pass
-
func_matches = {
- (2,7) : bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,5) : bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
- (3,6) : bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (2, 7): bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 5): bytearray(b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'),
+ (3, 6): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
+ (3, 7): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'),
}
meth_matches = [
@@ -1823,27 +1966,26 @@ class LazyActionTestCase(unittest.TestCase):
def factory(act, **kw):
return SCons.Action.FunctionAction(act, kw)
-
a = SCons.Action.Action("${FOO}")
- env = Environment(FOO = factory(GlobalFunc))
+ env = Environment(FOO=factory(GlobalFunc))
c = a.get_contents(target=[], source=[], env=env)
# assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches])
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
-
-
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ func_matches[sys.version_info[:2]])
- env = Environment(FOO = factory(LocalFunc))
+ env = Environment(FOO=factory(LocalFunc))
c = a.get_contents(target=[], source=[], env=env)
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ func_matches[sys.version_info[:2]])
# matches_foo = [x + b"foo" for x in func_matches]
matches_foo = func_matches[sys.version_info[:2]] + b'foo'
-
- env = Environment(FOO = factory(GlobalFunc, varlist=['XYZ']))
+ env = Environment(FOO=factory(GlobalFunc, varlist=['XYZ']))
c = a.get_contents(target=[], source=[], env=env)
- assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+ assert c == func_matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ func_matches[sys.version_info[:2]])
env['XYZ'] = 'foo'
c = a.get_contents(target=[], source=[], env=env)
@@ -1853,36 +1995,39 @@ class LazyActionTestCase(unittest.TestCase):
class ActionCallerTestCase(unittest.TestCase):
def test___init__(self):
"""Test creation of an ActionCaller"""
- ac = SCons.Action.ActionCaller(1, [2, 3], {'FOO' : 4, 'BAR' : 5})
+ ac = SCons.Action.ActionCaller(1, [2, 3], {'FOO': 4, 'BAR': 5})
assert ac.parent == 1, ac.parent
assert ac.args == [2, 3], ac.args
- assert ac.kw == {'FOO' : 4, 'BAR' : 5}, ac.kw
+ assert ac.kw == {'FOO': 4, 'BAR': 5}, ac.kw
def test_get_contents(self):
"""Test fetching the contents of an ActionCaller"""
+
def strfunc():
pass
def LocalFunc():
pass
-
matches = {
- (2,7) : b'd\x00\x00S',
- (3,5) : b'd\x00\x00S',
- (3,6) : b'd\x00S\x00',
- }
+ (2, 7): b'd\x00\x00S',
+ (3, 5): b'd\x00\x00S',
+ (3, 6): b'd\x00S\x00',
+ (3, 7): b'd\x00S\x00',
+ }
af = SCons.Action.ActionFactory(GlobalFunc, strfunc)
ac = SCons.Action.ActionCaller(af, [], {})
c = ac.get_contents([], [], Environment())
- assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
+ assert c == matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ matches[sys.version_info[:2]])
af = SCons.Action.ActionFactory(LocalFunc, strfunc)
ac = SCons.Action.ActionCaller(af, [], {})
c = ac.get_contents([], [], Environment())
- assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
+ assert c == matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ matches[sys.version_info[:2]])
class LocalActFunc(object):
def __call__(self):
@@ -1891,12 +2036,14 @@ class ActionCallerTestCase(unittest.TestCase):
af = SCons.Action.ActionFactory(GlobalActFunc(), strfunc)
ac = SCons.Action.ActionCaller(af, [], {})
c = ac.get_contents([], [], Environment())
- assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
+ assert c == matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ matches[sys.version_info[:2]])
af = SCons.Action.ActionFactory(LocalActFunc(), strfunc)
ac = SCons.Action.ActionCaller(af, [], {})
c = ac.get_contents([], [], Environment())
- assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
+ assert c == matches[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected one of \n" + repr(
+ matches[sys.version_info[:2]])
matches = [
b"<built-in function str>",
@@ -1914,12 +2061,14 @@ class ActionCallerTestCase(unittest.TestCase):
def test___call__(self):
"""Test calling an ActionCaller"""
actfunc_args = []
+
def actfunc(a1, a2, a3, args=actfunc_args):
args.extend([a1, a2, a3])
+
def strfunc(a1, a2, a3):
pass
- e = Environment(FOO = 2, BAR = 5)
+ e = Environment(FOO=2, BAR=5)
af = SCons.Action.ActionFactory(actfunc, strfunc)
ac = SCons.Action.ActionCaller(af, ['$__env__', '$FOO', 3], {})
@@ -1929,7 +2078,7 @@ class ActionCallerTestCase(unittest.TestCase):
assert actfunc_args[2] == 3, actfunc_args
del actfunc_args[:]
- ac = SCons.Action.ActionCaller(af, [], {'a3' : '$__env__', 'a2' : '$BAR', 'a1' : 4})
+ ac = SCons.Action.ActionCaller(af, [], {'a3': '$__env__', 'a2': '$BAR', 'a1': 4})
ac([], [], e)
assert actfunc_args[0] == 4, actfunc_args
assert actfunc_args[1] == '5', actfunc_args
@@ -1939,29 +2088,35 @@ class ActionCallerTestCase(unittest.TestCase):
def test_strfunction(self):
"""Test calling the ActionCaller strfunction() method"""
strfunc_args = []
+
def actfunc(a1, a2, a3, a4):
pass
+
def strfunc(a1, a2, a3, a4, args=strfunc_args):
args.extend([a1, a2, a3, a4])
af = SCons.Action.ActionFactory(actfunc, strfunc)
ac = SCons.Action.ActionCaller(af, [1, '$FOO', 3, '$WS'], {})
- ac.strfunction([], [], Environment(FOO = 2, WS='white space'))
+ ac.strfunction([], [], Environment(FOO=2, WS='white space'))
assert strfunc_args == [1, '2', 3, 'white space'], strfunc_args
del strfunc_args[:]
- d = {'a3' : 6, 'a2' : '$BAR', 'a1' : 4, 'a4' : '$WS'}
+ d = {'a3': 6, 'a2': '$BAR', 'a1': 4, 'a4': '$WS'}
ac = SCons.Action.ActionCaller(af, [], d)
- ac.strfunction([], [], Environment(BAR = 5, WS='w s'))
+ ac.strfunction([], [], Environment(BAR=5, WS='w s'))
assert strfunc_args == [4, '5', 6, 'w s'], strfunc_args
+
class ActionFactoryTestCase(unittest.TestCase):
def test___init__(self):
"""Test creation of an ActionFactory"""
+
def actfunc():
pass
+
def strfunc():
pass
+
ac = SCons.Action.ActionFactory(actfunc, strfunc)
assert ac.actfunc is actfunc, ac.actfunc
assert ac.strfunc is strfunc, ac.strfunc
@@ -1970,10 +2125,13 @@ class ActionFactoryTestCase(unittest.TestCase):
"""Test calling whatever's returned from an ActionFactory"""
actfunc_args = []
strfunc_args = []
+
def actfunc(a1, a2, a3, args=actfunc_args):
args.extend([a1, a2, a3])
+
def strfunc(a1, a2, a3, args=strfunc_args):
args.extend([a1, a2, a3])
+
af = SCons.Action.ActionFactory(actfunc, strfunc)
af(3, 6, 9)([], [], Environment())
assert actfunc_args == [3, 6, 9], actfunc_args
@@ -1987,8 +2145,8 @@ class ActionCompareTestCase(unittest.TestCase):
Basically ensures we can locate the builder, comparing it to
itself along the way."""
- bar = SCons.Builder.Builder(action = {})
- env = Environment( BUILDERS = {'BAR' : bar} )
+ bar = SCons.Builder.Builder(action={})
+ env = Environment(BUILDERS={'BAR': bar})
name = bar.get_name(env)
assert name == 'BAR', name
@@ -1997,12 +2155,12 @@ class ActionCompareTestCase(unittest.TestCase):
Ensure that we can compare builders (and thereby actions) to
each other safely."""
- foo = SCons.Builder.Builder(action = '$FOO', suffix = '.foo')
- bar = SCons.Builder.Builder(action = {})
+ foo = SCons.Builder.Builder(action='$FOO', suffix='.foo')
+ bar = SCons.Builder.Builder(action={})
assert foo != bar
assert foo.action != bar.action
- env = Environment( BUILDERS = {'FOO' : foo,
- 'BAR' : bar} )
+ env = Environment(BUILDERS={'FOO': foo,
+ 'BAR': bar})
name = foo.get_name(env)
assert name == 'FOO', name
name = bar.get_name(env)
@@ -2016,14 +2174,14 @@ class ActionCompareTestCase(unittest.TestCase):
where one of the builders has a suffix dictionary with a None
key."""
- foo = SCons.Builder.Builder(action = '$FOO', suffix = '.foo')
- bar = SCons.Builder.Builder(action = {}, suffix={None:'.bar'})
+ foo = SCons.Builder.Builder(action='$FOO', suffix='.foo')
+ bar = SCons.Builder.Builder(action={}, suffix={None: '.bar'})
bar.add_action('.cow', "$MOO")
- dog = SCons.Builder.Builder(suffix = '.bar')
+ dog = SCons.Builder.Builder(suffix='.bar')
- env = Environment( BUILDERS = {'FOO' : foo,
- 'BAR' : bar,
- 'DOG' : dog} )
+ env = Environment(BUILDERS={'FOO': foo,
+ 'BAR': bar,
+ 'DOG': dog})
assert foo.get_name(env) == 'FOO', foo.get_name(env)
assert bar.get_name(env) == 'BAR', bar.get_name(env)
@@ -2032,9 +2190,11 @@ class ActionCompareTestCase(unittest.TestCase):
class TestClass(object):
"""A test class used by ObjectContentsTestCase.test_object_contents"""
+
def __init__(self):
self.a = "a"
self.b = "b"
+
def method(self, arg):
pass
@@ -2050,14 +2210,15 @@ class ObjectContentsTestCase(unittest.TestCase):
# Since the python bytecode has per version differences, we need different expected results per version
expected = {
- (2,7) : bytearray(b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()'),
- (3,5) : bytearray(b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()'),
- (3,6) : bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'),
+ (2, 7): bytearray(b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()'),
+ (3, 5): bytearray(b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()'),
+ (3, 6): bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'),
+ (3, 7): bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'),
}
c = SCons.Action._function_contents(func1)
- assert c == expected[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected[sys.version_info[:2]])
-
+ assert c == expected[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected \n" + "\n" + repr(
+ expected[sys.version_info[:2]])
def test_object_contents(self):
"""Test that Action._object_contents works"""
@@ -2070,12 +2231,18 @@ class ObjectContentsTestCase(unittest.TestCase):
# Since the python bytecode has per version differences, we need different expected results per version
expected = {
- (2,7): bytearray(b"{TestClass:__main__}[[[(<type \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<type \'object\'>,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}"),
- (3,5): bytearray(b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}"),
- (3,6): bytearray(b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(),(),(d\x00S\x00),(),()}}{{{a=a,b=b}}}"),
+ (2, 7): bytearray(
+ b"{TestClass:__main__}[[[(<type \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<type \'object\'>,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}"),
+ (3, 5): bytearray(
+ b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}"),
+ (3, 6): bytearray(
+ b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(),(),(d\x00S\x00),(),()}}{{{a=a,b=b}}}"),
+ (3, 7): bytearray(
+ b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(),(),(d\x00S\x00),(),()}}{{{a=a,b=b}}}"),
}
- assert c == expected[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected[sys.version_info[:2]])
+ assert c == expected[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected \n" + "\n" + repr(
+ expected[sys.version_info[:2]])
def test_code_contents(self):
"""Test that Action._code_contents works"""
@@ -2085,36 +2252,18 @@ class ObjectContentsTestCase(unittest.TestCase):
# Since the python bytecode has per version differences, we need different expected results per version
expected = {
- (2,7) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)'),
- (3,5) : bytearray(b'0, 0, 0, 0,(N.),(print),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)'),
- (3,6) : bytearray(b'0, 0, 0, 0,(N.),(print),(e\x00d\x00\x83\x01\x01\x00d\x01S\x00)'),
+ (2, 7): bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)'),
+ (3, 5): bytearray(b'0, 0, 0, 0,(N.),(print),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)'),
+ (3, 6): bytearray(b'0, 0, 0, 0,(N.),(print),(e\x00d\x00\x83\x01\x01\x00d\x01S\x00)'),
+ (3, 7): bytearray(b'0, 0, 0, 0,(N.),(print),(e\x00d\x00\x83\x01\x01\x00d\x01S\x00)'),
}
- assert c == expected[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+"\n"+expected[sys.version_info[:2]]
-
+ assert c == expected[sys.version_info[:2]], "Got\n" + repr(c) + "\nExpected \n" + "\n" + expected[
+ sys.version_info[:2]]
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [ _ActionActionTestCase,
- ActionTestCase,
- CommandActionTestCase,
- CommandGeneratorActionTestCase,
- FunctionActionTestCase,
- ListActionTestCase,
- LazyActionTestCase,
- ActionCallerTestCase,
- ActionFactoryTestCase,
- ActionCompareTestCase,
- ObjectContentsTestCase ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
-
- TestUnit.run(suite)
-
- # Swap this for above to debug otherwise you can't run individual tests as TestUnit is swallowing arguments
- # unittest.main()
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py
index ac91c85..ab80808 100644
--- a/src/engine/SCons/CacheDir.py
+++ b/src/engine/SCons/CacheDir.py
@@ -56,6 +56,10 @@ def CacheRetrieveFunc(target, source, env):
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
diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py
index 494db98..ef87746 100644
--- a/src/engine/SCons/CacheDirTests.py
+++ b/src/engine/SCons/CacheDirTests.py
@@ -29,7 +29,6 @@ import sys
import unittest
from TestCmd import TestCmd
-import TestUnit
import SCons.CacheDir
@@ -287,16 +286,7 @@ class FileTestCase(BaseTestCase):
SCons.CacheDir.CacheRetrieveSilent = save_CacheRetrieveSilent
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [
- CacheDirTestCase,
- FileTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
-
+ unittest.main()
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py
index abaf00d..84aa992 100644
--- a/src/engine/SCons/Conftest.py
+++ b/src/engine/SCons/Conftest.py
@@ -136,7 +136,7 @@ def CheckBuilder(context, text = None, language = None):
if not text:
text = """
-int main() {
+int main(void) {
return 0;
}
"""
@@ -157,7 +157,7 @@ def CheckCC(context):
"""
context.Display("Checking whether the C compiler works... ")
text = """
-int main()
+int main(void)
{
return 0;
}
@@ -177,7 +177,7 @@ def CheckSHCC(context):
"""
context.Display("Checking whether the (shared) C compiler works... ")
text = """
-int foo()
+int foo(void)
{
return 0;
}
@@ -197,7 +197,7 @@ def CheckCXX(context):
"""
context.Display("Checking whether the C++ compiler works... ")
text = """
-int main()
+int main(void)
{
return 0;
}
@@ -217,7 +217,7 @@ def CheckSHCXX(context):
"""
context.Display("Checking whether the (shared) C++ compiler works... ")
text = """
-int main()
+int main(void)
{
return 0;
}
@@ -290,7 +290,7 @@ char %s();""" % function_name
#include <assert.h>
%(hdr)s
-int main() {
+int main(void) {
#if defined (__stub_%(name)s) || defined (__stub___%(name)s)
fail fail fail
#else
@@ -400,7 +400,7 @@ def CheckType(context, type_name, fallback = None,
%(include)s
%(header)s
-int main() {
+int main(void) {
if ((%(name)s *) 0)
return 0;
if (sizeof (%(name)s))
@@ -465,7 +465,7 @@ def CheckTypeSize(context, type_name, header = None, language = None, expect = N
src = src + r"""
typedef %s scons_check_type;
-int main()
+int main(void)
{
static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)];
test_array[0] = 0;
@@ -498,7 +498,7 @@ int main()
src = src + """
#include <stdlib.h>
#include <stdio.h>
-int main() {
+int main(void) {
printf("%d", (int)sizeof(""" + type_name + """));
return 0;
}
@@ -560,7 +560,7 @@ def CheckDeclaration(context, symbol, includes = None, language = None):
context.Display('Checking whether %s is declared... ' % symbol)
src = src + r"""
-int main()
+int main(void)
{
#ifndef %s
(void) %s;
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index 44d1e46..817cae1 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -342,6 +342,7 @@ Touch = ActionFactory(touch_func,
# 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
@@ -358,6 +359,7 @@ def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
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
@@ -395,6 +397,7 @@ def _concat_ixes(prefix, list, suffix, env):
return result
+
def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None):
"""
This is a wrapper around _concat()/_concat_ixes() that checks for
diff --git a/src/engine/SCons/DefaultsTests.py b/src/engine/SCons/DefaultsTests.py
index 141243b..e04d1eb 100644
--- a/src/engine/SCons/DefaultsTests.py
+++ b/src/engine/SCons/DefaultsTests.py
@@ -32,7 +32,6 @@ import unittest
from collections import UserDict
import TestCmd
-import TestUnit
import SCons.Errors
@@ -77,13 +76,7 @@ class DefaultsTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [ DefaultsTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index 13df189..150e234 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -163,7 +163,7 @@ def _set_BUILDERS(env, key, value):
for k in list(bd.keys()):
del bd[k]
except KeyError:
- bd = BuilderDict(kwbd, env)
+ bd = BuilderDict(bd, env)
env._dict[key] = bd
for k, v in value.items():
if not SCons.Builder.is_a_Builder(v):
@@ -2326,7 +2326,8 @@ class Base(SubstitutionEnvironment):
node = node.srcnode()
return node
- sources = list(map(final_source, sources));
+ sources = list(map(final_source, sources))
+
# remove duplicates
return list(set(sources))
diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml
index ccee68d..324096f 100644
--- a/src/engine/SCons/Environment.xml
+++ b/src/engine/SCons/Environment.xml
@@ -60,7 +60,7 @@ or this:
<example_commands>
env = Environment()
-env['BUILDERS]['NewBuilder'] = foo
+env['BUILDERS']['NewBuilder'] = foo
</example_commands>
</summary>
</cvar>
diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py
index dae20b2..3746d5d 100644
--- a/src/engine/SCons/Errors.py
+++ b/src/engine/SCons/Errors.py
@@ -190,14 +190,13 @@ def convert_to_BuildError(status, exc_info=None):
# error, which might be different from the target being built
# (for example, failure to create the directory in which the
# target file will appear).
- try:
- filename = status.filename
- except AttributeError:
- filename = None
+ filename = getattr(status, 'filename', None)
+ strerror = getattr(status, 'strerror', str(status))
+ errno = getattr(status, 'errno', 2)
buildError = BuildError(
- errstr=status.strerror,
- status=status.errno,
+ errstr=strerror,
+ status=errno,
exitstatus=2,
filename=filename,
exc_info=exc_info)
diff --git a/src/engine/SCons/ErrorsTests.py b/src/engine/SCons/ErrorsTests.py
index c38158d..5c16160 100644
--- a/src/engine/SCons/ErrorsTests.py
+++ b/src/engine/SCons/ErrorsTests.py
@@ -23,11 +23,11 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import errno
+import os
import sys
import unittest
-import TestUnit
-
import SCons.Errors
@@ -100,9 +100,31 @@ class ErrorsTestCase(unittest.TestCase):
except SCons.Errors.ExplicitExit as e:
assert e.node == "node"
+ def test_convert_EnvironmentError_to_BuildError(self):
+ """Test the convert_to_BuildError function on EnvironmentError
+ exceptions.
+ """
+ ee = SCons.Errors.EnvironmentError("test env error")
+ be = SCons.Errors.convert_to_BuildError(ee)
+ assert be.errstr == "test env error"
+ assert be.status == 2
+ assert be.exitstatus == 2
+ assert be.filename is None
+
+ def test_convert_OSError_to_BuildError(self):
+ """Test the convert_to_BuildError function on OSError
+ exceptions.
+ """
+ ose = OSError(7, 'test oserror')
+ be = SCons.Errors.convert_to_BuildError(ose)
+ assert be.errstr == 'test oserror'
+ assert be.status == 7
+ assert be.exitstatus == 2
+ assert be.filename is None
+
+
if __name__ == "__main__":
- suite = unittest.makeSuite(ErrorsTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/ExecutorTests.py b/src/engine/SCons/ExecutorTests.py
index eeab3ad..59ca5c7 100644
--- a/src/engine/SCons/ExecutorTests.py
+++ b/src/engine/SCons/ExecutorTests.py
@@ -26,8 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
-import TestUnit
-
import SCons.Executor
@@ -483,12 +481,7 @@ class ExecutorTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [ ExecutorTestCase ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/JobTests.py b/src/engine/SCons/JobTests.py
index 6ae8e92..325c0e1 100644
--- a/src/engine/SCons/JobTests.py
+++ b/src/engine/SCons/JobTests.py
@@ -52,7 +52,7 @@ def get_cpu_nums():
return 1 # Default
# a large number
-num_sines = 10000
+num_sines = 500
# how many parallel jobs to perform for the test
num_jobs = get_cpu_nums()*2
@@ -98,14 +98,24 @@ class Task(object):
return True
def execute(self):
- self.taskmaster.test_case.failUnless(self.was_prepared,
+ self.taskmaster.test_case.assertTrue(self.was_prepared,
"the task wasn't prepared")
self.taskmaster.guard.acquire()
self.taskmaster.begin_list.append(self.i)
self.taskmaster.guard.release()
+ # while task is executing, represent this in the parallel_list
+ # and then turn it off
+ self.taskmaster.parallel_list[self.i] = 1
self._do_something()
+ self.taskmaster.parallel_list[self.i] = 0
+
+ # check if task was executing while another was also executing
+ for j in range(1, self.taskmaster.num_tasks):
+ if(self.taskmaster.parallel_list[j+1] == 1):
+ self.taskmaster.found_parallel = True
+ break
self.was_executed = 1
@@ -116,26 +126,29 @@ class Task(object):
def executed(self):
self.taskmaster.num_executed = self.taskmaster.num_executed + 1
- self.taskmaster.test_case.failUnless(self.was_prepared,
+ self.taskmaster.test_case.assertTrue(self.was_prepared,
"the task wasn't prepared")
- self.taskmaster.test_case.failUnless(self.was_executed,
+ self.taskmaster.test_case.assertTrue(self.was_executed,
"the task wasn't really executed")
- self.taskmaster.test_case.failUnless(isinstance(self, Task),
+ self.taskmaster.test_case.assertTrue(isinstance(self, Task),
"the task wasn't really a Task instance")
def failed(self):
self.taskmaster.num_failed = self.taskmaster.num_failed + 1
self.taskmaster.stop = 1
- self.taskmaster.test_case.failUnless(self.was_prepared,
+ self.taskmaster.test_case.assertTrue(self.was_prepared,
"the task wasn't prepared")
def postprocess(self):
self.taskmaster.num_postprocessed = self.taskmaster.num_postprocessed + 1
+ def exception_set(self):
+ pass
+
class RandomTask(Task):
def _do_something(self):
# do something that will take some random amount of time:
- for i in range(random.randrange(0, num_sines, 1)):
+ for i in range(random.randrange(0, 100 + num_sines, 1)):
x = math.sin(i)
time.sleep(0.01)
@@ -158,17 +171,17 @@ class ExceptionTask(object):
def executed(self):
self.taskmaster.num_executed = self.taskmaster.num_executed + 1
- self.taskmaster.test_case.failUnless(self.was_prepared,
+ self.taskmaster.test_case.assertTrue(self.was_prepared,
"the task wasn't prepared")
- self.taskmaster.test_case.failUnless(self.was_executed,
+ self.taskmaster.test_case.assertTrue(self.was_executed,
"the task wasn't really executed")
- self.taskmaster.test_case.failUnless(self.__class__ is Task,
+ self.taskmaster.test_case.assertTrue(self.__class__ is Task,
"the task wasn't really a Task instance")
def failed(self):
self.taskmaster.num_failed = self.taskmaster.num_failed + 1
self.taskmaster.stop = 1
- self.taskmaster.test_case.failUnless(self.was_prepared,
+ self.taskmaster.test_case.assertTrue(self.was_prepared,
"the task wasn't prepared")
def postprocess(self):
@@ -190,7 +203,10 @@ class Taskmaster(object):
self.num_executed = 0
self.num_failed = 0
self.num_postprocessed = 0
+ self.parallel_list = [0] * (n+1)
+ self.found_parallel = False
self.Task = Task
+
# 'guard' guards 'task_begin_list' and 'task_end_list'
try:
import threading
@@ -222,12 +238,7 @@ class Taskmaster(object):
def tasks_were_serial(self):
"analyze the task order to see if they were serial"
- serial = 1 # assume the tasks were serial
- for i in range(num_tasks):
- serial = serial and (self.begin_list[i]
- == self.end_list[i]
- == (i + 1))
- return serial
+ return not self.found_parallel
def exception_set(self):
pass
@@ -251,15 +262,15 @@ class ParallelTestCase(unittest.TestCase):
jobs = SCons.Job.Jobs(num_jobs, taskmaster)
jobs.run()
- self.failUnless(not taskmaster.tasks_were_serial(),
+ self.assertTrue(not taskmaster.tasks_were_serial(),
"the tasks were not executed in parallel")
- self.failUnless(taskmaster.all_tasks_are_executed(),
+ self.assertTrue(taskmaster.all_tasks_are_executed(),
"all the tests were not executed")
- self.failUnless(taskmaster.all_tasks_are_iterated(),
+ self.assertTrue(taskmaster.all_tasks_are_iterated(),
"all the tests were not iterated over")
- self.failUnless(taskmaster.all_tasks_are_postprocessed(),
+ self.assertTrue(taskmaster.all_tasks_are_postprocessed(),
"all the tests were not postprocessed")
- self.failIf(taskmaster.num_failed,
+ self.assertFalse(taskmaster.num_failed,
"some task(s) failed to execute")
# Verify that parallel jobs will pull all of the completed tasks
@@ -271,7 +282,7 @@ class ParallelTestCase(unittest.TestCase):
class SleepTask(Task):
def _do_something(self):
- time.sleep(0.1)
+ time.sleep(0.01)
global SaveThreadPool
SaveThreadPool = SCons.Job.ThreadPool
@@ -281,7 +292,7 @@ class ParallelTestCase(unittest.TestCase):
ThreadPoolCallList.append('put(%s)' % task.i)
return SaveThreadPool.put(self, task)
def get(self):
- time.sleep(0.5)
+ time.sleep(0.05)
result = SaveThreadPool.get(self)
ThreadPoolCallList.append('get(%s)' % result[0].i)
return result
@@ -314,15 +325,15 @@ class SerialTestCase(unittest.TestCase):
jobs = SCons.Job.Jobs(1, taskmaster)
jobs.run()
- self.failUnless(taskmaster.tasks_were_serial(),
+ self.assertTrue(taskmaster.tasks_were_serial(),
"the tasks were not executed in series")
- self.failUnless(taskmaster.all_tasks_are_executed(),
+ self.assertTrue(taskmaster.all_tasks_are_executed(),
"all the tests were not executed")
- self.failUnless(taskmaster.all_tasks_are_iterated(),
+ self.assertTrue(taskmaster.all_tasks_are_iterated(),
"all the tests were not iterated over")
- self.failUnless(taskmaster.all_tasks_are_postprocessed(),
+ self.assertTrue(taskmaster.all_tasks_are_postprocessed(),
"all the tests were not postprocessed")
- self.failIf(taskmaster.num_failed,
+ self.assertFalse(taskmaster.num_failed,
"some task(s) failed to execute")
class NoParallelTestCase(unittest.TestCase):
@@ -335,18 +346,18 @@ class NoParallelTestCase(unittest.TestCase):
try:
taskmaster = Taskmaster(num_tasks, self, RandomTask)
jobs = SCons.Job.Jobs(2, taskmaster)
- self.failUnless(jobs.num_jobs == 1,
+ self.assertTrue(jobs.num_jobs == 1,
"unexpected number of jobs %d" % jobs.num_jobs)
jobs.run()
- self.failUnless(taskmaster.tasks_were_serial(),
+ self.assertTrue(taskmaster.tasks_were_serial(),
"the tasks were not executed in series")
- self.failUnless(taskmaster.all_tasks_are_executed(),
+ self.assertTrue(taskmaster.all_tasks_are_executed(),
"all the tests were not executed")
- self.failUnless(taskmaster.all_tasks_are_iterated(),
+ self.assertTrue(taskmaster.all_tasks_are_iterated(),
"all the tests were not iterated over")
- self.failUnless(taskmaster.all_tasks_are_postprocessed(),
+ self.assertTrue(taskmaster.all_tasks_are_postprocessed(),
"all the tests were not postprocessed")
- self.failIf(taskmaster.num_failed,
+ self.assertFalse(taskmaster.num_failed,
"some task(s) failed to execute")
finally:
SCons.Job.Parallel = save_Parallel
@@ -360,13 +371,13 @@ class SerialExceptionTestCase(unittest.TestCase):
jobs = SCons.Job.Jobs(1, taskmaster)
jobs.run()
- self.failIf(taskmaster.num_executed,
+ self.assertFalse(taskmaster.num_executed,
"a task was executed")
- self.failUnless(taskmaster.num_iterated == 1,
+ self.assertTrue(taskmaster.num_iterated == 1,
"exactly one task should have been iterated")
- self.failUnless(taskmaster.num_failed == 1,
+ self.assertTrue(taskmaster.num_failed == 1,
"exactly one task should have failed")
- self.failUnless(taskmaster.num_postprocessed == 1,
+ self.assertTrue(taskmaster.num_postprocessed == 1,
"exactly one task should have been postprocessed")
class ParallelExceptionTestCase(unittest.TestCase):
@@ -377,13 +388,13 @@ class ParallelExceptionTestCase(unittest.TestCase):
jobs = SCons.Job.Jobs(num_jobs, taskmaster)
jobs.run()
- self.failIf(taskmaster.num_executed,
+ self.assertFalse(taskmaster.num_executed,
"a task was executed")
- self.failUnless(taskmaster.num_iterated >= 1,
+ self.assertTrue(taskmaster.num_iterated >= 1,
"one or more task should have been iterated")
- self.failUnless(taskmaster.num_failed >= 1,
+ self.assertTrue(taskmaster.num_failed >= 1,
"one or more tasks should have failed")
- self.failUnless(taskmaster.num_postprocessed >= 1,
+ self.assertTrue(taskmaster.num_postprocessed >= 1,
"one or more tasks should have been postprocessed")
#---------------------------------------------------------------------
@@ -514,10 +525,10 @@ class _SConsTaskTest(unittest.TestCase):
for N in testnodes:
state = N.get_state()
- self.failUnless(state in [SCons.Node.no_state, N.expect_to_be],
+ self.assertTrue(state in [SCons.Node.no_state, N.expect_to_be],
"Node %s got unexpected result: %s" % (N, state))
- self.failUnless([N for N in testnodes if N.get_state()],
+ self.assertTrue([N for N in testnodes if N.get_state()],
"no nodes ran at all.")
diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py
index 3ce9a11..726f656 100644
--- a/src/engine/SCons/MemoizeTests.py
+++ b/src/engine/SCons/MemoizeTests.py
@@ -26,8 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
-import TestUnit
-
import SCons.Memoize
# Enable memoization counting
@@ -165,15 +163,7 @@ class CountValueTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [
- CountDictTestCase,
- CountValueTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py
index 8e31875..5d9c799 100644
--- a/src/engine/SCons/Node/AliasTests.py
+++ b/src/engine/SCons/Node/AliasTests.py
@@ -26,8 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Node.Alias
@@ -113,16 +111,7 @@ class AliasBuildInfoTestCase(unittest.TestCase):
bi = SCons.Node.Alias.AliasBuildInfo()
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [
- AliasTestCase,
- AliasBuildInfoTestCase,
- AliasNodeInfoTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 9a48432..bc15064 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -132,7 +132,10 @@ def initialize_do_splitdrive():
global do_splitdrive
global has_unc
drive, path = os.path.splitdrive('X:/foo')
- has_unc = hasattr(os.path, 'splitunc')
+ # 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
@@ -1394,10 +1397,10 @@ class FS(LocalFS):
if not isinstance(d, SCons.Node.Node):
d = self.Dir(d)
self.Top.addRepository(d)
-
+
def PyPackageDir(self, modulename):
"""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
@@ -3302,7 +3305,7 @@ class File(Base):
try: node = dir.entries[norm_name]
except KeyError: node = dir.file_on_disk(self.name)
if node and node.exists() and \
- (isinstance(node, File) or isinstance(node, Entry) \
+ (isinstance(node, File) or isinstance(node, Entry)
or not node.is_derived()):
result = node
# Copy over our local attributes to the repository
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index 273f809..698f574 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -605,7 +605,7 @@ class VariantDirTestCase(unittest.TestCase):
print("File `%s' alter_targets() `%s' != expected `%s'" % (f, tp, expect))
errors = errors + 1
- self.failIf(errors)
+ self.assertFalse(errors)
class BaseTestCase(_tempdirTestCase):
def test_stat(self):
@@ -1657,7 +1657,12 @@ class FSTestCase(_tempdirTestCase):
import ntpath
x = test.workpath(*dirs)
drive, path = ntpath.splitdrive(x)
- unc, path = ntpath.splitunc(path)
+ try:
+ unc, path = ntpath.splitunc(path)
+ except AttributeError:
+ # could be python 3.7 or newer, make sure splitdrive can do UNC
+ assert ntpath.splitdrive(r'\\split\drive\test')[0] == r'\\split\drive'
+ pass
path = strip_slash(path)
return '//' + path[1:]
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index 3802f8c..ca6c883 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -30,8 +30,6 @@ import re
import sys
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Node
import SCons.Util
@@ -1349,15 +1347,7 @@ class NodeListTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [ BuildInfoBaseTestCase,
- NodeInfoBaseTestCase,
- NodeTestCase,
- NodeListTestCase ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py
index 346542b..7ef9e52 100644
--- a/src/engine/SCons/Node/PythonTests.py
+++ b/src/engine/SCons/Node/PythonTests.py
@@ -26,8 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Node.Python
@@ -113,16 +111,7 @@ class ValueBuildInfoTestCase(unittest.TestCase):
bi = SCons.Node.Python.ValueBuildInfo()
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [
- ValueTestCase,
- ValueBuildInfoTestCase,
- ValueNodeInfoTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index e186752..c18a954 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -155,7 +155,7 @@ def exists_file(node):
# 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"%self)
+ 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
@@ -665,7 +665,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)):
executor.cleanup()
def reset_executor(self):
- "Remove cached executor; forces recompute when needed."
+ """Remove cached executor; forces recompute when needed."""
try:
delattr(self, 'executor')
except AttributeError:
diff --git a/src/engine/SCons/Platform/PlatformTests.py b/src/engine/SCons/Platform/PlatformTests.py
index 3432e94..6f720ec 100644
--- a/src/engine/SCons/Platform/PlatformTests.py
+++ b/src/engine/SCons/Platform/PlatformTests.py
@@ -28,8 +28,6 @@ import SCons.compat
import collections
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Platform
import SCons.Environment
@@ -204,17 +202,8 @@ class PlatformEscapeTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.TestSuite()
-
- tclasses = [ PlatformTestCase,
- TempFileMungeTestCase,
- PlatformEscapeTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
+ unittest.main()
- TestUnit.run(suite)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Platform/cygwin.py b/src/engine/SCons/Platform/cygwin.py
index 8b4669c..f6c5086 100644
--- a/src/engine/SCons/Platform/cygwin.py
+++ b/src/engine/SCons/Platform/cygwin.py
@@ -32,9 +32,18 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+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)
diff --git a/src/engine/SCons/Platform/mingw.py b/src/engine/SCons/Platform/mingw.py
new file mode 100644
index 0000000..73633d7
--- /dev/null
+++ b/src/engine/SCons/Platform/mingw.py
@@ -0,0 +1,39 @@
+"""SCons.Platform.mingw
+
+Platform-specific initialization for the MinGW system.
+
+"""
+
+#
+# __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 sys
+
+MINGW_DEFAULT_PATHS = []
+if sys.platform == 'win32':
+ MINGW_DEFAULT_PATHS = [
+ r'C:\msys64',
+ r'C:\msys'
+ ] \ No newline at end of file
diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py
index 8db08db..ae2ad1a 100644
--- a/src/engine/SCons/Platform/posix.py
+++ b/src/engine/SCons/Platform/posix.py
@@ -48,7 +48,7 @@ exitvalmap = {
}
def escape(arg):
- "escape shell special characters"
+ """escape shell special characters"""
slash = '\\'
special = '"$'
diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py
index 0e9e01f..ea2fd3f 100644
--- a/src/engine/SCons/Platform/win32.py
+++ b/src/engine/SCons/Platform/win32.py
@@ -132,7 +132,7 @@ try:
# Without this, python can randomly crash while using -jN.
# See the python bug at http://bugs.python.org/issue6476
# and SCons issue at
- # http://scons.tigris.org/issues/show_bug.cgi?id=2449
+ # https://github.com/SCons/scons/issues/2449
def spawnve(mode, file, args, env):
spawn_lock.acquire()
try:
@@ -200,11 +200,11 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
except OSError as e:
# catch any error
try:
- ret = exitvalmap[e[0]]
+ ret = exitvalmap[e.errno]
except KeyError:
- sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e[0], cmd, e[1]))
+ 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[1]))
+ 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 stdoutRedirected == 0:
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index 48eed8e..0dcbab8 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -609,7 +609,7 @@ class SConfBase(object):
ok = self.TryBuild(self.env.SConfActionBuilder, text, extension)
del self.env['BUILDERS']['SConfActionBuilder']
if ok:
- outputStr = self.lastTarget.get_contents().decode()
+ outputStr = self.lastTarget.get_text_contents()
return (1, outputStr)
return (0, "")
@@ -1000,7 +1000,7 @@ def CheckLib(context, library = None, symbol = "main",
compiles without flags.
"""
- if library == []:
+ if not library:
library = [None]
if not SCons.Util.is_List(library):
diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py
index f4c6f89..cf8a7fb 100644
--- a/src/engine/SCons/SConfTests.py
+++ b/src/engine/SCons/SConfTests.py
@@ -33,8 +33,6 @@ from types import *
import unittest
import TestCmd
-import TestUnit
-
sys.stdout = io.StringIO()
@@ -115,9 +113,9 @@ class SConfTestCase(unittest.TestCase):
def checks(self, sconf, TryFuncString):
TryFunc = self.SConf.SConfBase.__dict__[TryFuncString]
- res1 = TryFunc( sconf, "int main() { return 0; }\n", ".c" )
+ res1 = TryFunc( sconf, "int main(void) { return 0; }\n", ".c" )
res2 = TryFunc( sconf,
- '#include "no_std_header.h"\nint main() {return 0; }\n',
+ '#include "no_std_header.h"\nint main(void) {return 0; }\n',
'.c' )
return (res1,res2)
@@ -254,7 +252,7 @@ class SConfTestCase(unittest.TestCase):
def checks(sconf):
prog = """
#include <stdio.h>
-int main() {
+int main(void) {
printf( "Hello" );
return 0;
}
@@ -300,10 +298,15 @@ int main() {
"""Test SConf.TryAction
"""
def actionOK(target, source, env):
- open(str(target[0]), "w").write( "RUN OK\n" )
+ open(str(target[0]), "w").write("RUN OK\n")
return None
def actionFAIL(target, source, env):
return 1
+ def actionUnicode(target, source, env):
+ open(str(target[0]), "wb").write('2\302\242\n')
+ return None
+
+
self._resetSConfState()
sconf = self.SConf.SConf(self.scons_env,
conf_dir=self.test.workpath('config.tests'),
@@ -313,6 +316,12 @@ int main() {
assert ret and output.encode('utf-8') == bytearray("RUN OK"+os.linesep,'utf-8'), (ret, output)
(ret, output) = sconf.TryAction(action=actionFAIL)
assert not ret and output == "", (ret, output)
+
+ if not TestCmd.IS_PY3:
+ # GH Issue #3141 - unicode text and py2.7 crashes.
+ (ret, output) = sconf.TryAction(action=actionUnicode)
+ assert ret and output == u'2\xa2\n', (ret, output)
+
finally:
sconf.Finish()
@@ -755,7 +764,7 @@ int main() {
prog = """
#include <stdio.h>
-int main() {
+int main(void) {
printf( "Hello" );
return 0;
}
@@ -779,8 +788,7 @@ int main() {
if __name__ == "__main__":
- suite = unittest.makeSuite(SConfTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py
index 9c7df12..4b7233c 100644
--- a/src/engine/SCons/Scanner/CTests.py
+++ b/src/engine/SCons/Scanner/CTests.py
@@ -48,7 +48,7 @@ test.write('f1.cpp',"""
#include \"f1.h\"
#include <f2.h>
-int main()
+int main(void)
{
return 0;
}
@@ -60,7 +60,7 @@ test.write('f2.cpp',"""
#include \"f1.h\"
#import <f4.h>
-int main()
+int main(void)
{
return 0;
}
@@ -79,7 +79,7 @@ test.write('f3.cpp',"""
const char* x = "#include <never.h>"
-int main()
+int main(void)
{
return 0;
}
@@ -113,7 +113,7 @@ test.write('fa.cpp',"""
#include \"fa.h\"
#include <fb.h>
-int main()
+int main(void)
{
return 0;
}
@@ -135,7 +135,7 @@ test.write(['work', 'src', 'fff.c'], """
#include <iii.h>
#include <jjj.h>
-int main()
+int main(void)
{
return 0;
}
@@ -144,7 +144,7 @@ int main()
test.write([ 'work', 'src', 'aaa.c'], """
#include "bbb.h"
-int main()
+int main(void)
{
return 0;
}
@@ -155,7 +155,7 @@ test.write([ 'work', 'src', 'bbb.h'], "\n")
test.write([ 'repository', 'src', 'ccc.c'], """
#include "ddd.h"
-int main()
+int main(void)
{
return 0;
}
@@ -218,7 +218,7 @@ def deps_match(self, deps, headers):
global my_normpath
scanned = list(map(my_normpath, list(map(str, deps))))
expect = list(map(my_normpath, headers))
- self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
+ self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
diff --git a/src/engine/SCons/Scanner/DTests.py b/src/engine/SCons/Scanner/DTests.py
index 51e527a..d0157bf 100644
--- a/src/engine/SCons/Scanner/DTests.py
+++ b/src/engine/SCons/Scanner/DTests.py
@@ -26,7 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import unittest
import TestCmd
-import TestUnit
import SCons.Scanner.D
@@ -80,7 +79,7 @@ def deps_match(self, deps, headers):
global my_normpath
scanned = list(map(my_normpath, list(map(str, deps))))
expect = list(map(my_normpath, headers))
- self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
+ self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
"""
Examples from https://dlang.org/spec/module.html
@@ -266,14 +265,7 @@ class DScannerTestCase(unittest.TestCase):
self.helper('multiline.d', ['A.d'])
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [
- DScannerTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/DirTests.py b/src/engine/SCons/Scanner/DirTests.py
index 9701921..c433663 100644
--- a/src/engine/SCons/Scanner/DirTests.py
+++ b/src/engine/SCons/Scanner/DirTests.py
@@ -28,7 +28,6 @@ import sys
import unittest
import TestCmd
-import TestUnit
import SCons.Node.FS
import SCons.Scanner.Dir
@@ -121,14 +120,8 @@ class DirEntryScannerTestCase(DirScannerTestBase):
sss = list(map(str, deps))
assert sss == [], sss
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(DirScannerTestCase())
- suite.addTest(DirEntryScannerTestCase())
- return suite
-
if __name__ == "__main__":
- TestUnit.run(suite())
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/Fortran.py b/src/engine/SCons/Scanner/Fortran.py
index 1b55130..6065bbd 100644
--- a/src/engine/SCons/Scanner/Fortran.py
+++ b/src/engine/SCons/Scanner/Fortran.py
@@ -78,7 +78,7 @@ class F90Scanner(SCons.Scanner.Classic):
def scan(self, node, env, path=()):
# cache the includes list in node so we only scan it once:
- if node.includes != None:
+ if node.includes is not None:
mods_and_includes = node.includes
else:
# retrieve all included filenames
diff --git a/src/engine/SCons/Scanner/FortranTests.py b/src/engine/SCons/Scanner/FortranTests.py
index aaefa79..5a09e3b 100644
--- a/src/engine/SCons/Scanner/FortranTests.py
+++ b/src/engine/SCons/Scanner/FortranTests.py
@@ -258,7 +258,7 @@ class DummyEnvironment(object):
def deps_match(self, deps, headers):
scanned = list(map(os.path.normpath, list(map(str, deps))))
expect = list(map(os.path.normpath, headers))
- self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
+ self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
diff --git a/src/engine/SCons/Scanner/IDLTests.py b/src/engine/SCons/Scanner/IDLTests.py
index 227799e..2cd67d5 100644
--- a/src/engine/SCons/Scanner/IDLTests.py
+++ b/src/engine/SCons/Scanner/IDLTests.py
@@ -159,7 +159,7 @@ test.write(['work', 'src', 'fff.c'], """
#include <iii.idl>
#include <jjj.idl>
-int main()
+int main(void)
{
return 0;
}
@@ -168,7 +168,7 @@ int main()
test.write([ 'work', 'src', 'aaa.c'], """
#include "bbb.idl"
-int main()
+int main(void)
{
return 0;
}
@@ -179,7 +179,7 @@ test.write([ 'work', 'src', 'bbb.idl'], "\n")
test.write([ 'repository', 'src', 'ccc.c'], """
#include "ddd.idl"
-int main()
+int main(void)
{
return 0;
}
@@ -243,7 +243,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'):
def deps_match(self, deps, headers):
scanned = list(map(my_normpath, list(map(str, deps))))
expect = list(map(my_normpath, headers))
- self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
+ self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
diff --git a/src/engine/SCons/Scanner/LaTeX.py b/src/engine/SCons/Scanner/LaTeX.py
index 5800443..1cf2567 100644
--- a/src/engine/SCons/Scanner/LaTeX.py
+++ b/src/engine/SCons/Scanner/LaTeX.py
@@ -128,8 +128,8 @@ class LaTeX(SCons.Scanner.Base):
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
+ "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.
@@ -137,7 +137,7 @@ class LaTeX(SCons.Scanner.Base):
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::
@@ -333,7 +333,7 @@ class LaTeX(SCons.Scanner.Base):
line_continues_a_comment = False
for line in text.splitlines():
line,comment = self.comment_re.findall(line)[0]
- if line_continues_a_comment == True:
+ if line_continues_a_comment:
out[-1] = out[-1] + line.lstrip()
else:
out.append(line)
@@ -349,7 +349,7 @@ class LaTeX(SCons.Scanner.Base):
# path_dict = dict(list(path))
# add option for whitespace (\s) before the '['
noopt_cre = re.compile('\s*\[.*$')
- if node.includes != None:
+ if node.includes is not None:
includes = node.includes
else:
text = self.canonical_text(node.get_text_contents())
@@ -386,8 +386,8 @@ class LaTeX(SCons.Scanner.Base):
directory of the main file just as latex does"""
path_dict = dict(list(path))
-
- queue = []
+
+ queue = []
queue.extend( self.scan(node) )
seen = {}
@@ -402,7 +402,7 @@ class LaTeX(SCons.Scanner.Base):
source_dir = node.get_dir()
#for include in includes:
while queue:
-
+
include = queue.pop()
inc_type, inc_subdir, inc_filename = include
diff --git a/src/engine/SCons/Scanner/LaTeXTests.py b/src/engine/SCons/Scanner/LaTeXTests.py
index 213e89e..0114d45 100644
--- a/src/engine/SCons/Scanner/LaTeXTests.py
+++ b/src/engine/SCons/Scanner/LaTeXTests.py
@@ -31,7 +31,6 @@ import sys
import unittest
import TestCmd
-import TestUnit
import SCons.Node.FS
import SCons.Scanner.LaTeX
@@ -123,7 +122,7 @@ def deps_match(self, deps, headers):
global my_normpath
scanned = list(map(my_normpath, list(map(str, deps))))
expect = list(map(my_normpath, headers))
- self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
+ self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
class LaTeXScannerTestCase1(unittest.TestCase):
@@ -156,16 +155,8 @@ class LaTeXScannerTestCase3(unittest.TestCase):
files = ['inc5.xyz', 'subdir/inc4.eps']
deps_match(self, deps, files)
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(LaTeXScannerTestCase1())
- suite.addTest(LaTeXScannerTestCase2())
- suite.addTest(LaTeXScannerTestCase3())
- return suite
-
if __name__ == "__main__":
- TestUnit.run(suite())
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py
index e7c791c..45fdcb2 100644
--- a/src/engine/SCons/Scanner/ProgTests.py
+++ b/src/engine/SCons/Scanner/ProgTests.py
@@ -28,7 +28,6 @@ import sys
import unittest
import TestCmd
-import TestUnit
import SCons.Node.FS
import SCons.Scanner.Prog
@@ -274,7 +273,7 @@ def suite():
return suite
if __name__ == "__main__":
- TestUnit.run(suite())
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/RCTests.py b/src/engine/SCons/Scanner/RCTests.py
index 2864026..551e613 100644
--- a/src/engine/SCons/Scanner/RCTests.py
+++ b/src/engine/SCons/Scanner/RCTests.py
@@ -29,7 +29,6 @@ import collections
import os
import TestCmd
-import TestUnit
import SCons.Scanner.RC
import SCons.Node.FS
@@ -117,7 +116,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'):
def deps_match(self, deps, headers):
scanned = sorted(map(my_normpath, list(map(str, deps))))
expect = sorted(map(my_normpath, headers))
- self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
+ self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
@@ -167,7 +166,7 @@ def suite():
return suite
if __name__ == "__main__":
- TestUnit.run(suite())
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py
index 8050216..5cdd5b1 100644
--- a/src/engine/SCons/Scanner/ScannerTests.py
+++ b/src/engine/SCons/Scanner/ScannerTests.py
@@ -132,16 +132,16 @@ class BaseTestCase(unittest.TestCase):
scanned = scanner(filename, env, path)
scanned_strs = [str(x) for x in scanned]
- self.failUnless(self.filename == filename, "the filename was passed incorrectly")
- self.failUnless(self.env == env, "the environment was passed incorrectly")
- self.failUnless(scanned_strs == deps, "the dependencies were returned incorrectly")
+ self.assertTrue(self.filename == filename, "the filename was passed incorrectly")
+ self.assertTrue(self.env == env, "the environment was passed incorrectly")
+ self.assertTrue(scanned_strs == deps, "the dependencies were returned incorrectly")
for d in scanned:
- self.failUnless(not isinstance(d, str), "got a string in the dependencies")
+ self.assertTrue(not isinstance(d, str), "got a string in the dependencies")
if len(args) > 0:
- self.failUnless(self.arg == args[0], "the argument was passed incorrectly")
+ self.assertTrue(self.arg == args[0], "the argument was passed incorrectly")
else:
- self.failIf(hasattr(self, "arg"), "an argument was given when it shouldn't have been")
+ self.assertFalse(hasattr(self, "arg"), "an argument was given when it shouldn't have been")
def test___call__dict(self):
"""Test calling Scanner.Base objects with a dictionary"""
@@ -245,7 +245,7 @@ class BaseTestCase(unittest.TestCase):
dict[s] = 777
i = hash(id(s))
h = hash(list(dict.keys())[0])
- self.failUnless(h == i,
+ self.assertTrue(h == i,
"hash Scanner base class expected %s, got %s" % (i, h))
def test_scan_check(self):
@@ -260,7 +260,7 @@ class BaseTestCase(unittest.TestCase):
self.checked = {}
path = s.path(env)
scanned = s(DummyNode('x'), env, path)
- self.failUnless(self.checked['x'] == 1,
+ self.assertTrue(self.checked['x'] == 1,
"did not call check function")
def test_recursive(self):
@@ -269,42 +269,42 @@ class BaseTestCase(unittest.TestCase):
s = SCons.Scanner.Base(function = self.func)
n = s.recurse_nodes(nodes)
- self.failUnless(n == [],
+ self.assertTrue(n == [],
"default behavior returned nodes: %s" % n)
s = SCons.Scanner.Base(function = self.func, recursive = None)
n = s.recurse_nodes(nodes)
- self.failUnless(n == [],
+ self.assertTrue(n == [],
"recursive = None returned nodes: %s" % n)
s = SCons.Scanner.Base(function = self.func, recursive = 1)
n = s.recurse_nodes(nodes)
- self.failUnless(n == n,
+ self.assertTrue(n == n,
"recursive = 1 didn't return all nodes: %s" % n)
def odd_only(nodes):
return [n for n in nodes if n % 2]
s = SCons.Scanner.Base(function = self.func, recursive = odd_only)
n = s.recurse_nodes(nodes)
- self.failUnless(n == [1, 3],
+ self.assertTrue(n == [1, 3],
"recursive = 1 didn't return all nodes: %s" % n)
def test_get_skeys(self):
"""Test the Scanner.Base get_skeys() method"""
s = SCons.Scanner.Base(function = self.func)
sk = s.get_skeys()
- self.failUnless(sk == [],
+ self.assertTrue(sk == [],
"did not initialize to expected []")
s = SCons.Scanner.Base(function = self.func, skeys = ['.1', '.2'])
sk = s.get_skeys()
- self.failUnless(sk == ['.1', '.2'],
+ self.assertTrue(sk == ['.1', '.2'],
"sk was %s, not ['.1', '.2']")
s = SCons.Scanner.Base(function = self.func, skeys = '$LIST')
env = DummyEnvironment(LIST = ['.3', '.4'])
sk = s.get_skeys(env)
- self.failUnless(sk == ['.3', '.4'],
+ self.assertTrue(sk == ['.3', '.4'],
"sk was %s, not ['.3', '.4']")
def test_select(self):
@@ -432,19 +432,19 @@ class CurrentTestCase(unittest.TestCase):
path = s.path(env)
hnb = HasNoBuilder()
s(hnb, env, path)
- self.failUnless(hnb.called_has_builder, "did not call has_builder()")
- self.failUnless(not hnb.called_is_up_to_date, "did call is_up_to_date()")
- self.failUnless(hnb.func_called, "did not call func()")
+ self.assertTrue(hnb.called_has_builder, "did not call has_builder()")
+ self.assertTrue(not hnb.called_is_up_to_date, "did call is_up_to_date()")
+ self.assertTrue(hnb.func_called, "did not call func()")
inc = IsNotCurrent()
s(inc, env, path)
- self.failUnless(inc.called_has_builder, "did not call has_builder()")
- self.failUnless(inc.called_is_up_to_date, "did not call is_up_to_date()")
- self.failUnless(not inc.func_called, "did call func()")
+ self.assertTrue(inc.called_has_builder, "did not call has_builder()")
+ self.assertTrue(inc.called_is_up_to_date, "did not call is_up_to_date()")
+ self.assertTrue(not inc.func_called, "did call func()")
ic = IsCurrent()
s(ic, env, path)
- self.failUnless(ic.called_has_builder, "did not call has_builder()")
- self.failUnless(ic.called_is_up_to_date, "did not call is_up_to_date()")
- self.failUnless(ic.func_called, "did not call func()")
+ self.assertTrue(ic.called_has_builder, "did not call has_builder()")
+ self.assertTrue(ic.called_is_up_to_date, "did not call is_up_to_date()")
+ self.assertTrue(ic.func_called, "did not call func()")
class ClassicTestCase(unittest.TestCase):
@@ -566,7 +566,7 @@ class ClassicTestCase(unittest.TestCase):
s = SCons.Scanner.Classic("Test", [], None, "", function=self.func, recursive=1)
n = s.recurse_nodes(nodes)
- self.failUnless(n == n,
+ self.assertTrue(n == n,
"recursive = 1 didn't return all nodes: %s" % n)
def odd_only(nodes):
@@ -574,7 +574,7 @@ class ClassicTestCase(unittest.TestCase):
s = SCons.Scanner.Classic("Test", [], None, "", function=self.func, recursive=odd_only)
n = s.recurse_nodes(nodes)
- self.failUnless(n == [1, 3],
+ self.assertTrue(n == [1, 3],
"recursive = 1 didn't return all nodes: %s" % n)
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index c810634..6516a15 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -48,6 +48,7 @@ import sys
import time
import traceback
import sysconfig
+import platform
import SCons.CacheDir
import SCons.Debug
@@ -622,7 +623,7 @@ def _SConstruct_exists(dirname='', repositories=[], filelist=None):
current directory.
"""
if not filelist:
- filelist = ['SConstruct', 'Sconstruct', 'sconstruct']
+ 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):
@@ -1253,7 +1254,11 @@ def _build_targets(fs, options, targets, target_top):
BuildTask.options = options
- python_has_threads = sysconfig.get_config_var('WITH_THREAD')
+ 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
# to check if python configured with threads.
global num_jobs
num_jobs = options.num_jobs
diff --git a/src/engine/SCons/Script/MainTests.py b/src/engine/SCons/Script/MainTests.py
index fd6aaf4..aa6bfac 100644
--- a/src/engine/SCons/Script/MainTests.py
+++ b/src/engine/SCons/Script/MainTests.py
@@ -25,8 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Script.Main
@@ -41,12 +39,7 @@ import SCons.Script.Main
# of private functionality.
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = []
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index db6552c..560402c 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -153,6 +153,35 @@ def Return(*vars, **kw):
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:
+ 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()
@@ -264,8 +293,7 @@ def _SConscript(fs, *files, **kw):
if old_file is not None:
call_stack[-1].globals.update({__file__:old_file})
else:
- SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning,
- "Ignoring missing SConscript '%s'" % f.get_internal_path())
+ handle_missing_SConscript(f, kw.get('must_exist', None))
finally:
SCons.Script.sconscript_reading = SCons.Script.sconscript_reading - 1
@@ -523,6 +551,31 @@ class SConsEnvironment(SCons.Environment.Base):
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.
+ """
+
if 'build_dir' in kw:
msg = """The build_dir keyword has been deprecated; use the variant_dir keyword instead."""
SCons.Warnings.warn(SCons.Warnings.DeprecatedBuildDirWarning, msg)
diff --git a/src/engine/SCons/Script/SConscript.xml b/src/engine/SCons/Script/SConscript.xml
index 8553fbe..a6258c4 100644
--- a/src/engine/SCons/Script/SConscript.xml
+++ b/src/engine/SCons/Script/SConscript.xml
@@ -357,12 +357,12 @@ Return('val1 val2')
<scons_function name="SConscript">
<arguments>
-(scripts, [exports, variant_dir, duplicate])
-<!-- (scripts, [exports, variant_dir, src_dir, duplicate]) -->
+(scripts, [exports, variant_dir, duplicate, must_exist])
+<!-- (scripts, [exports, variant_dir, src_dir, duplicate, must_exist]) -->
</arguments>
<arguments>
-(dirs=subdirs, [name=script, exports, variant_dir, duplicate])
-<!-- (dirs=subdirs, [name=script, exports, variant_dir, src_dir, duplicate]) -->
+(dirs=subdirs, [name=script, exports, variant_dir, duplicate, must_exist])
+<!-- (dirs=subdirs, [name=script, exports, variant_dir, src_dir, duplicate, must_exist]) -->
</arguments>
<summary>
<para>
@@ -564,6 +564,17 @@ TODO??? SConscript('build/SConscript', src_dir='src')
</para>
<para>
+The optional
+<varname>must_exist</varname>
+argument, if true, causes an exception to be raised if a requested
+&SConscript; file is not found. The current default is false,
+causing only a warning to be omitted, but this behavior is deprecated.
+For scripts which truly intend to be optional, transition to
+explicty supplying
+<literal>must_exist=False</literal> to the call.
+</para>
+
+<para>
Here are some composite examples:
</para>
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index a05c541..90bc311 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -276,12 +276,20 @@ def HelpFunction(text, append=False):
# 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=[], args=ARGUMENTS):
return SCons.Variables.Variables(files, args)
-def Options(files=[], args=ARGUMENTS):
- return SCons.Options.Options(files, args)
# The list of global functions to add to the SConscript name space
# that end up calling corresponding methods or Builders in the
diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py
index 0e3e778..43de5f8 100644
--- a/src/engine/SCons/Subst.py
+++ b/src/engine/SCons/Subst.py
@@ -89,6 +89,8 @@ class Literal(object):
def __neq__(self, other):
return not self.__eq__(other)
+ def __hash__(self):
+ return hash(self.lstr)
class SpecialAttrWrapper(object):
"""This is a wrapper for what we call a 'Node special attribute.'
diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py
index 35c34e8..3450e6c 100644
--- a/src/engine/SCons/SubstTests.py
+++ b/src/engine/SCons/SubstTests.py
@@ -32,8 +32,6 @@ import unittest
from collections import UserDict
-import TestUnit
-
import SCons.Errors
from SCons.Subst import *
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index 17507a6..1522ca2 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -470,14 +470,23 @@ class Task(object):
pending_children.discard(t)
for p in t.waiting_parents:
parents[p] = parents.get(p, 0) + 1
+ t.waiting_parents = set()
for t in targets:
if t.side_effects is not None:
for s in t.side_effects:
if s.get_state() == NODE_EXECUTING:
s.set_state(NODE_NO_STATE)
+
+ # The side-effects may have been transferred to
+ # NODE_NO_STATE by executed_with{,out}_callbacks, but was
+ # not taken out of the waiting parents/pending children
+ # data structures. Check for that now.
+ if s.get_state() == NODE_NO_STATE and s.waiting_parents:
+ pending_children.discard(s)
for p in s.waiting_parents:
parents[p] = parents.get(p, 0) + 1
+ s.waiting_parents = set()
for p in s.waiting_s_e:
if p.ref_count == 0:
self.tm.candidates.append(p)
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index d237d60..42ed00e 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -30,7 +30,6 @@ import copy
import sys
import unittest
-import TestUnit
import SCons.Taskmaster
import SCons.Errors
@@ -1239,8 +1238,7 @@ Taskmaster: No candidate anymore.
if __name__ == "__main__":
- suite = unittest.makeSuite(TaskmasterTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/GettextCommon.py b/src/engine/SCons/Tool/GettextCommon.py
index 3b840a6..b7d02a7 100644
--- a/src/engine/SCons/Tool/GettextCommon.py
+++ b/src/engine/SCons/Tool/GettextCommon.py
@@ -390,7 +390,7 @@ def _detect_xgettext(env):
""" Detects *xgettext(1)* binary """
if 'XGETTEXT' in env:
return env['XGETTEXT']
- xgettext = env.Detect('xgettext');
+ xgettext = env.Detect('xgettext')
if xgettext:
return xgettext
raise SCons.Errors.StopError(XgettextNotFound, "Could not detect xgettext")
@@ -409,7 +409,7 @@ def _detect_msginit(env):
""" Detects *msginit(1)* program. """
if 'MSGINIT' in env:
return env['MSGINIT']
- msginit = env.Detect('msginit');
+ msginit = env.Detect('msginit')
if msginit:
return msginit
raise SCons.Errors.StopError(MsginitNotFound, "Could not detect msginit")
@@ -428,7 +428,7 @@ def _detect_msgmerge(env):
""" Detects *msgmerge(1)* program. """
if 'MSGMERGE' in env:
return env['MSGMERGE']
- msgmerge = env.Detect('msgmerge');
+ msgmerge = env.Detect('msgmerge')
if msgmerge:
return msgmerge
raise SCons.Errors.StopError(MsgmergeNotFound, "Could not detect msgmerge")
@@ -447,7 +447,7 @@ def _detect_msgfmt(env):
""" Detects *msgmfmt(1)* program. """
if 'MSGFMT' in env:
return env['MSGFMT']
- msgfmt = env.Detect('msgfmt');
+ msgfmt = env.Detect('msgfmt')
if msgfmt:
return msgfmt
raise SCons.Errors.StopError(MsgfmtNotFound, "Could not detect msgfmt")
diff --git a/src/engine/SCons/Tool/JavaCommon.py b/src/engine/SCons/Tool/JavaCommon.py
index 8b13f9f..23cc43b 100644
--- a/src/engine/SCons/Tool/JavaCommon.py
+++ b/src/engine/SCons/Tool/JavaCommon.py
@@ -37,6 +37,10 @@ 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')
+
if java_parsing:
# Parse Java files for class names.
#
@@ -64,8 +68,9 @@ if java_parsing:
interfaces, and anonymous inner classes."""
def __init__(self, version=default_java_version):
- if not version in ('1.1', '1.2', '1.3','1.4', '1.5', '1.6', '1.7',
- '1.8', '5', '6'):
+ if not version 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'):
+
msg = "Java version %s not supported" % version
raise NotImplementedError(msg)
@@ -115,8 +120,8 @@ if java_parsing:
ret = SkipState(1, self)
self.skipState = ret
return ret
-
- def __getAnonStack(self):
+
+ def _getAnonStack(self):
return self.anonStacksStack[-1]
def openBracket(self):
@@ -125,15 +130,16 @@ if java_parsing:
def closeBracket(self):
self.brackets = self.brackets - 1
if len(self.stackBrackets) and \
- self.brackets == self.stackBrackets[-1]:
+ 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]:
- self.__getAnonStack().pop()
+ self.brackets == self.stackAnonClassBrackets[-1] and \
+ self.version not in scopeStateVersions:
+ self._getAnonStack().pop()
self.stackAnonClassBrackets.pop()
def parseToken(self, token):
@@ -171,21 +177,87 @@ if java_parsing:
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'):
+ elif self.version in ('1.5', '1.6', '1.7', '1.8', '5', '6', '9.0', '10.0', '11.0'):
self.stackAnonClassBrackets.append(self.brackets)
className = []
className.extend(self.listClasses)
- self.__getAnonStack()[-1] = self.__getAnonStack()[-1] + 1
- for anon in self.__getAnonStack():
+ 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)
+ self._getAnonStack().append(0)
def setPackage(self, package):
self.package = package
+ class ScopeState(object):
+ """
+ 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(object):
"""A state that looks for anonymous inner classes."""
def __init__(self, old_state):
@@ -212,13 +284,15 @@ if java_parsing:
if token == 'new':
# look further for anonymous inner class
return SkipState(1, AnonClassState(self))
- elif token in [ '"', "'" ]:
+ 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(object):
@@ -245,10 +319,10 @@ if java_parsing:
# 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'
- # http://scons.tigris.org/issues/show_bug.cgi?id=2087
+ # https://github.com/SCons/scons/issues/2087
if self.outer_state.localClasses and \
- self.outer_state.stackBrackets[-1] > \
- self.outer_state.stackBrackets[-2]+1:
+ self.outer_state.stackBrackets[-1] > \
+ self.outer_state.stackBrackets[-2]+1:
locals = self.outer_state.localClasses[-1]
try:
idx = locals[token]
@@ -315,7 +389,7 @@ else:
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(file)
+ return os.path.split(fn)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/JavaCommonTests.py b/src/engine/SCons/Tool/JavaCommonTests.py
index 902030d..10be671 100644
--- a/src/engine/SCons/Tool/JavaCommonTests.py
+++ b/src/engine/SCons/Tool/JavaCommonTests.py
@@ -27,8 +27,6 @@ import os.path
import sys
import unittest
-import TestUnit
-
import SCons.Scanner.IDL
import SCons.Tool.JavaCommon
@@ -566,14 +564,52 @@ public class Foo
assert expect == classes, (expect, classes)
+ def test_in_function_class_declaration(self):
+ """
+ Test that implementing a class in a function call doesn't confuse SCons.
+ """
+
+ input = """
+package com.Matthew;
+
+public class AnonDemo {
+
+ public static void main(String[] args) {
+ new AnonDemo().execute();
+ }
+
+ public void execute() {
+ Foo bar = new Foo(new Foo() {
+ @Override
+ public int getX() { return this.x; }
+ }) {
+ @Override
+ public int getX() { return this.x; }
+ };
+ }
+
+ public abstract class Foo {
+ public int x;
+ public abstract int getX();
+
+ public Foo(Foo f) {
+ this.x = f.x;
+ }
+
+ public Foo() {}
+ }
+}
+"""
+ expect = ['AnonDemo$1',
+ 'AnonDemo$2',
+ 'AnonDemo$Foo',
+ 'AnonDemo']
+ pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.8')
+ assert expect == classes, (expect, classes)
+
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [ parse_javaTestCase ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/MSCommon/arch.py b/src/engine/SCons/Tool/MSCommon/arch.py
index 9bcc221..ad17959 100644
--- a/src/engine/SCons/Tool/MSCommon/arch.py
+++ b/src/engine/SCons/Tool/MSCommon/arch.py
@@ -37,22 +37,22 @@ class ArchDefinition(object):
self.synonyms = synonyms
SupportedArchitectureList = [
- ArchitectureDefinition(
+ ArchDefinition(
'x86',
['i386', 'i486', 'i586', 'i686'],
),
- ArchitectureDefinition(
+ ArchDefinition(
'x86_64',
['AMD64', 'amd64', 'em64t', 'EM64T', 'x86_64'],
),
- ArchitectureDefinition(
+ ArchDefinition(
'ia64',
['IA64'],
),
- ArchitectureDefinition(
+ ArchDefinition(
'arm',
['ARM'],
),
diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py
index 53bd397..32ee96f 100644
--- a/src/engine/SCons/Tool/MSCommon/vc.py
+++ b/src/engine/SCons/Tool/MSCommon/vc.py
@@ -43,6 +43,7 @@ import platform
from string import digits as string_digits
import SCons.Warnings
+from SCons.Tool import find_program_path
from . import common
@@ -357,9 +358,15 @@ def get_installed_vcs():
for ver in _VCVER:
debug('trying to find VC %s' % ver)
try:
- if find_vc_pdir(ver):
+ VC_DIR = find_vc_pdir(ver)
+ if VC_DIR:
debug('found VC %s' % ver)
- installed_versions.append(ver)
+ # check to see if the x86 or 64 bit compiler is in the bin dir
+ if (os.path.exists(os.path.join(VC_DIR, r'bin\cl.exe'))
+ or os.path.exists(os.path.join(VC_DIR, r'bin\amd64\cl.exe'))):
+ installed_versions.append(ver)
+ else:
+ debug('find_vc_pdir no cl.exe found %s' % ver)
else:
debug('find_vc_pdir return None for ver %s' % ver)
except VisualCException as e:
@@ -565,6 +572,12 @@ def msvc_setup_env(env):
for k, v in d.items():
debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v))
env.PrependENVPath(k, v, delete_existing=True)
+
+ # final check to issue a warning if the compiler is not present
+ msvc_cl = find_program_path(env, 'cl')
+ if not msvc_cl:
+ SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning,
+ "Could not find MSVC compiler 'cl.exe', it may need to be installed separately with Visual Studio")
def msvc_exists(version=None):
vcs = cached_get_installed_vcs()
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 42f84e1..8a94a71 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -238,7 +238,7 @@ class Tool(object):
setattr(SCons.Tool, self.name, module)
found_module = module
-
+
if found_module is not None:
sys.path = oldpythonpath
return found_module
@@ -1081,11 +1081,11 @@ class ToolInitializer(object):
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.
+ # 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'])
@@ -1247,6 +1247,35 @@ def tool_list(platform, env):
return [x for x in tools if x]
+
+def find_program_path(env, key_program, default_paths=[]):
+ """
+ Find the location of key_program and then return the path it was located at.
+ Checking the default install locations.
+ Mainly for windows where tools aren't all installed in /usr/bin,etc
+ :param env: Current Environment()
+ :param key_program: Program we're using to locate the directory to add to PATH.
+ """
+ # First search in the SCons path
+ path=env.WhereIs(key_program)
+ if (path):
+ return path
+ # then the OS path:
+ path=SCons.Util.WhereIs(key_program)
+ if (path):
+ return path
+
+ # If that doesn't work try default location for mingw
+ save_path = env['ENV']['PATH']
+ for p in default_paths:
+ env.AppendENVPath('PATH',p)
+ path = env.WhereIs(key_program)
+ if not path:
+ env['ENV']['PATH']=save_path
+ return path
+
+
+
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py
index c5f4376..5a06f9c 100644
--- a/src/engine/SCons/Tool/applelink.py
+++ b/src/engine/SCons/Tool/applelink.py
@@ -39,13 +39,15 @@ import SCons.Util
# the -rpath option, so we use the "link" tool instead of "gnulink".
from . import link
+
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__)}'
+ env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__, RDirs)}'
+
env['_FRAMEWORKS'] = '${_concat("-framework ", FRAMEWORKS, "", __env__)}'
env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib')
@@ -67,8 +69,6 @@ def generate(env):
env['LDMODULEFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -bundle')
env['LDMODULECOM'] = '$LDMODULE -o ${TARGET} $LDMODULEFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
-
-
def exists(env):
return env['PLATFORM'] == 'darwin'
diff --git a/src/engine/SCons/Tool/clang.py b/src/engine/SCons/Tool/clang.py
index 177e6b2..cbb48cb 100644
--- a/src/engine/SCons/Tool/clang.py
+++ b/src/engine/SCons/Tool/clang.py
@@ -45,6 +45,8 @@ import sys
import SCons.Util
import SCons.Tool.cc
+from SCons.Tool.clangCommon import get_clang_install_dirs
+
compilers = ['clang']
@@ -52,11 +54,20 @@ 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)
+
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'],
diff --git a/src/engine/SCons/Tool/clangCommon/__init__.py b/src/engine/SCons/Tool/clangCommon/__init__.py
new file mode 100644
index 0000000..37efbf6
--- /dev/null
+++ b/src/engine/SCons/Tool/clangCommon/__init__.py
@@ -0,0 +1,17 @@
+"""
+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:\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/src/engine/SCons/Tool/clangxx.py b/src/engine/SCons/Tool/clangxx.py
index dd501af..7194d9e 100644
--- a/src/engine/SCons/Tool/clangxx.py
+++ b/src/engine/SCons/Tool/clangxx.py
@@ -46,6 +46,8 @@ import sys
import SCons.Tool
import SCons.Util
import SCons.Tool.cxx
+from SCons.Tool.clangCommon import get_clang_install_dirs
+
compilers = ['clang++']
@@ -66,13 +68,22 @@ def generate(env):
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)
+
# 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
+ if pipe.wait() != 0:
+ return
+
# clang -dumpversion is of no use
line = pipe.stdout.readline()
if sys.version_info[0] > 2:
diff --git a/src/engine/SCons/Tool/docbook/docs/manual.xml b/src/engine/SCons/Tool/docbook/docs/manual.xml
index c129753..64ee925 100644
--- a/src/engine/SCons/Tool/docbook/docs/manual.xml
+++ b/src/engine/SCons/Tool/docbook/docs/manual.xml
@@ -67,7 +67,7 @@ package's <literal>docbook</literal> folder to
<itemizedlist><listitem><para>the SCons User's Guide, chap. 19.7 "Where to put your custom Builders and Tools" and
</para>
</listitem>
-<listitem><para>the SCons Tools Wiki page at <ulink url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.
+<listitem><para>the SCons Tools Wiki page at <ulink url="https://github.com/SCons/scons/wiki/ToolsIndex">http://github.com/SCons/scons/wiki/ToolsIndex</ulink>.
</para>
</listitem>
</itemizedlist>
diff --git a/src/engine/SCons/Tool/gettext_tool.py b/src/engine/SCons/Tool/gettext_tool.py
index 6031e49..41bd70b 100644
--- a/src/engine/SCons/Tool/gettext_tool.py
+++ b/src/engine/SCons/Tool/gettext_tool.py
@@ -27,10 +27,22 @@ __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.Warning(t + ' tool requested, but binary not found in ENV PATH')
env.Tool(t)
env.AddMethod(_translate, 'Translate')
#############################################################################
diff --git a/src/engine/SCons/Tool/gfortran.py b/src/engine/SCons/Tool/gfortran.py
index d33bf52..45750d6 100644
--- a/src/engine/SCons/Tool/gfortran.py
+++ b/src/engine/SCons/Tool/gfortran.py
@@ -54,6 +54,8 @@ def generate(env):
env['INC%sPREFIX' % dialect] = "-I"
env['INC%sSUFFIX' % dialect] = ""
+ env['FORTRANMODDIRPREFIX'] = "-J"
+
def exists(env):
return env.Detect('gfortran')
diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py
index 02da912..9fc0bf7 100644
--- a/src/engine/SCons/Tool/intelc.py
+++ b/src/engine/SCons/Tool/intelc.py
@@ -73,7 +73,7 @@ def linux_ver_normalize(vstr):
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.;
+ return float(vmaj) * 10. + float(vmin) + float(build) / 1000.
else:
f = float(vstr)
if is_windows:
diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py
index b31ccb9..481f8f5 100644
--- a/src/engine/SCons/Tool/jar.py
+++ b/src/engine/SCons/Tool/jar.py
@@ -115,7 +115,7 @@ def Jar(env, target = None, source = [], *args, **kw):
return jars
# they passed no target so make a target implicitly
- if target == None:
+ if target is None:
try:
# make target from the first source file
target = os.path.splitext(str(source[0]))[0] + env.subst('$JARSUFFIX')
@@ -140,7 +140,7 @@ def Jar(env, target = None, source = [], *args, **kw):
# source for jar, otherwise turn it into a class file then
# return the source
def file_to_class(s):
- if(str(_my_normcase(s)).endswith(java_suffix)):
+ if _my_normcase(str(s)).endswith(java_suffix):
return env.JavaClassFile(source = s, *args, **kw)
else:
return [env.fs.File(s)]
@@ -163,19 +163,6 @@ def Jar(env, target = None, source = [], *args, **kw):
else:
return dir_targets
- # In the case that we are passed just string to a node which is directory
- # but does not exist, we need to check all the current targets to see if
- # that directory is going to exist so we can add it as a source to Jar builder
- def get_all_targets(env, node='.'):
- def get_all_targets_iter(env, node):
- if node.has_builder():
- yield node
- for kid in node.all_children():
- for kid in get_all_targets(env, kid):
- yield kid
- node = env.arg2nodes(node, env.fs.Entry)[0]
- return list(get_all_targets_iter(env, node))
-
# 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
@@ -189,27 +176,22 @@ def Jar(env, target = None, source = [], *args, **kw):
# found a dir so get the class files out of it
target_nodes.extend(dir_to_class(s))
else:
- if os.path.isfile(s):
- # found a file that exists on the FS, make sure its a class file
- target_nodes.extend(file_to_class(s))
- elif os.path.isdir(s):
- # found a dir so get the class files out of it
- target_nodes.extend(dir_to_class(s))
- elif s[-len(java_suffix):] == java_suffix or s[-len(java_class_suffix):] == java_class_suffix:
- # found a file that may not exists and is only a string
- # so add it after converting it to a class file
- target_nodes.extend(file_to_class(s))
- else:
- # found a swig file so add it after converting it to class files
- if(os.path.splitext(str(s))[1] == ".i"):
- target_nodes.extend(env.JavaClassFile(source = s, *args, **kw))
- else:
- # The final else case handles anything not caught above and makes
- # sure other nodes that are sources for this jar get add as
- # a source to the JarFile builder
- for node in get_all_targets(env):
- if(s == str(node)):
- target_nodes.append(node)
+ 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.Warning("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)
diff --git a/src/engine/SCons/Tool/javac.py b/src/engine/SCons/Tool/javac.py
index b26c0b3..72c48f7 100644
--- a/src/engine/SCons/Tool/javac.py
+++ b/src/engine/SCons/Tool/javac.py
@@ -34,6 +34,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import os.path
+from collections import OrderedDict
import SCons.Action
import SCons.Builder
@@ -70,7 +71,7 @@ def emit_java_classes(target, source, env):
if isinstance(entry, SCons.Node.FS.File):
slist.append(entry)
elif isinstance(entry, SCons.Node.FS.Dir):
- result = SCons.Util.OrderedDict()
+ result = OrderedDict()
dirnode = entry.rdir()
def find_java_files(arg, dirpath, filenames):
java_files = sorted([n for n in filenames
diff --git a/src/engine/SCons/Tool/javacTests.py b/src/engine/SCons/Tool/javacTests.py
index bf75d8a..96d41b2 100644
--- a/src/engine/SCons/Tool/javacTests.py
+++ b/src/engine/SCons/Tool/javacTests.py
@@ -24,8 +24,6 @@
import os
import unittest
-import TestUnit
-
import SCons.Tool.javac
class DummyNode(object):
@@ -40,14 +38,14 @@ class pathoptTestCase(unittest.TestCase):
popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH')
env = {'FOOPATH': path}
actual = popt(None, None, env, None)
- self.assertEquals(expect, actual)
+ self.assertEqual(expect, actual)
def assert_pathopt_default(self, expect, path, default):
popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH', default='DPATH')
env = {'FOOPATH': path,
'DPATH': default}
actual = popt(None, None, env, None)
- self.assertEquals(expect, actual)
+ self.assertEqual(expect, actual)
def test_unset(self):
self.assert_pathopt([], None)
@@ -101,5 +99,4 @@ class pathoptTestCase(unittest.TestCase):
'')
if __name__ == "__main__":
- suite = unittest.makeSuite(pathoptTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py
index 778db3c..738460d 100644
--- a/src/engine/SCons/Tool/mingw.py
+++ b/src/engine/SCons/Tool/mingw.py
@@ -35,6 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import os.path
+import glob
import SCons.Action
import SCons.Builder
@@ -42,26 +43,14 @@ import SCons.Defaults
import SCons.Tool
import SCons.Util
-# This is what we search for to find mingw:
-key_program = 'mingw32-gcc'
-
-def find(env):
- # First search in the SCons path
- path=env.WhereIs(key_program)
- if (path):
- return path
- # then the OS path:
- path=SCons.Util.WhereIs(key_program)
- if (path):
- return path
-
- # If that doesn't work try default location for mingw
- save_path=env['ENV']['PATH']
- env.AppendENVPath('PATH',r'c:\MinGW\bin')
- path =env.WhereIs(key_program)
- if not path:
- env['ENV']['PATH']=save_path
- return path
+
+mingw_paths = [
+ r'c:\MinGW\bin',
+ r'C:\cygwin64\bin',
+ r'C:\msys64',
+ r'C:\cygwin\bin',
+ r'C:\msys',
+]
def shlib_generator(target, source, env, for_signature):
cmd = SCons.Util.CLVar(['$SHLINK', '$SHLINKFLAGS'])
@@ -126,12 +115,33 @@ 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():
+ """
+ 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):
- mingw = find(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:
- dir = os.path.dirname(mingw)
- env.PrependENVPath('PATH', dir )
-
+ mingw_bin_dir = os.path.dirname(mingw)
+ 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']
@@ -173,7 +183,12 @@ def generate(env):
env['PROGSUFFIX'] = '.exe'
def exists(env):
- return find(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
diff --git a/src/engine/SCons/Tool/msgfmt.py b/src/engine/SCons/Tool/msgfmt.py
index 4fe6afd..3c9dde7 100644
--- a/src/engine/SCons/Tool/msgfmt.py
+++ b/src/engine/SCons/Tool/msgfmt.py
@@ -75,8 +75,22 @@ def _create_mo_file_builder(env, **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.Warning('msgfmt tool requested, but binary not found in ENV PATH')
+
try:
env['MSGFMT'] = _detect_msgfmt(env)
except:
diff --git a/src/engine/SCons/Tool/msginit.py b/src/engine/SCons/Tool/msginit.py
index 39f460d..9e056e7 100644
--- a/src/engine/SCons/Tool/msginit.py
+++ b/src/engine/SCons/Tool/msginit.py
@@ -77,8 +77,22 @@ def _POInitBuilderWrapper(env, target=None, source=_null, **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.Warning('msginit tool requested, but binary not found in ENV PATH')
+
try:
env['MSGINIT'] = _detect_msginit(env)
except:
diff --git a/src/engine/SCons/Tool/msgmerge.py b/src/engine/SCons/Tool/msgmerge.py
index 11d7b48..76661d2 100644
--- a/src/engine/SCons/Tool/msgmerge.py
+++ b/src/engine/SCons/Tool/msgmerge.py
@@ -68,8 +68,21 @@ def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw):
#############################################################################
def generate(env,**kw):
- """ Generate the `xgettext` tool """
+ """ 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.Warning('msgmerge tool requested, but binary not found in ENV PATH')
try:
env['MSGMERGE'] = _detect_msgmerge(env)
except:
diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py
index e1b0536..1412cf7 100644
--- a/src/engine/SCons/Tool/msvc.py
+++ b/src/engine/SCons/Tool/msvc.py
@@ -112,7 +112,7 @@ def object_emitter(target, source, env, parent_emitter):
#
# See issue #2505 for a discussion of what to do if it turns
# out this assumption causes trouble in the wild:
- # http://scons.tigris.org/issues/show_bug.cgi?id=2505
+ # 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':
@@ -195,7 +195,10 @@ def msvc_output_flag(target, source, env, for_signature):
# 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.
- return '/Fo${TARGET.dir}' + os.sep
+ # 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,
diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py
index e1175e0..62f27f2 100644
--- a/src/engine/SCons/Tool/msvs.py
+++ b/src/engine/SCons/Tool/msvs.py
@@ -149,9 +149,9 @@ def splitFully(path):
return [base]
def makeHierarchy(sources):
- '''Break a list of files into a hierarchy; for each value, if it is a string,
+ """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.'''
+ the original path of the file."""
hierarchy = {}
for file in sources:
@@ -189,7 +189,7 @@ class _UserGenerator(object):
elif SCons.Util.is_List(env['variant']):
variants = env['variant']
- if 'DebugSettings' not in env or env['DebugSettings'] == None:
+ if 'DebugSettings' not in env or env['DebugSettings'] is None:
dbg_settings = []
elif SCons.Util.is_Dict(env['DebugSettings']):
dbg_settings = [env['DebugSettings']]
@@ -1287,7 +1287,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User):
'Other Files': ''}
cats = sorted([k for k in list(categories.keys()) if self.sources[k]],
- key = lambda a: a.lower())
+ key = lambda a: a.lower())
# print vcxproj.filters file first
self.filters_file.write('\t<ItemGroup>\n')
@@ -1519,7 +1519,7 @@ class _GenerateV7DSW(_DSWGenerator):
name = base
self.file.write('Project("%s") = "%s", "%s", "%s"\n'
% (external_makefile_guid, name, dspinfo['SLN_RELATIVE_FILE_PATH'], dspinfo['GUID']))
- if self.version_num >= 7.1 and self.version_num < 8.0:
+ if 7.1 <= self.version_num < 8.0:
self.file.write('\tProjectSection(ProjectDependencies) = postProject\n'
'\tEndProjectSection\n')
self.file.write('EndProject\n')
diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py
index dc4b80d..6261f98 100644
--- a/src/engine/SCons/Tool/packaging/__init__.py
+++ b/src/engine/SCons/Tool/packaging/__init__.py
@@ -27,16 +27,21 @@ SCons Packaging Tool.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import SCons.Defaults
import SCons.Environment
from SCons.Variables import *
from SCons.Errors import *
from SCons.Util import is_List, make_path_relative
from SCons.Warnings import warn, Warning
-import os, imp
-import SCons.Defaults
+import os
+import imp
-__all__ = [ 'src_targz', 'src_tarbz2', 'src_zip', 'tarbz2', 'targz', 'zip', 'rpm', 'msi', 'ipk' ]
+__all__ = [
+ 'src_targz', 'src_tarbz2', 'src_xz', 'src_zip',
+ 'targz', 'tarbz2', 'xz', 'zip',
+ 'rpm', 'msi', 'ipk',
+]
#
# Utility and Builder function
@@ -102,7 +107,7 @@ def Package(env, target=None, source=None, **kw):
from SCons.Script import GetOption
kw['PACKAGETYPE'] = GetOption('package_type')
- if kw['PACKAGETYPE'] == None:
+ if kw['PACKAGETYPE'] is None:
if 'Tar' in env['BUILDERS']:
kw['PACKAGETYPE']='targz'
elif 'Zip' in env['BUILDERS']:
@@ -163,15 +168,22 @@ def Package(env, target=None, source=None, **kw):
# 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.
- from inspect import getargspec
- args,varargs,varkw,defaults=getargspec(packager.package)
- if defaults!=None:
- args=args[:-len(defaults)] # throw away arguments with default values
+ #TODO: getargspec deprecated in Py3. cleanup when Py2.7 dropped.
+ try:
+ from inspect import getfullargspec
+ argspec = getfullargspec(packager.package)
+ except ImportError:
+ from inspect import getargspec
+ argspec = getargspec(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]
+ args = [x for x in args if x not in kw]
if len(args)==0:
raise # must be a different error, so re-raise
@@ -283,10 +295,9 @@ def stripinstallbuilder(target, source, env):
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=="InstallBuilder" or\
- file.builder.name=="InstallAsBuilder"))
+ 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(Warning, "there are files to package which have no\
diff --git a/src/engine/SCons/Tool/packaging/__init__.xml b/src/engine/SCons/Tool/packaging/__init__.xml
index e4b1865..41a3f11 100644
--- a/src/engine/SCons/Tool/packaging/__init__.xml
+++ b/src/engine/SCons/Tool/packaging/__init__.xml
@@ -64,13 +64,15 @@ the following packagers available:
<para>
* msi - Microsoft Installer
- * rpm - Redhat Package Manger
+ * rpm - RPM Package Manger
* ipkg - Itsy Package Management System
- * tarbz2 - compressed tar
- * targz - compressed tar
+ * tarbz2 - bzip2 compressed tar
+ * targz - gzip compressed tar
+ * tarxz - xz compressed tar
* zip - zip file
- * src_tarbz2 - compressed tar source
- * src_targz - compressed tar source
+ * src_tarbz2 - bzip2 compressed tar source
+ * src_targz - gzip compressed tar source
+ * src_tarxz - xz compressed tar source
* src_zip - zip file source
</para>
@@ -106,7 +108,9 @@ This is used to fill in the
<literal>Architecture:</literal>
field in an Ipkg
<filename>control</filename> file,
-and as part of the name of a generated RPM file.
+and the <literal>BuildArch:</literal> field
+in the RPM <filename>.spec</filename> file,
+as well as forming part of the name of a generated RPM package file.
</para>
</summary>
</cvar>
@@ -120,7 +124,6 @@ the <filename>control</filename> for Ipkg,
the <filename>.wxs</filename> for MSI).
If set, the function will be called
after the SCons template for the file has been written.
-XXX
</para>
</summary>
</cvar>
@@ -164,10 +167,10 @@ section of an RPM
<cvar name="LICENSE">
<summary>
<para>
-The abbreviated name of the license under which
-this project is released (gpl, lpgl, bsd etc.).
+The abbreviated name, preferably the SPDX code, of the license under which
+this project is released (GPL-3.0, LGPL-2.1, BSD-2-Clause etc.).
See http://www.opensource.org/licenses/alphabetical
-for a list of license names.
+for a list of license names and SPDX codes.
</para>
</summary>
</cvar>
@@ -383,6 +386,7 @@ This is used to fill in the
<literal>BuildRequires:</literal>
field in the RPM
<filename>.spec</filename> file.
+Note this should only be used on a host managed by rpm as the dependencies will not be resolvable at build time otherwise.
</para>
</summary>
</cvar>
@@ -441,7 +445,8 @@ field in the RPM
<para>
This is used to fill in the
<literal>Epoch:</literal>
-field in the controlling information for RPM packages.
+field in the RPM
+<filename>.spec</filename> file.
</para>
</summary>
</cvar>
@@ -468,6 +473,38 @@ field in the RPM
</summary>
</cvar>
+<cvar name="X_RPM_EXTRADEFS">
+<summary>
+<para>
+A list used to supply extra defintions or flags
+to be added to the RPM <filename>.spec</filename> file.
+Each item is added as-is with a carriage return appended.
+This is useful if some specific RPM feature not otherwise
+anticipated by SCons needs to be turned on or off.
+Note if this variable is omitted, SCons will by
+default supply the value
+<literal>'%global debug_package %{nil}'</literal>
+to disable debug package generation.
+To enable debug package generation, include this
+variable set either to None, or to a custom
+list that does not include the default line.
+Added in version 3.1.
+</para>
+
+<example_commands>
+env.Package(
+ NAME = 'foo',
+...
+ X_RPM_EXTRADEFS = [
+ '%define _unpackaged_files_terminate_build 0'
+ '%define _missing_doc_files_terminate_build 0'
+ ],
+... )
+</example_commands>
+
+</summary>
+</cvar>
+
<cvar name="X_RPM_GROUP">
<summary>
<para>
diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py
index c25f856..7e28df3 100644
--- a/src/engine/SCons/Tool/packaging/msi.py
+++ b/src/engine/SCons/Tool/packaging/msi.py
@@ -114,8 +114,7 @@ def gen_dos_short_file_name(file, filename_set):
# thisis1.txt, thisis2.txt etc.
duplicate, num = not None, 1
while duplicate:
- shortname = "%s%s" % (fname[:8-len(str(num))].upper(),\
- str(num))
+ shortname = "%s%s" % (fname[:8-len(str(num))].upper(), str(num))
if len(ext) >= 2:
shortname = "%s%s" % (shortname, ext[:4].upper())
@@ -301,7 +300,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set,
if c.nodeName == 'Directory'
and c.attributes['LongName'].value == escape(d)]
- if already_created != []:
+ if already_created:
Directory = already_created[0]
dir_parts.remove(d)
upper_dir += d
diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py
index a3481a4..0a4db6c 100644
--- a/src/engine/SCons/Tool/packaging/rpm.py
+++ b/src/engine/SCons/Tool/packaging/rpm.py
@@ -51,10 +51,9 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
if str(target[0])!="%s-%s"%(NAME, VERSION):
raise UserError( "Setting target is not supported for rpm." )
else:
- # This should be overridable from the construction environment,
- # which it is by using ARCHITECTURE=.
+ # 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']
@@ -126,20 +125,18 @@ def build_specfile(target, source, env):
""" Builds a RPM specfile from a dictionary with string metadata and
by analyzing a tree of nodes.
"""
- file = open(target[0].get_abspath(), 'w')
-
- try:
- file.write( build_specfile_header(env) )
- file.write( build_specfile_sections(env) )
- file.write( build_specfile_filesection(env, source) )
- file.close()
+ with open(target[0].get_abspath(), 'w') as file:
+ try:
+ file.write(build_specfile_header(env))
+ file.write(build_specfile_sections(env))
+ file.write(build_specfile_filesection(env, source))
- # call a user specified function
- if 'CHANGE_SPECFILE' in env:
- env['CHANGE_SPECFILE'](target, 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] )
+ except KeyError as e:
+ raise SCons.Errors.UserError('"%s" package field for RPM is missing.' % e.args[0])
#
@@ -201,7 +198,8 @@ def build_specfile_header(spec):
'PACKAGEVERSION' : '%%define release %s\nRelease: %%{release}\n',
'X_RPM_GROUP' : 'Group: %s\n',
'SUMMARY' : 'Summary: %s\n',
- 'LICENSE' : 'License: %s\n', }
+ 'LICENSE' : 'License: %s\n',
+ }
str = str + SimpleTagCompiler(mandatory_header_fields).compile( spec )
@@ -211,6 +209,7 @@ def build_specfile_header(spec):
'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',
@@ -229,19 +228,33 @@ def build_specfile_header(spec):
'X_RPM_PREFIX' : 'Prefix: %s\n',
# internal use
- 'X_RPM_BUILDROOT' : 'BuildRoot: %s\n', }
+ 'X_RPM_BUILDROOT' : 'BuildRoot: %s\n',
+ }
# fill in default values:
- # Adding a BuildRequires renders the .rpm unbuildable under System, which
+ # 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 not s.has_key('x_rpm_BuildRequires'):
-# s['x_rpm_BuildRequires'] = 'scons'
+ #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
#
diff --git a/src/engine/SCons/Tool/packaging/src_tarbz2.py b/src/engine/SCons/Tool/packaging/src_tarbz2.py
index 04ea71b..d132291 100644
--- a/src/engine/SCons/Tool/packaging/src_tarbz2.py
+++ b/src/engine/SCons/Tool/packaging/src_tarbz2.py
@@ -1,4 +1,4 @@
-"""SCons.Tool.Packaging.tarbz2
+"""SCons.Tool.Packaging.src_tarbz2
The tarbz2 SRC packager.
"""
diff --git a/src/engine/SCons/Tool/packaging/src_targz.py b/src/engine/SCons/Tool/packaging/src_targz.py
index 62d6f5d..7b759dc 100644
--- a/src/engine/SCons/Tool/packaging/src_targz.py
+++ b/src/engine/SCons/Tool/packaging/src_targz.py
@@ -1,4 +1,4 @@
-"""SCons.Tool.Packaging.targz
+"""SCons.Tool.Packaging.src_targz
The targz SRC packager.
"""
diff --git a/src/engine/SCons/Tool/packaging/src_tarxz.py b/src/engine/SCons/Tool/packaging/src_tarxz.py
new file mode 100644
index 0000000..5889b8a
--- /dev/null
+++ b/src/engine/SCons/Tool/packaging/src_tarxz.py
@@ -0,0 +1,43 @@
+"""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/src/engine/SCons/Tool/packaging/tarbz2.py b/src/engine/SCons/Tool/packaging/tarbz2.py
index 2e38da2..392bf95 100644
--- a/src/engine/SCons/Tool/packaging/tarbz2.py
+++ b/src/engine/SCons/Tool/packaging/tarbz2.py
@@ -1,6 +1,6 @@
"""SCons.Tool.Packaging.tarbz2
-The tarbz2 SRC packager.
+The tarbz2 packager.
"""
#
@@ -32,7 +32,7 @@ from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
def package(env, target, source, PACKAGEROOT, **kw):
bld = env['BUILDERS']['Tar']
- bld.set_suffix('.tar.gz')
+ 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')
diff --git a/src/engine/SCons/Tool/packaging/targz.py b/src/engine/SCons/Tool/packaging/targz.py
index acb6344..4130f32 100644
--- a/src/engine/SCons/Tool/packaging/targz.py
+++ b/src/engine/SCons/Tool/packaging/targz.py
@@ -1,6 +1,6 @@
"""SCons.Tool.Packaging.targz
-The targz SRC packager.
+The targz packager.
"""
#
diff --git a/src/engine/SCons/Tool/packaging/tarxz.py b/src/engine/SCons/Tool/packaging/tarxz.py
new file mode 100644
index 0000000..747296b
--- /dev/null
+++ b/src/engine/SCons/Tool/packaging/tarxz.py
@@ -0,0 +1,44 @@
+"""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/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py
index 77269a8..b8cf77a 100644
--- a/src/engine/SCons/Tool/qt.py
+++ b/src/engine/SCons/Tool/qt.py
@@ -37,6 +37,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os.path
import re
+import glob
import SCons.Action
import SCons.Builder
@@ -44,6 +45,8 @@ import SCons.Defaults
import SCons.Scanner
import SCons.Tool
import SCons.Util
+import SCons.Tool.cxx
+cplusplus = SCons.Tool.cxx
class ToolQtWarning(SCons.Warnings.Warning):
pass
@@ -60,12 +63,33 @@ header_extensions = [".h", ".hxx", ".hpp", ".hh"]
if SCons.Util.case_sensitive_suffixes('.h', '.H'):
header_extensions.append('.H')
-import SCons.Tool.cxx
-cplusplus = SCons.Tool.cxx
-#cplusplus = __import__('cxx', globals(), locals(), [])
-
cxx_suffixes = cplusplus.CXXSuffixes
+
+#
+def find_platform_specific_qt_paths():
+ """
+ If the platform has non-standard paths which it installs QT in,return the likely default path
+ :return:
+ """
+
+ # 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')
+ 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]
@@ -188,13 +212,12 @@ AutomocStatic = _Automoc('StaticObject')
def _detect(env):
"""Not really safe, but fast method to detect the QT library"""
- QTDIR = None
- if not QTDIR:
- QTDIR = env.get('QTDIR',None)
+
+ QTDIR = env.get('QTDIR',None)
if not QTDIR:
QTDIR = os.environ.get('QTDIR',None)
if not QTDIR:
- moc = env.WhereIs('moc')
+ moc = env.WhereIs('moc') or env.WhereIs('moc',QT_BIN_DIR)
if moc:
QTDIR = os.path.dirname(os.path.dirname(moc))
SCons.Warnings.warn(
diff --git a/src/engine/SCons/Tool/rpcgen.py b/src/engine/SCons/Tool/rpcgen.py
index 4af5965..5ed5658 100644
--- a/src/engine/SCons/Tool/rpcgen.py
+++ b/src/engine/SCons/Tool/rpcgen.py
@@ -43,7 +43,7 @@ rpcgen_service = cmd % ('m', '$RPCGENSERVICEFLAGS')
rpcgen_xdr = cmd % ('c', '$RPCGENXDRFLAGS')
def generate(env):
- "Add RPCGEN Builders and construction variables for an Environment."
+ """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')
diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py
index da4472f..08881a0 100644
--- a/src/engine/SCons/Tool/swig.py
+++ b/src/engine/SCons/Tool/swig.py
@@ -35,6 +35,7 @@ from __future__ import print_function
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os.path
+import sys
import re
import subprocess
@@ -169,6 +170,17 @@ def generate(env):
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
+
+ if sys.platform == 'win32':
+ swig = SCons.Tool.find_program_path(env, 'swig', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + [r'C:\ProgramData\chocolatey\bin'] )
+ if swig:
+ swig_bin_dir = os.path.dirname(swig)
+ env.AppendENVPath('PATH', swig_bin_dir)
+ else:
+ SCons.Warnings.Warning('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'])
diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py
index 8e09d56..2dfa229 100644
--- a/src/engine/SCons/Tool/tex.py
+++ b/src/engine/SCons/Tool/tex.py
@@ -790,7 +790,7 @@ def tex_emitter_core(target, source, env, graphics_extensions):
for multibibmatch in multibib_re.finditer(content):
if Verbose:
print("multibib match ",multibibmatch.group(1))
- if multibibmatch != None:
+ if multibibmatch is not None:
baselist = multibibmatch.group(1).split(',')
if Verbose:
print("multibib list ", baselist)
diff --git a/src/engine/SCons/Tool/wixTests.py b/src/engine/SCons/Tool/wixTests.py
index c683e98..6039115 100644
--- a/src/engine/SCons/Tool/wixTests.py
+++ b/src/engine/SCons/Tool/wixTests.py
@@ -33,7 +33,6 @@ from SCons.Tool.wix import *
from SCons.Environment import Environment
import TestCmd
-import TestUnit
# create fake candle and light, so the tool's exists() method will succeed
@@ -53,8 +52,7 @@ class WixTestCase(unittest.TestCase):
assert env.subst('$WIXSRCSUF') == '.wxs'
if __name__ == "__main__":
- suite = unittest.makeSuite(WixTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py
index 2c0ce40..e4a17ca 100644
--- a/src/engine/SCons/Tool/xgettext.py
+++ b/src/engine/SCons/Tool/xgettext.py
@@ -288,9 +288,21 @@ def _POTUpdateBuilder(env, **kw):
#############################################################################
def generate(env, **kw):
""" Generate `xgettext` tool """
+ import sys
+ import os
import SCons.Util
+ import SCons.Tool
from SCons.Tool.GettextCommon import RPaths, _detect_xgettext
-
+ from SCons.Platform.mingw import MINGW_DEFAULT_PATHS
+ from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS
+
+ 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.Warning('xgettext tool requested, but binary not found in ENV PATH')
try:
env['XGETTEXT'] = _detect_xgettext(env)
except:
diff --git a/src/engine/SCons/Tool/yacc.py b/src/engine/SCons/Tool/yacc.py
index 648433b..cd9b9a8 100644
--- a/src/engine/SCons/Tool/yacc.py
+++ b/src/engine/SCons/Tool/yacc.py
@@ -34,10 +34,13 @@ selection method.
__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
YaccAction = SCons.Action.Action("$YACCCOM", "$YACCCOMSTR")
@@ -113,6 +116,14 @@ def generate(env):
cxx_file.add_action('.yy', YaccAction)
cxx_file.add_emitter('.yy', yyEmitter)
+ if sys.platform == 'win32':
+ bison = SCons.Tool.find_program_path(env, 'bison', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS )
+ if bison:
+ bison_bin_dir = os.path.dirname(bison)
+ env.AppendENVPath('PATH', bison_bin_dir)
+ else:
+ SCons.Warnings.Warning('yacc tool requested, but bison binary not found in ENV PATH')
+
env['YACC'] = env.Detect('bison') or 'yacc'
env['YACCFLAGS'] = SCons.Util.CLVar('')
env['YACCCOM'] = '$YACC $YACCFLAGS -o $TARGET $SOURCES'
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index 661c1c5..480d087 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -37,21 +37,18 @@ import pprint
PY3 = sys.version_info[0] == 3
try:
+ from collections import UserDict, UserList, UserString
+except ImportError:
from UserDict import UserDict
-except ImportError as e:
- from collections import UserDict
-
-try:
from UserList import UserList
-except ImportError as e:
- from collections import UserList
-
-from collections import Iterable
+ from UserString import UserString
try:
- from UserString import UserString
-except ImportError as e:
- from collections import UserString
+ from collections.abc import Iterable
+except ImportError:
+ from collections import Iterable
+
+from collections import OrderedDict
# Don't "from types import ..." these because we need to get at the
# types module later to look for UnicodeType.
@@ -63,7 +60,7 @@ MethodType = types.MethodType
FunctionType = types.FunctionType
try:
- unicode
+ _ = type(unicode)
except NameError:
UnicodeType = str
else:
@@ -106,7 +103,7 @@ def containsOnly(str, set):
return 1
def splitext(path):
- "Same as os.path.splitext() but faster."
+ """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
@@ -1048,60 +1045,7 @@ class CLVar(UserList):
def __eq__(self, other):
return str(self) == str(other)
-# A dictionary that preserves the order in which items are added.
-# Submitted by David Benjamin to ActiveState's Python Cookbook web site:
-# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
-# Including fixes/enhancements from the follow-on discussions.
-# TODO: Replace with collections.OrderedDict ? (bdbaddog)
-class OrderedDict(UserDict):
- def __init__(self, dict = None):
- self._keys = []
- UserDict.__init__(self, dict)
-
- def __delitem__(self, key):
- UserDict.__delitem__(self, key)
- self._keys.remove(key)
-
- def __setitem__(self, key, item):
- UserDict.__setitem__(self, key, item)
- if key not in self._keys: self._keys.append(key)
-
- def clear(self):
- UserDict.clear(self)
- self._keys = []
-
- def copy(self):
- dict = OrderedDict()
- dict.update(self)
- return dict
- def items(self):
- return list(zip(self._keys, list(self.values())))
-
- def keys(self):
- return self._keys[:]
-
- def popitem(self):
- try:
- key = self._keys[-1]
- except IndexError:
- raise KeyError('dictionary is empty')
-
- val = self[key]
- del self[key]
-
- return (key, val)
-
- def setdefault(self, key, failobj = None):
- UserDict.setdefault(self, key, failobj)
- if key not in self._keys: self._keys.append(key)
-
- def update(self, dict):
- for (key, val) in dict.items():
- self.__setitem__(key, val)
-
- def values(self):
- return list(map(self.get, self._keys))
class Selector(OrderedDict):
"""A callable ordered dictionary that maps file suffixes to
@@ -1443,8 +1387,8 @@ def make_path_relative(path):
# The original idea for AddMethod() and RenameFunction() come from the
# following post to the ActiveState Python Cookbook:
#
-# ASPN: Python Cookbook : Install bound methods in an instance
-# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/223613
+# ASPN: Python Cookbook : Install bound methods in an instance
+# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/223613
#
# That code was a little fragile, though, so the following changes
# have been wrung on it:
@@ -1461,8 +1405,8 @@ def make_path_relative(path):
# the "new" module, as alluded to in Alex Martelli's response to the
# following Cookbook post:
#
-# ASPN: Python Cookbook : Dynamically added methods to a class
-# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732
+# ASPN: Python Cookbook : Dynamically added methods to a class
+# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732
def AddMethod(obj, function, name=None):
"""
@@ -1624,14 +1568,20 @@ class NullSeq(Null):
del __revision__
-def to_bytes (s):
+
+def to_bytes(s):
if s is None:
return b'None'
+ if not PY3 and isinstance(s, UnicodeType):
+ # PY2, must encode unicode
+ return bytearray(s, 'utf-8')
if isinstance (s, (bytes, bytearray)) or bytes is str:
+ # Above case not covered here as py2 bytes and strings are the same
return s
- return bytes (s, 'utf-8')
+ return bytes(s, 'utf-8')
-def to_str (s):
+
+def to_str(s):
if s is None:
return 'None'
if bytes is str or is_String(s):
@@ -1639,8 +1589,6 @@ def to_str (s):
return str (s, 'utf-8')
-
-# No cmp in py3, so we'll define it.
def cmp(a, b):
"""
Define cmp because it's no longer available in python3
diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py
index 6b12f8a..81ec09d 100644
--- a/src/engine/SCons/UtilTests.py
+++ b/src/engine/SCons/UtilTests.py
@@ -32,7 +32,6 @@ import unittest
from collections import UserDict, UserList, UserString
import TestCmd
-import TestUnit
import SCons.Errors
@@ -307,6 +306,14 @@ class UtilTestCase(unittest.TestCase):
if HasUnicode:
exec("assert not is_Tuple(u'')")
+ def test_to_Bytes(self):
+ """ Test the to_Bytes method"""
+ if not PY3:
+ self.assertEqual(to_bytes(UnicodeType('Hello')),
+ bytearray(u'Hello', 'utf-8'),
+ "Check that to_bytes creates byte array when presented with unicode string. PY2 only")
+
+
def test_to_String(self):
"""Test the to_String() method."""
assert to_String(1) == "1", to_String(1)
@@ -481,8 +488,10 @@ class UtilTestCase(unittest.TestCase):
filename = tempfile.mktemp()
str = '1234567890 ' + filename
try:
- open(filename, 'w').write(str)
- assert open(get_native_path(filename)).read() == str
+ with open(filename, 'w') as f:
+ f.write(str)
+ with open(get_native_path(filename)) as f:
+ assert f.read() == str
finally:
try:
os.unlink(filename)
@@ -843,17 +852,8 @@ class flattenTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [ dictifyTestCase,
- flattenTestCase,
- MD5TestCase,
- NodeListTestCase,
- UtilTestCase,
- ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
+
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Variables/BoolVariableTests.py b/src/engine/SCons/Variables/BoolVariableTests.py
index 7110f6f..3184407 100644
--- a/src/engine/SCons/Variables/BoolVariableTests.py
+++ b/src/engine/SCons/Variables/BoolVariableTests.py
@@ -26,8 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Variables
@@ -118,8 +116,7 @@ class BoolVariableTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.makeSuite(BoolVariableTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Variables/EnumVariableTests.py b/src/engine/SCons/Variables/EnumVariableTests.py
index 931dfe2..4ecb8bd 100644
--- a/src/engine/SCons/Variables/EnumVariableTests.py
+++ b/src/engine/SCons/Variables/EnumVariableTests.py
@@ -26,8 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Variables
@@ -195,8 +193,7 @@ class EnumVariableTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.makeSuite(EnumVariableTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Variables/ListVariableTests.py b/src/engine/SCons/Variables/ListVariableTests.py
index adfd353..ef4832c 100644
--- a/src/engine/SCons/Variables/ListVariableTests.py
+++ b/src/engine/SCons/Variables/ListVariableTests.py
@@ -27,8 +27,6 @@ import copy
import sys
import unittest
-import TestUnit
-
import SCons.Errors
import SCons.Variables
@@ -125,8 +123,7 @@ class ListVariableTestCase(unittest.TestCase):
n = l.__class__(copy.copy(l))
if __name__ == "__main__":
- suite = unittest.makeSuite(ListVariableTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Variables/PackageVariableTests.py b/src/engine/SCons/Variables/PackageVariableTests.py
index 3aa411d..cda3a4a 100644
--- a/src/engine/SCons/Variables/PackageVariableTests.py
+++ b/src/engine/SCons/Variables/PackageVariableTests.py
@@ -30,8 +30,6 @@ import SCons.Errors
import SCons.Variables
import TestCmd
-import TestUnit
-
class PackageVariableTestCase(unittest.TestCase):
def test_PackageVariable(self):
@@ -115,8 +113,7 @@ class PackageVariableTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.makeSuite(PackageVariableTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Variables/PathVariableTests.py b/src/engine/SCons/Variables/PathVariableTests.py
index 3d9d25c..48ad0e0 100644
--- a/src/engine/SCons/Variables/PathVariableTests.py
+++ b/src/engine/SCons/Variables/PathVariableTests.py
@@ -31,8 +31,6 @@ import SCons.Errors
import SCons.Variables
import TestCmd
-import TestUnit
-
class PathVariableTestCase(unittest.TestCase):
def test_PathVariable(self):
@@ -228,8 +226,7 @@ class PathVariableTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.makeSuite(PathVariableTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Variables/VariablesTests.py b/src/engine/SCons/Variables/VariablesTests.py
index 175a14b..43c785f 100644
--- a/src/engine/SCons/Variables/VariablesTests.py
+++ b/src/engine/SCons/Variables/VariablesTests.py
@@ -27,7 +27,6 @@ import sys
import unittest
import TestSCons
-import TestUnit
import SCons.Variables
import SCons.Subst
@@ -60,7 +59,9 @@ def check(key, value, env):
def checkSave(file, expected):
gdict = {}
ldict = {}
- exec(open(file, 'r').read(), gdict, ldict)
+ with open(file, 'r') as f:
+ exec(f.read(), gdict, ldict)
+
assert expected == ldict, "%s\n...not equal to...\n%s" % (expected, ldict)
class VariablesTestCase(unittest.TestCase):
@@ -690,13 +691,7 @@ class UnknownVariablesTestCase(unittest.TestCase):
if __name__ == "__main__":
- suite = unittest.TestSuite()
- tclasses = [ VariablesTestCase,
- UnknownVariablesTestCase ]
- for tclass in tclasses:
- names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(list(map(tclass, names)))
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py
index e8158a4..63acd22 100644
--- a/src/engine/SCons/Warnings.py
+++ b/src/engine/SCons/Warnings.py
@@ -147,6 +147,9 @@ class DeprecatedSigModuleWarning(MandatoryDeprecatedWarning):
class DeprecatedBuilderKeywordsWarning(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.
@@ -179,8 +182,8 @@ def warn(clazz, *args):
global _enabled, _warningAsException, _warningOut
warning = clazz(args)
- for clazz, flag in _enabled:
- if isinstance(warning, clazz):
+ for cls, flag in _enabled:
+ if isinstance(warning, cls):
if flag:
if _warningAsException:
raise warning
diff --git a/src/engine/SCons/WarningsTests.py b/src/engine/SCons/WarningsTests.py
index 7b8d00d..b5c5aef 100644
--- a/src/engine/SCons/WarningsTests.py
+++ b/src/engine/SCons/WarningsTests.py
@@ -26,8 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
-import TestUnit
-
import SCons.Warnings
class TestOutput(object):
@@ -127,8 +125,7 @@ class WarningsTestCase(unittest.TestCase):
assert to.out == "Foo", to.out
if __name__ == "__main__":
- suite = unittest.makeSuite(WarningsTestCase, 'test_')
- TestUnit.run(suite)
+ unittest.main()
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py
index 0b6c016..7ab94c5 100644
--- a/src/engine/SCons/compat/__init__.py
+++ b/src/engine/SCons/compat/__init__.py
@@ -98,7 +98,7 @@ import pickle
# Was pickle.HIGHEST_PROTOCOL
# Changed to 2 so py3.5+'s pickle will be compatible with py2.7.
-PICKLE_PROTOCOL = 2
+PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
# TODO: FIXME
# In 3.x, 'profile' automatically loads the fast version if available.
diff --git a/src/script/scons-time.py b/src/script/scons-time.py
index aa875f1..d114f9a 100644
--- a/src/script/scons-time.py
+++ b/src/script/scons-time.py
@@ -58,12 +58,12 @@ def make_temp_file(**kw):
return result
def HACK_for_exec(cmd, *args):
- '''
+ """
For some reason, Python won't allow an exec() within a function
that also declares an internal function (including lambda functions).
This function is a hack that calls exec() in a function with no
internal functions.
- '''
+ """
if not args: exec(cmd)
elif len(args) == 1: exec(cmd, args[0])
else: exec(cmd, args[0], args[1])
@@ -147,7 +147,7 @@ class Gnuplotter(Plotter):
return line.plot_string()
def vertical_bar(self, x, type, label, comment):
- if self.get_min_x() <= x and x <= self.get_max_x():
+ if self.get_min_x() <= x <= self.get_max_x():
points = [(x, 0), (x, self.max_graph_value(self.get_max_y()))]
self.line(points, type, label, comment)
diff --git a/src/script/sconsign.py b/src/script/sconsign.py
index e7bc271..559dffe 100644
--- a/src/script/sconsign.py
+++ b/src/script/sconsign.py
@@ -275,7 +275,7 @@ def map_bkids(entry, name):
result = []
for i in range(len(bkids)):
result.append(nodeinfo_string(bkids[i], bkidsigs[i], " "))
- if result == []:
+ if not result:
return None
return "\n ".join(result)
diff --git a/src/setup.py b/src/setup.py
index 100e367..273da18 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -247,10 +247,12 @@ class install_lib(_install_lib):
if Options.standalone_lib:
# ...but they asked for a standalone directory.
self.install_dir = os.path.join(prefix, "scons")
- elif Options.version_lib or not Options.standard_lib:
+ elif Options.version_lib:
# ...they asked for a version-specific directory,
- # or they get it by default.
self.install_dir = os.path.join(prefix, "scons-%s" % Version)
+ elif not Options.standard_lib:
+ # default.
+ self.install_dir = os.path.join(prefix, "scons")
msg = "Installed SCons library modules into %s" % self.install_dir
Installed.append(msg)
@@ -416,7 +418,6 @@ arguments = {
'packages': ["SCons",
"SCons.compat",
"SCons.Node",
- "SCons.Options",
"SCons.Platform",
"SCons.Scanner",
"SCons.Script",
diff --git a/src/test_strings.py b/src/test_strings.py
index 297d59d..e9f0abf 100644
--- a/src/test_strings.py
+++ b/src/test_strings.py
@@ -208,12 +208,10 @@ check_list = [
'doc/user/SCons-win32-install-4.jpg',
'examples',
'gentoo',
- 'QMTest/classes.qmc',
- 'QMTest/configuration',
- 'QMTest/TestCmd.py',
- 'QMTest/TestCmdTests.py',
- 'QMTest/TestCommon.py',
- 'QMTest/TestCommonTests.py',
+ 'testing/framework/TestCmd.py',
+ 'testing/framework/TestCmdTests.py',
+ 'testing/framework/TestCommon.py',
+ 'testing/framework/TestCommonTests.py',
'src/MANIFEST.in',
'src/setup.cfg',
'src/engine/MANIFEST.in',
diff --git a/test/AS/nasm.py b/test/AS/nasm.py
index 1733789..4d93c7f 100644
--- a/test/AS/nasm.py
+++ b/test/AS/nasm.py
@@ -47,17 +47,18 @@ if sys.platform.find('linux') == -1:
test.skip_test("skipping test on non-Linux platform '%s'\n" % sys.platform)
try:
- import popen2
- stdout = popen2.popen2('nasm -v')[0]
+ import subprocess
+ stdout = subprocess.check_output(['nasm','-v'])
except OSError:
test.skip_test('could not determine nasm version; skipping test\n')
else:
- version = stdout.read().split()[2]
- if version[:4] != '0.98':
+ stdout = stdout.decode()
+ version = stdout.split()[2].split('.')
+ if int(version[0]) ==0 and int(version[1]) < 98:
test.skip_test("skipping test of nasm version %s\n" % version)
machine = os.uname()[4]
- if not machine in ('i386', 'i486', 'i586', 'i686'):
+ if not machine in ('i386', 'i486', 'i586', 'i686', 'x86_64'):
fmt = "skipping test of nasm %s on non-x86 machine '%s'\n"
test.skip_test(fmt % (version, machine))
@@ -78,6 +79,8 @@ test.file_fixture('wrapper.py')
test.write('SConstruct', """
eee = Environment(tools = ['gcc', 'gnulink', 'nasm'],
+ CFLAGS = ['-m32'],
+ LINKFLAGS = '-m32',
ASFLAGS = '-f %(nasm_format)s')
fff = eee.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('nasm'))
eee.Program(target = 'eee', source = ['eee.asm', 'eee_main.c'])
@@ -99,6 +102,7 @@ name:
""")
test.write('eee_main.c', r"""
+#include <stdio.h>
extern char name[];
int
diff --git a/test/Builder/TargetSubst.py b/test/Builder/TargetSubst.py
index 7d0438c..76ca76c 100644
--- a/test/Builder/TargetSubst.py
+++ b/test/Builder/TargetSubst.py
@@ -35,7 +35,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
builder = Builder(action=Copy('$TARGET', '$SOURCE'))
tgt = builder(env, target="${SOURCE}.out", source="infile")
""")
diff --git a/test/Builder/add_src_builder.py b/test/Builder/add_src_builder.py
index d5b13c1..e499933 100644
--- a/test/Builder/add_src_builder.py
+++ b/test/Builder/add_src_builder.py
@@ -38,6 +38,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
copy_out = Builder(action = Copy('$TARGET', '$SOURCE'),
suffix = '.out',
src_suffix = '.mid')
@@ -46,7 +47,7 @@ copy_mid = Builder(action = Copy('$TARGET', '$SOURCE'),
suffix = '.mid', \
src_suffix = '.in')
-env = Environment()
+env = Environment(tools=[])
env['BUILDERS']['CopyOut'] = copy_out
env['BUILDERS']['CopyMid'] = copy_mid
diff --git a/test/Builder/different-actions.py b/test/Builder/different-actions.py
index f98db93..f355586 100644
--- a/test/Builder/different-actions.py
+++ b/test/Builder/different-actions.py
@@ -34,8 +34,9 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
-e1 = Environment()
-e2 = Environment()
+DefaultEnvironment(tools=[])
+e1 = Environment(tools=[])
+e2 = Environment(tools=[])
e1.Command('out.txt', [], 'echo 1 > $TARGET')
e2.Command('out.txt', [], 'echo 2 > $TARGET')
diff --git a/test/Builder/ensure_suffix.py b/test/Builder/ensure_suffix.py
index 4515ff6..52fb1d4 100644
--- a/test/Builder/ensure_suffix.py
+++ b/test/Builder/ensure_suffix.py
@@ -35,7 +35,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
tbuilder = Builder(action=Copy('$TARGET', '$SOURCE'),
suffix='.dll',
diff --git a/test/Builder/multi/different-actions.py b/test/Builder/multi/different-actions.py
index 66b1e8e..30e98f8 100644
--- a/test/Builder/multi/different-actions.py
+++ b/test/Builder/multi/different-actions.py
@@ -34,13 +34,14 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
file.write(open(str(s), 'rb').read())
B = Builder(action=Action(build, varlist=['XXX']), multi=1)
-env = Environment(BUILDERS = { 'B' : B }, XXX = 'foo')
+env = Environment(tools=[], BUILDERS = { 'B' : B }, XXX = 'foo')
env2 = env.Clone(XXX = 'var')
env.B(target = 'file6.out', source = 'file6a.in')
env2.B(target = 'file6.out', source = 'file6b.in')
diff --git a/test/Builder/multi/different-environments.py b/test/Builder/multi/different-environments.py
index c3e96c2..686e15c 100644
--- a/test/Builder/multi/different-environments.py
+++ b/test/Builder/multi/different-environments.py
@@ -47,8 +47,9 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:])
""")
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
B = Builder(action=r'%(_python_)s build.py $foo $TARGET $SOURCES', multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'file03.out', source = 'file03a.in', foo=1)
env.B(target = 'file03.out', source = 'file03b.in', foo=2)
""" % locals())
diff --git a/test/Builder/multi/different-multi.py b/test/Builder/multi/different-multi.py
index dce235e..28002bd 100644
--- a/test/Builder/multi/different-multi.py
+++ b/test/Builder/multi/different-multi.py
@@ -34,6 +34,8 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
@@ -47,7 +49,7 @@ def build2(env, target, source):
# or how we mess with the Builder internals.
B = Builder(action=build, multi=1, name='B')
C = Builder(action=build2, multi=1, name='C')
-env = Environment(BUILDERS = { 'B' : B, 'C' : C })
+env = Environment(tools=[], BUILDERS = { 'B' : B, 'C' : C })
env.B(target = 'file8.out', source = 'file8.in')
env.C(target = 'file8.out', source = 'file8.in')
""")
diff --git a/test/Builder/multi/different-order.py b/test/Builder/multi/different-order.py
index 99a19c2..c423969 100644
--- a/test/Builder/multi/different-order.py
+++ b/test/Builder/multi/different-order.py
@@ -36,6 +36,7 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def build(env, target, source):
for t in target:
file = open(str(target[0]), 'wb')
@@ -43,7 +44,7 @@ def build(env, target, source):
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = ['file10a.out', 'file10b.out'], source = 'file10.in')
env.B(target = ['file10b.out', 'file10a.out'], source = 'file10.in')
""")
diff --git a/test/Builder/multi/different-overrides.py b/test/Builder/multi/different-overrides.py
index 8eb3e13..6a38a93 100644
--- a/test/Builder/multi/different-overrides.py
+++ b/test/Builder/multi/different-overrides.py
@@ -34,13 +34,14 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'file3.out', source = 'file3a.in', foo=1)
env.B(target = 'file3.out', source = 'file3b.in', foo=2)
""")
diff --git a/test/Builder/multi/different-target-lists.py b/test/Builder/multi/different-target-lists.py
index 39e388c..437311f 100644
--- a/test/Builder/multi/different-target-lists.py
+++ b/test/Builder/multi/different-target-lists.py
@@ -40,6 +40,7 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def build(env, target, source):
for t in target:
file = open(str(target[0]), 'wb')
@@ -47,7 +48,7 @@ def build(env, target, source):
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = ['file11a.out', 'file11b.out'], source = 'file11a.in')
env.B(target = ['file11b.out', 'file11c.out'], source = 'file11b.in')
""")
diff --git a/test/Builder/multi/error.py b/test/Builder/multi/error.py
index 37a012b..2de23d3 100644
--- a/test/Builder/multi/error.py
+++ b/test/Builder/multi/error.py
@@ -34,13 +34,15 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=0)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'file2.out', source = 'file2a.in')
env.B(target = 'file2.out', source = 'file2b.in')
""")
diff --git a/test/Builder/multi/lone-target-list.py b/test/Builder/multi/lone-target-list.py
index 40e7dc9..7c02c4a 100644
--- a/test/Builder/multi/lone-target-list.py
+++ b/test/Builder/multi/lone-target-list.py
@@ -33,6 +33,8 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
for t in target:
file = open(str(target[0]), 'wb')
@@ -40,7 +42,7 @@ def build(env, target, source):
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = ['file12a.out', 'file12b.out'], source = 'file12a.in')
env.B(target = 'file12a.out', source = 'file12b.in')
""")
diff --git a/test/Builder/multi/multi.py b/test/Builder/multi/multi.py
index b2ceae9..0f83d71 100644
--- a/test/Builder/multi/multi.py
+++ b/test/Builder/multi/multi.py
@@ -34,13 +34,15 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'file1.out', source = 'file1a.in')
env.B(target = 'file1.out', source = 'file1b.in')
""")
diff --git a/test/Builder/multi/same-actions.py b/test/Builder/multi/same-actions.py
index 5695fa3..0b75566 100644
--- a/test/Builder/multi/same-actions.py
+++ b/test/Builder/multi/same-actions.py
@@ -34,13 +34,15 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env2 = env.Clone(DIFFERENT_VARIABLE = 'true')
env.B(target = 'file5.out', source = 'file5a.in')
env2.B(target = 'file5.out', source = 'file5b.in')
diff --git a/test/Builder/multi/same-overrides.py b/test/Builder/multi/same-overrides.py
index 95c0759..e51b2ef 100644
--- a/test/Builder/multi/same-overrides.py
+++ b/test/Builder/multi/same-overrides.py
@@ -45,8 +45,10 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:])
""")
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
B = Builder(action=r'%(_python_)s build.py $foo $TARGET $SOURCES', multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'file4.out', source = 'file4a.in', foo=3)
env.B(target = 'file4.out', source = 'file4b.in', foo=3)
""" % locals())
diff --git a/test/Builder/multi/same-targets.py b/test/Builder/multi/same-targets.py
index 714b9da..c800a1c 100644
--- a/test/Builder/multi/same-targets.py
+++ b/test/Builder/multi/same-targets.py
@@ -34,6 +34,8 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
for t in target:
file = open(str(t), 'wb')
@@ -41,7 +43,7 @@ def build(env, target, source):
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = ['file9a.out', 'file9b.out'], source = 'file9a.in')
env.B(target = ['file9a.out', 'file9b.out'], source = 'file9b.in')
""")
diff --git a/test/Builder/non-multi.py b/test/Builder/non-multi.py
index baf0ed0..0ddb038 100644
--- a/test/Builder/non-multi.py
+++ b/test/Builder/non-multi.py
@@ -34,13 +34,15 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
file.write(open(str(s), 'rb').read())
B = Builder(action=build, multi=0)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'file7.out', source = 'file7.in')
env.B(target = 'file7.out', source = 'file7.in')
env.B(target = 'file8.out', source = 'file8.in', arg=1)
diff --git a/test/Builder/same-actions-diff-envs.py b/test/Builder/same-actions-diff-envs.py
index b111737..289ee09 100644
--- a/test/Builder/same-actions-diff-envs.py
+++ b/test/Builder/same-actions-diff-envs.py
@@ -34,13 +34,15 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
file = open(str(target[0]), 'w')
file.write('1')
B = Builder(action=build)
-env = Environment(BUILDERS = { 'B' : B })
-env2 = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
+env2 = Environment(tools=[], BUILDERS = { 'B' : B })
env.B('out.txt', [])
env2.B('out.txt', [])
""")
diff --git a/test/Builder/same-actions-diff-overrides.py b/test/Builder/same-actions-diff-overrides.py
index dde7dd9..2b7cefe 100644
--- a/test/Builder/same-actions-diff-overrides.py
+++ b/test/Builder/same-actions-diff-overrides.py
@@ -34,12 +34,14 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+
def build(env, target, source):
file = open(str(target[0]), 'w')
file.write('1')
B = Builder(action=build)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B('out.txt', [], arg=1)
env.B('out.txt', [], arg=2)
""")
diff --git a/test/Builder/srcdir.py b/test/Builder/srcdir.py
index 669c5e1..d7a9e18 100644
--- a/test/Builder/srcdir.py
+++ b/test/Builder/srcdir.py
@@ -48,6 +48,8 @@ o.close()
""")
test.write(['src', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
+
Command('output',
['file1', File('file2'), r'%(file3)s', 'file4'],
r'%(_python_)s cat.py $TARGET $SOURCES',
diff --git a/test/Builder/wrapper.py b/test/Builder/wrapper.py
index ae62846..3ee9f79 100644
--- a/test/Builder/wrapper.py
+++ b/test/Builder/wrapper.py
@@ -34,6 +34,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
+
import os.path
import string
def cat(target, source, env):
@@ -49,7 +51,8 @@ def Wrapper(env, target, source):
env.Cat(t1, source)
t2 = 't2-'+str(target[0])
env.Cat(t2, source)
-env = Environment(BUILDERS = {'Cat' : Cat,
+env = Environment(tools=[],
+ BUILDERS = {'Cat' : Cat,
'Wrapper' : Wrapper})
env.Wrapper('f1.out', 'f1.in')
env.Wrapper('f2.in')
diff --git a/test/CPPDEFINES/append.py b/test/CPPDEFINES/append.py
index 7973f22..874fceb 100644
--- a/test/CPPDEFINES/append.py
+++ b/test/CPPDEFINES/append.py
@@ -43,7 +43,7 @@ env_1738_2.Append(CPPDEFINES={'value' : '1'})
print(env_1738_2.subst('$_CPPDEFFLAGS'))
#env_1738_2.Object('test_1738_2', 'main.c')
-# http://scons.tigris.org/issues/show_bug.cgi?id=2300
+# https://github.com/SCons/scons/issues/2300
env_2300_1 = Environment(CPPDEFINES = 'foo', CPPDEFPREFIX='-D')
env_2300_1.Append(CPPDEFINES='bar')
print(env_2300_1.subst('$_CPPDEFFLAGS'))
@@ -52,8 +52,8 @@ env_2300_2 = Environment(CPPDEFINES = ['foo'], CPPDEFPREFIX='-D') # note the lis
env_2300_2.Append(CPPDEFINES='bar')
print(env_2300_2.subst('$_CPPDEFFLAGS'))
-# http://scons.tigris.org/issues/show_bug.cgi?id=1152
-# http://scons.tigris.org/issues/show_bug.cgi?id=2900
+# https://github.com/SCons/scons/issues/1152
+# https://github.com/SCons/scons/issues/2900
# Python3 dicts dont preserve order. Hence we supply subclass of OrderedDict
# whose __str__ and __repr__ act like a normal dict.
from collections import OrderedDict
diff --git a/test/CPPDEFINES/pkg-config.py b/test/CPPDEFINES/pkg-config.py
index 42f38b6..65210ce 100644
--- a/test/CPPDEFINES/pkg-config.py
+++ b/test/CPPDEFINES/pkg-config.py
@@ -29,12 +29,14 @@ Verify merging with MergeFlags to CPPPDEFINES with various data types.
"""
import TestSCons
+import TestCmd
test = TestSCons.TestSCons()
pkg_config_path = test.where_is('pkg-config')
if not pkg_config_path:
test.skip_test("Could not find 'pkg-config' in system PATH, skipping test.\n")
+pkg_config_path = pkg_config_path.replace("\\", "/")
test.write('bug.pc', """\
prefix=/usr
@@ -55,7 +57,18 @@ int main(int argc, char *argv[])
}
""")
+if TestCmd.IS_WINDOWS:
+ pkg_config_file = 'bug.pc'
+ pkg_config_tools = 'mingw'
+ pkg_config_cl_path = ""
+else:
+ pkg_config_file = 'bug'
+ pkg_config_tools = 'default'
+ pkg_config_cl_path = "PKG_CONFIG_PATH=."
+
test.write('SConstruct', """\
+import os
+import sys
# Python3 dicts dont preserve order. Hence we supply subclass of OrderedDict
# whose __str__ and __repr__ act like a normal dict.
from collections import OrderedDict
@@ -70,28 +83,30 @@ class OrderedPrintingDict(OrderedDict):
def __semi_deepcopy__(self):
return self.copy()
""" + """
-# http://scons.tigris.org/issues/show_bug.cgi?id=2671
+# https://github.com/SCons/scons/issues/2671
# Passing test cases
-env_1 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST'])
-env_1.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags bug')
+env_1 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST'], tools = ['%(pkg_config_tools)s'])
+if sys.platform == 'win32':
+ os.environ['PKG_CONFIG_PATH'] = env_1.Dir('.').abspath.replace("\\\\" , "/")
+env_1.ParseConfig('%(pkg_config_cl_path)s "%(pkg_config_path)s" --cflags %(pkg_config_file)s')
print(env_1.subst('$_CPPDEFFLAGS'))
-env_2 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST'])
+env_2 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST'], tools = ['%(pkg_config_tools)s'])
env_2.MergeFlags('-DSOMETHING -DVARIABLE=2')
print(env_2.subst('$_CPPDEFFLAGS'))
# Failing test cases
-env_3 = Environment(CPPDEFINES=OrderedPrintingDict([('DEBUG', 1), ('TEST', None)]))
-env_3.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags bug')
+env_3 = Environment(CPPDEFINES=OrderedPrintingDict([('DEBUG', 1), ('TEST', None)]), tools = ['%(pkg_config_tools)s'])
+env_3.ParseConfig('%(pkg_config_cl_path)s "%(pkg_config_path)s" --cflags %(pkg_config_file)s')
print(env_3.subst('$_CPPDEFFLAGS'))
-env_4 = Environment(CPPDEFINES=OrderedPrintingDict([('DEBUG', 1), ('TEST', None)]))
+env_4 = Environment(CPPDEFINES=OrderedPrintingDict([('DEBUG', 1), ('TEST', None)]), tools = ['%(pkg_config_tools)s'])
env_4.MergeFlags('-DSOMETHING -DVARIABLE=2')
print(env_4.subst('$_CPPDEFFLAGS'))
-# http://scons.tigris.org/issues/show_bug.cgi?id=1738
-env_1738_1 = Environment(tools=['default'])
-env_1738_1.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags --libs bug')
+# https://github.com/SCons/scons/issues/1738
+env_1738_1 = Environment(tools = ['%(pkg_config_tools)s'])
+env_1738_1.ParseConfig('%(pkg_config_cl_path)s "%(pkg_config_path)s" --cflags --libs %(pkg_config_file)s')
env_1738_1.Append(CPPDEFINES={'value' : '1'})
print(env_1738_1.subst('$_CPPDEFFLAGS'))
"""%locals() )
diff --git a/test/CacheDir/CacheDir.py b/test/CacheDir/CacheDir.py
index 45c5db5..3d2c3b5 100644
--- a/test/CacheDir/CacheDir.py
+++ b/test/CacheDir/CacheDir.py
@@ -45,6 +45,7 @@ src_all = test.workpath('src', 'all')
test.subdir('cache', 'src')
test.write(['src', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
CacheDir(r'%(cache)s')
SConscript('SConscript')
""" % locals())
@@ -57,7 +58,7 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
diff --git a/test/CacheDir/NoCache.py b/test/CacheDir/NoCache.py
index b035b44..f0929aa 100644
--- a/test/CacheDir/NoCache.py
+++ b/test/CacheDir/NoCache.py
@@ -35,6 +35,7 @@ test = TestSCons.TestSCons()
test.subdir('cache', 'alpha', 'beta')
sconstruct = """
+DefaultEnvironment(tools=[])
import os
CacheDir(r'%s')
diff --git a/test/CacheDir/SideEffect.py b/test/CacheDir/SideEffect.py
index 2ddba31..4eae4c3 100644
--- a/test/CacheDir/SideEffect.py
+++ b/test/CacheDir/SideEffect.py
@@ -37,6 +37,7 @@ test.subdir('cache', 'work')
cache = test.workpath('cache')
test.write(['work', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
def copy(source, target):
open(target, "w").write(open(source, "r").read())
@@ -51,7 +52,7 @@ def build(env, source, target):
CacheDir(r'%(cache)s')
Build = Builder(action=build)
-env = Environment(BUILDERS={'Build':Build}, SUBDIR='subdir')
+env = Environment(tools=[], BUILDERS={'Build':Build}, SUBDIR='subdir')
env.Build('f1.out', 'f1.in')
env.Build('f2.out', 'f2.in')
env.Build('f3.out', 'f3.in')
diff --git a/test/CacheDir/VariantDir.py b/test/CacheDir/VariantDir.py
index d31b9ed..58918be 100644
--- a/test/CacheDir/VariantDir.py
+++ b/test/CacheDir/VariantDir.py
@@ -47,7 +47,7 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
@@ -65,7 +65,8 @@ test.write(['src', 'ccc.in'], "ccc.in\n")
#
test.write('SConstruct', """\
-env = Environment(TWO = '2')
+DefaultEnvironment(tools=[])
+env = Environment(tools=[], TWO = '2')
CacheDir(r'%s')
VariantDir('build', 'src', duplicate=0)
SConscript('build/SConscript')
diff --git a/test/CacheDir/debug.py b/test/CacheDir/debug.py
index e3186b0..7e08e0b 100644
--- a/test/CacheDir/debug.py
+++ b/test/CacheDir/debug.py
@@ -45,6 +45,7 @@ debug_out = test.workpath('cache-debug.out')
test.write(['src', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
CacheDir(r'%(cache)s')
SConscript('SConscript')
""" % locals())
@@ -57,7 +58,7 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
diff --git a/test/CacheDir/environment.py b/test/CacheDir/environment.py
index e37b999..5d8eb6c 100644
--- a/test/CacheDir/environment.py
+++ b/test/CacheDir/environment.py
@@ -46,6 +46,7 @@ src_all = test.workpath('src', 'all')
test.subdir('cache', 'src')
test.write(['src', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
CacheDir(r'%(cache)s')
SConscript('SConscript')
""" % locals())
@@ -58,7 +59,7 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env_cache = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env_cache = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env_nocache = env_cache.Clone()
env_nocache.CacheDir(None)
env_cache.Cat('aaa.out', 'aaa.in')
diff --git a/test/CacheDir/multi-targets.py b/test/CacheDir/multi-targets.py
index 9ca194e..7977ba0 100644
--- a/test/CacheDir/multi-targets.py
+++ b/test/CacheDir/multi-targets.py
@@ -40,11 +40,12 @@ multiple_bar = test.workpath('multiple', 'bar')
multiple_foo = test.workpath('multiple', 'foo')
test.write(['multiple', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
def touch(env, source, target):
open('foo', 'w').write("")
open('bar', 'w').write("")
CacheDir(r'%(cache)s')
-env = Environment()
+env = Environment(tools=[])
env.Command(['foo', 'bar'], ['input'], touch)
""" % locals())
diff --git a/test/CacheDir/multiple-targets.py b/test/CacheDir/multiple-targets.py
index d7e6ac7..9f94e4c 100644
--- a/test/CacheDir/multiple-targets.py
+++ b/test/CacheDir/multiple-targets.py
@@ -38,11 +38,12 @@ test = TestSCons.TestSCons()
test.subdir('cache')
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def touch(env, source, target):
open('foo', 'w').write("")
open('bar', 'w').write("")
CacheDir(r'%s')
-env = Environment()
+env = Environment(tools=[], )
env.Command(['foo', 'bar'], ['input'], touch)
""" % (test.workpath('cache')))
diff --git a/test/CacheDir/option--cd.py b/test/CacheDir/option--cd.py
index fad5add..20d1184 100644
--- a/test/CacheDir/option--cd.py
+++ b/test/CacheDir/option--cd.py
@@ -39,6 +39,7 @@ test = TestSCons.TestSCons()
test.subdir('cache', 'src')
test.write(['src', 'SConstruct'], """
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
open('cat.out', 'a').write(target + "\\n")
@@ -46,7 +47,7 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
diff --git a/test/CacheDir/option--cf.py b/test/CacheDir/option--cf.py
index bb9d1cc..5e823ae 100644
--- a/test/CacheDir/option--cf.py
+++ b/test/CacheDir/option--cf.py
@@ -46,7 +46,7 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
diff --git a/test/CacheDir/option--cr.py b/test/CacheDir/option--cr.py
index 792dede..4ed587c 100644
--- a/test/CacheDir/option--cr.py
+++ b/test/CacheDir/option--cr.py
@@ -39,6 +39,7 @@ test = TestSCons.TestSCons()
test.subdir('cache', 'src')
test.write(['src', 'SConstruct'], """
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
open('cat.out', 'a').write(target + "\\n")
@@ -46,7 +47,7 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
diff --git a/test/CacheDir/option--cs.py b/test/CacheDir/option--cs.py
index 2e37e5a..b73fb70 100644
--- a/test/CacheDir/option--cs.py
+++ b/test/CacheDir/option--cs.py
@@ -55,6 +55,7 @@ file.close()
cache = test.workpath('cache')
test.write(['src1', 'SConstruct'], """
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
open('cat.out', 'a').write(target + "\\n")
@@ -62,7 +63,8 @@ def cat(env, source, target):
for src in source:
f.write(open(str(src), "r").read())
f.close()
-env = Environment(BUILDERS={'Internal':Builder(action=cat),
+env = Environment(tools=[],
+ BUILDERS={'Internal':Builder(action=cat),
'External':Builder(action=r'%(_python_)s build.py $TARGET $SOURCES')})
env.External('aaa.out', 'aaa.in')
env.External('bbb.out', 'bbb.in')
diff --git a/test/CacheDir/readonly-cache.py b/test/CacheDir/readonly-cache.py
new file mode 100755
index 0000000..6520106
--- /dev/null
+++ b/test/CacheDir/readonly-cache.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify accessing cache works even if it's read-only.
+"""
+
+import glob
+import os
+import TestSCons
+import time
+from stat import *
+
+test = TestSCons.TestSCons()
+
+test.write(['SConstruct'], """\
+DefaultEnvironment(tools=[])
+CacheDir('cache')
+Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
+""")
+
+test.write('file.in', "file.in\n")
+
+test.run(arguments = '--debug=explain --cache-debug=- .')
+
+cachefile = glob.glob("cache/??/*")[0]
+
+time0 = os.stat(cachefile).st_mtime
+
+time.sleep(.1)
+
+test.unlink('file.out')
+
+test.run(arguments = '--debug=explain --cache-debug=- .')
+
+time1 = os.stat(cachefile).st_mtime
+
+# make sure that mtime has been updated on cache use
+if time1 <= time0:
+ test.fail_test()
+
+test.unlink('file.out')
+
+for root, dirs, files in os.walk("cache",topdown=False):
+ for file in files:
+ os.chmod(os.path.join(root,file),0o444)
+ for dir in dirs:
+ os.chmod(os.path.join(root,dir),0o555)
+
+test.run(arguments = '--debug=explain --cache-debug=- .')
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/CacheDir/scanner-target.py b/test/CacheDir/scanner-target.py
index c39042e..7df9792 100644
--- a/test/CacheDir/scanner-target.py
+++ b/test/CacheDir/scanner-target.py
@@ -41,6 +41,7 @@ test = TestSCons.TestSCons()
test.subdir('cache')
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
import SCons
CacheDir(r'%s')
diff --git a/test/CacheDir/source-scanner.py b/test/CacheDir/source-scanner.py
index 2359872..f00360d 100644
--- a/test/CacheDir/source-scanner.py
+++ b/test/CacheDir/source-scanner.py
@@ -43,6 +43,7 @@ cache = test.workpath('cache')
test.subdir('cache', 'subdir')
test.write(['subdir', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
import SCons
CacheDir(r'%(cache)s')
diff --git a/test/CacheDir/timestamp-match.py b/test/CacheDir/timestamp-match.py
index afc3f63..4b64137 100644
--- a/test/CacheDir/timestamp-match.py
+++ b/test/CacheDir/timestamp-match.py
@@ -33,6 +33,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write(['SConstruct'], """\
+DefaultEnvironment(tools=[])
Decider('timestamp-match')
CacheDir('cache')
Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
diff --git a/test/CacheDir/timestamp-newer.py b/test/CacheDir/timestamp-newer.py
index 8a47fec..618f467 100644
--- a/test/CacheDir/timestamp-newer.py
+++ b/test/CacheDir/timestamp-newer.py
@@ -33,6 +33,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write(['SConstruct'], """\
+DefaultEnvironment(tools=[])
Decider('timestamp-newer')
CacheDir('cache')
Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
diff --git a/test/CacheDir/up-to-date-q.py b/test/CacheDir/up-to-date-q.py
index 275b127..f0e3962 100644
--- a/test/CacheDir/up-to-date-q.py
+++ b/test/CacheDir/up-to-date-q.py
@@ -55,7 +55,7 @@ test = TestSCons.TestSCons()
test.subdir('cache', 'alpha', 'beta')
foo_c = """
-int main(){ return 0; }
+int main(void){ return 0; }
"""
sconstruct = """
diff --git a/test/Case.py b/test/Case.py
index fb6821d..193da54 100644
--- a/test/Case.py
+++ b/test/Case.py
@@ -43,7 +43,7 @@ test.write('main.c', """\
void foo();
void bar();
-int main() {
+int main(void) {
foo();
bar();
exit (0);
diff --git a/test/Clang/clang_default_environment.py b/test/Clang/clang_default_environment.py
index 4ac1c68..5ebd839 100644
--- a/test/Clang/clang_default_environment.py
+++ b/test/Clang/clang_default_environment.py
@@ -35,9 +35,8 @@ if not test.where_is('clang'):
## This will likely NOT use clang
test.write('SConstruct', """
-env = Environment()
-if env['CC'] != 'clang':
- env['CC'] = 'clang'
+DefaultEnvironment(tools=[])
+env = Environment(tools=['clang','link'])
env.Program('foo.c')
""")
diff --git a/test/Clang/clang_shared_library.py b/test/Clang/clang_shared_library.py
index 5e4d36f..9af3770 100644
--- a/test/Clang/clang_shared_library.py
+++ b/test/Clang/clang_shared_library.py
@@ -33,20 +33,22 @@ test = TestSCons.TestSCons()
if not test.where_is('clang'):
test.skip_test("Could not find 'clang', skipping test.\n")
-platform = Base()['PLATFORM']
+base = Base()
+platform = base['PLATFORM']
if platform == 'posix':
- filename = 'foo.os'
+ filename_options = ['foo.os']
libraryname = 'libfoo.so'
elif platform == 'darwin':
- filename = 'foo.os'
+ filename_options = ['foo.os']
libraryname = 'libfoo.dylib'
elif platform == 'win32':
- filename = 'foo.obj'
+ filename_options = ['foo.obj','foo.os']
libraryname = 'foo.dll'
else:
test.fail_test()
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
env = Environment(tools=['clang', 'link'])
env.SharedLibrary('foo', 'foo.c')
""")
@@ -59,7 +61,7 @@ int bar() {
test.run()
-test.must_exist(test.workpath(filename))
+test.must_exist_one_of([test.workpath(f) for f in filename_options])
test.must_exist(test.workpath(libraryname))
test.pass_test()
diff --git a/test/Clang/clang_specific_environment.py b/test/Clang/clang_specific_environment.py
index 7266a9f..81991f0 100644
--- a/test/Clang/clang_specific_environment.py
+++ b/test/Clang/clang_specific_environment.py
@@ -33,6 +33,7 @@ if not test.where_is('clang'):
test.skip_test("Could not find 'clang', skipping test.\n")
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
env = Environment(tools=['clang', 'link'])
env.Program('foo.c')
""")
diff --git a/test/Clang/clang_static_library.py b/test/Clang/clang_static_library.py
index 39e9931..7dedc6f 100644
--- a/test/Clang/clang_static_library.py
+++ b/test/Clang/clang_static_library.py
@@ -33,7 +33,8 @@ if not test.where_is('clang'):
test.skip_test("Could not find 'clang', skipping test.\n")
test.write('SConstruct', """\
-env = Environment(tools=['clang', 'ar'])
+DefaultEnvironment(tools=[])
+env = Environment(tools=['mingw','clang', 'ar'])
env.StaticLibrary('foo', 'foo.c')
""")
diff --git a/test/Clang/clangxx_default_environment.py b/test/Clang/clangxx_default_environment.py
index beef1e5..5e46404 100644
--- a/test/Clang/clangxx_default_environment.py
+++ b/test/Clang/clangxx_default_environment.py
@@ -35,9 +35,8 @@ if not test.where_is('clang'):
## This will likely NOT use clang++.
test.write('SConstruct', """\
-env = Environment()
-if env['CXX'] != 'clang++':
- env['CXX'] = 'clang++'
+DefaultEnvironment(tools=[])
+env = Environment(tools=['clangxx','link'])
env.Program('foo.cpp')
""")
diff --git a/test/Clang/clangxx_shared_library.py b/test/Clang/clangxx_shared_library.py
index d6337ba..6240299 100644
--- a/test/Clang/clangxx_shared_library.py
+++ b/test/Clang/clangxx_shared_library.py
@@ -36,18 +36,21 @@ if not test.where_is('clang'):
platform = Base()['PLATFORM']
if platform == 'posix':
- filename = 'foo.os'
+ filename_options = ['foo.os']
libraryname = 'libfoo.so'
elif platform == 'darwin':
- filename = 'foo.os'
+ filename_options = ['foo.os']
libraryname = 'libfoo.dylib'
elif platform == 'win32':
- filename = 'foo.obj'
+ filename_options = ['foo.obj','foo.os']
libraryname = 'foo.dll'
else:
test.fail_test()
+
+
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
env = Environment(tools=['clang++', 'link'])
env.SharedLibrary('foo', 'foo.cpp')
""")
@@ -60,7 +63,7 @@ int bar() {
test.run()
-test.must_exist(test.workpath(filename))
+test.must_exist_one_of([test.workpath(f) for f in filename_options])
test.must_exist(test.workpath(libraryname))
test.pass_test()
diff --git a/test/Clang/clangxx_specific_environment.py b/test/Clang/clangxx_specific_environment.py
index 773fa94..39eaab1 100644
--- a/test/Clang/clangxx_specific_environment.py
+++ b/test/Clang/clangxx_specific_environment.py
@@ -33,6 +33,7 @@ if not test.where_is('clang'):
test.skip_test("Could not find 'clang++', skipping test.\n")
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
env = Environment(tools=['clang++', 'link'])
env.Program('foo.cpp')
""")
diff --git a/test/Clang/clangxx_static_library.py b/test/Clang/clangxx_static_library.py
index 77ea58e..c768deb 100644
--- a/test/Clang/clangxx_static_library.py
+++ b/test/Clang/clangxx_static_library.py
@@ -33,7 +33,8 @@ if not test.where_is('clang'):
test.skip_test("Could not find 'clang++', skipping test.\n")
test.write('SConstruct', """\
-env = Environment(tools=['clang++', 'ar'])
+DefaultEnvironment(tools=[])
+env = Environment(tools=['mingw','clang++', 'ar'])
env.StaticLibrary('foo', 'foo.cpp')
""")
diff --git a/test/Clean/Option.py b/test/Clean/Option.py
index 6264428..f49c226 100644
--- a/test/Clean/Option.py
+++ b/test/Clean/Option.py
@@ -46,8 +46,9 @@ file.close()
""")
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
mode = ARGUMENTS.get('MODE')
diff --git a/test/Clean/basic.py b/test/Clean/basic.py
index 7c4730e..e9f0540 100644
--- a/test/Clean/basic.py
+++ b/test/Clean/basic.py
@@ -45,8 +45,9 @@ file.close()
""")
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target = 'foo1.out', source = 'foo1.in')
env.B(target = 'foo2.out', source = 'foo2.xxx')
env.B(target = 'foo2.xxx', source = 'foo2.in')
diff --git a/test/Clean/function.py b/test/Clean/function.py
index aa53a35..7ddf727 100644
--- a/test/Clean/function.py
+++ b/test/Clean/function.py
@@ -51,8 +51,9 @@ subd_foon_in = os.path.join('subd', 'foon.in')
subd_foox_in = os.path.join('subd', 'foox.in')
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B }, FOO = 'foo2')
+env = Environment(tools=[], BUILDERS = { 'B' : B }, FOO = 'foo2')
env.B(target = 'foo1.out', source = 'foo1.in')
env.B(target = 'foo2.out', source = 'foo2.xxx')
foo2_xxx = env.B(target = 'foo2.xxx', source = 'foo2.in')
diff --git a/test/Climb/explicit-parent--D.py b/test/Climb/explicit-parent--D.py
index f894e33..6f669c3 100644
--- a/test/Climb/explicit-parent--D.py
+++ b/test/Climb/explicit-parent--D.py
@@ -36,13 +36,14 @@ test = TestSCons.TestSCons()
test.subdir(['subdir'])
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
f = open(target, "wb")
for src in source:
f.write(open(str(src), "rb").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=cat)})
env.Cat('f1.out', 'f1.in')
f2 = env.Cat('f2.out', 'f2.in')
Default(f2)
diff --git a/test/Climb/filename--D.py b/test/Climb/filename--D.py
index 6fea9bc..fee72f6 100644
--- a/test/Climb/filename--D.py
+++ b/test/Climb/filename--D.py
@@ -36,6 +36,7 @@ test = TestSCons.TestSCons()
test.subdir('subdir', 'other')
test.write('main.scons', """\
+DefaultEnvironment(tools=[])
print("main.scons")
SConscript('subdir/sub.scons')
""")
diff --git a/test/Climb/filename--U.py b/test/Climb/filename--U.py
index 49ccc0a..91a83f4 100644
--- a/test/Climb/filename--U.py
+++ b/test/Climb/filename--U.py
@@ -36,6 +36,7 @@ test = TestSCons.TestSCons()
test.subdir('subdir', 'other')
test.write('main.scons', """\
+DefaultEnvironment(tools=[])
print("main.scons")
SConscript('subdir/sub.scons')
""")
diff --git a/test/Climb/filename-u.py b/test/Climb/filename-u.py
index 4485c4b..006e53e 100644
--- a/test/Climb/filename-u.py
+++ b/test/Climb/filename-u.py
@@ -36,6 +36,7 @@ test = TestSCons.TestSCons()
test.subdir('subdir', 'other')
test.write('main.scons', """\
+DefaultEnvironment(tools=[])
print("main.scons")
SConscript('subdir/sub.scons')
""")
diff --git a/test/Climb/option--D.py b/test/Climb/option--D.py
index 57c0853..42b92d8 100644
--- a/test/Climb/option--D.py
+++ b/test/Climb/option--D.py
@@ -41,9 +41,10 @@ file.close()
""")
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
import SCons.Defaults
B = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES')
-env = Environment()
+env = Environment(tools=[])
env['BUILDERS']['B'] = B
env.B(target = 'sub1/foo.out', source = 'sub1/foo.in')
Export('env')
diff --git a/test/Climb/option--U.py b/test/Climb/option--U.py
index 04ab26a..c0e6e1e 100644
--- a/test/Climb/option--U.py
+++ b/test/Climb/option--U.py
@@ -43,8 +43,9 @@ file.close()
""")
test.write('SConstruct', r"""
+DefaultEnvironment(tools=[])
import SCons.Defaults
-env = Environment()
+env = Environment(tools=[])
env['BUILDERS']['B'] = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES', multi=1)
Default(env.B(target = 'sub1/foo.out', source = 'sub1/foo.in'))
Export('env')
@@ -83,7 +84,7 @@ test.must_not_exist(test.workpath('sub2/xxx.out'))
test.unlink(['sub1', 'foo.out'])
test.write('SConscript', """\
-env = Environment()
+env = Environment(tools=[], )
assert env.GetLaunchDir() == r'%s'
"""%test.workpath('sub1'))
test.run(arguments = '-U',
diff --git a/test/Climb/option-u.py b/test/Climb/option-u.py
index eeb2ccc..21e83cf 100644
--- a/test/Climb/option-u.py
+++ b/test/Climb/option-u.py
@@ -41,13 +41,14 @@ test.subdir('sub1',
'sub4', ['sub4', 'dir'])
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
f = open(target, "wb")
for src in source:
f.write(open(str(src), "rb").read())
f.close()
-env = Environment()
+env = Environment(tools=[])
env.Append(BUILDERS = {'Cat' : Builder(action=cat)})
env.Cat(target = 'sub1/f1a.out', source = 'sub1/f1a.in')
env.Cat(target = 'sub1/f1b.out', source = 'sub1/f1b.in')
diff --git a/test/Configure/VariantDir-SConscript.py b/test/Configure/VariantDir-SConscript.py
index c82778a..deb7b8f 100644
--- a/test/Configure/VariantDir-SConscript.py
+++ b/test/Configure/VariantDir-SConscript.py
@@ -96,7 +96,7 @@ test.write(['sub', 'TestProgram.c'], """\
#include "TestProgram.h"
#include <stdio.h>
-int main() {
+int main(void) {
printf( "Hello\\n" );
}
""")
diff --git a/test/Configure/VariantDir.py b/test/Configure/VariantDir.py
index 01df276..23a4b14 100644
--- a/test/Configure/VariantDir.py
+++ b/test/Configure/VariantDir.py
@@ -63,7 +63,7 @@ env.Program( 'TestProgram', 'TestProgram.c' )
test.write('TestProgram.c', """\
#include <stdio.h>
-int main() {
+int main(void) {
printf( "Hello\\n" );
}
""")
diff --git a/test/Configure/VariantDir2.py b/test/Configure/VariantDir2.py
index 62b832f..ffe6525 100644
--- a/test/Configure/VariantDir2.py
+++ b/test/Configure/VariantDir2.py
@@ -41,7 +41,7 @@ SConscript('SConscript', variant_dir='build', src='.')
test.write('SConscript', """\
env = Environment()
config = env.Configure(conf_dir='sconf', log_file='config.log')
-config.TryRun("int main() {}", ".c")
+config.TryRun("int main(void) {}", ".c")
config.Finish()
""")
diff --git a/test/Configure/basic.py b/test/Configure/basic.py
index 4344941..4038a45 100644
--- a/test/Configure/basic.py
+++ b/test/Configure/basic.py
@@ -61,7 +61,7 @@ env.Program( 'TestProgram', 'TestProgram.c' )
test.write('TestProgram.c', """\
#include <stdio.h>
-int main() {
+int main(void) {
printf( "Hello\\n" );
}
""")
diff --git a/test/Configure/build-fail.py b/test/Configure/build-fail.py
index 74609f6..218cf18 100644
--- a/test/Configure/build-fail.py
+++ b/test/Configure/build-fail.py
@@ -58,7 +58,7 @@ def _check(context):
result = context.TryRun('''
#include "%s"
- int main() { return 0; }
+ int main(void) { return 0; }
''' % inc, '.cpp')[0]
if result:
import sys
diff --git a/test/Configure/clean.py b/test/Configure/clean.py
index bb15165..d7a5dc7 100644
--- a/test/Configure/clean.py
+++ b/test/Configure/clean.py
@@ -53,7 +53,7 @@ env.Program( 'TestProgram', 'TestProgram.c' )
test.write('TestProgram.c', """\
#include <stdio.h>
-int main() {
+int main(void) {
printf( "Hello\\n" );
}
""")
diff --git a/test/Configure/custom-tests.py b/test/Configure/custom-tests.py
index 7bb2366..6362e25 100644
--- a/test/Configure/custom-tests.py
+++ b/test/Configure/custom-tests.py
@@ -41,12 +41,12 @@ CR = test.CR # cached rebuild (up to date)
NCF = test.NCF # non-cached build failure
CF = test.CF # cached build failure
-compileOK = '#include <stdio.h>\\nint main() {printf("Hello");return 0;}'
+compileOK = '#include <stdio.h>\\nint main(void) {printf("Hello");return 0;}'
compileFAIL = "syntax error"
linkOK = compileOK
-linkFAIL = "void myFunc(); int main() { myFunc(); }"
+linkFAIL = "void myFunc(); int main(void) { myFunc(); }"
runOK = compileOK
-runFAIL = "int main() { return 1; }"
+runFAIL = "int main(void) { return 1; }"
test.write('pyAct.py', """\
from __future__ import print_function
diff --git a/test/Configure/help.py b/test/Configure/help.py
index f42088b..32f74da 100644
--- a/test/Configure/help.py
+++ b/test/Configure/help.py
@@ -53,7 +53,7 @@ env.Program( 'TestProgram', 'TestProgram.c' )
test.write('TestProgram.c', """\
#include <stdio.h>
-int main() {
+int main(void) {
printf( "Hello\\n" );
}
""")
diff --git a/test/D/Issues/2994/Common/D_changed_DFLAGS_not_rebuilding.py b/test/D/Issues/2994/Common/D_changed_DFLAGS_not_rebuilding.py
index 7e69f50..07b1366 100644
--- a/test/D/Issues/2994/Common/D_changed_DFLAGS_not_rebuilding.py
+++ b/test/D/Issues/2994/Common/D_changed_DFLAGS_not_rebuilding.py
@@ -1,6 +1,6 @@
"""
-Test to check for issue reported in tigris bug 2994
-http://scons.tigris.org/issues/show_bug.cgi?id=2994
+Test to check for issue reported in github issue 2994
+https://github.com/SCons/scons/issues/2994
"""
#
diff --git a/test/D/Support/executablesSearch.py b/test/D/Support/executablesSearch.py
index 17d9990..c572f56 100755
--- a/test/D/Support/executablesSearch.py
+++ b/test/D/Support/executablesSearch.py
@@ -51,7 +51,7 @@ def isExecutableOfToolAvailable(test, tool):
if __name__ == '__main__':
import unittest
- sys.path.append(os.path.abspath('../../../QMTest'))
+ sys.path.append(os.path.abspath('../../../testing/framework'))
import TestSCons
diff --git a/test/Decider/Environment.py b/test/Decider/Environment.py
index 7c609ee..58cd57b 100644
--- a/test/Decider/Environment.py
+++ b/test/Decider/Environment.py
@@ -34,8 +34,9 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
import os.path
-env = Environment()
+env = Environment(tools=[])
env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
def my_decider(dependency, target, prev_ni):
return os.path.exists('has-changed')
diff --git a/test/Decider/MD5-timestamp.py b/test/Decider/MD5-timestamp.py
index f8776c3..6fcdb42 100644
--- a/test/Decider/MD5-timestamp.py
+++ b/test/Decider/MD5-timestamp.py
@@ -36,7 +36,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-m = Environment()
+DefaultEnvironment(tools=[])
+m = Environment(tools=[])
m.Decider('MD5-timestamp')
m.Command('content1.out', 'content1.in', Copy('$TARGET', '$SOURCE'))
m.Command('content2.out', 'content2.in', Copy('$TARGET', '$SOURCE'))
diff --git a/test/Decider/Node.py b/test/Decider/Node.py
index cdd3e35..c1910de 100644
--- a/test/Decider/Node.py
+++ b/test/Decider/Node.py
@@ -33,6 +33,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
import os.path
file_in = File('file.in')
file_out = File('file.out')
diff --git a/test/Decider/default.py b/test/Decider/default.py
index f05e869..5d0a452 100644
--- a/test/Decider/default.py
+++ b/test/Decider/default.py
@@ -33,6 +33,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
import os.path
Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
def my_decider(dependency, target, prev_ni):
diff --git a/test/Decider/mixed.py b/test/Decider/mixed.py
index 5598468..08daa7d 100644
--- a/test/Decider/mixed.py
+++ b/test/Decider/mixed.py
@@ -34,9 +34,10 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
import os.path
-denv = Environment()
-env = Environment()
+denv = Environment(tools=[])
+env = Environment(tools=[])
n1_in = File('n1.in')
n2_in = File('n2.in')
n3_in = File('n3.in')
diff --git a/test/Decider/switch-rebuild.py b/test/Decider/switch-rebuild.py
index 45becbe..d2b288d 100644
--- a/test/Decider/switch-rebuild.py
+++ b/test/Decider/switch-rebuild.py
@@ -34,12 +34,13 @@ import TestSCons
test = TestSCons.TestSCons(match=TestSCons.match_re_dotall)
base_sconstruct_contents = """\
+DefaultEnvironment(tools=[])
Decider('%s')
def build(env, target, source):
open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read())
B = Builder(action=build)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(target='switch.out', source='switch.in')
"""
diff --git a/test/Decider/timestamp.py b/test/Decider/timestamp.py
index 8389745..e528d77 100644
--- a/test/Decider/timestamp.py
+++ b/test/Decider/timestamp.py
@@ -37,11 +37,12 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-m = Environment()
+DefaultEnvironment(tools=[])
+m = Environment(tools=[])
m.Decider('timestamp-match')
m.Command('match1.out', 'match1.in', Copy('$TARGET', '$SOURCE'))
m.Command('match2.out', 'match2.in', Copy('$TARGET', '$SOURCE'))
-n = Environment()
+n = Environment(tools=[])
n.Decider('timestamp-newer')
n.Command('newer1.out', 'newer1.in', Copy('$TARGET', '$SOURCE'))
n.Command('newer2.out', 'newer2.in', Copy('$TARGET', '$SOURCE'))
diff --git a/test/Decider/unknown.py b/test/Decider/unknown.py
index ec24eff..9f79da3 100644
--- a/test/Decider/unknown.py
+++ b/test/Decider/unknown.py
@@ -34,6 +34,7 @@ import TestSCons
test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
Decider('fiddle-dee-dee')
""")
diff --git a/test/Depends/Depends.py b/test/Depends/Depends.py
index 6804fd0..054b9a1 100644
--- a/test/Depends/Depends.py
+++ b/test/Depends/Depends.py
@@ -51,9 +51,10 @@ SUBDIR_foo_dep = os.path.join('$SUBDIR', 'foo.dep')
SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out')
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/foo.dep')
Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/bar.dep')
-env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir')
+env = Environment(tools=[], BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir')
env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%(SUBDIR_foo_dep)s')
env.Depends(target = r'%(SUBDIR_f3_out)s', dependency = 'subdir/bar.dep')
env.Foo(target = 'f1.out', source = 'f1.in')
diff --git a/test/Depends/no-Builder.py b/test/Depends/no-Builder.py
index 48ab724..7e04bc9 100644
--- a/test/Depends/no-Builder.py
+++ b/test/Depends/no-Builder.py
@@ -34,13 +34,14 @@ test = TestSCons.TestSCons()
#
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
file1 = File('file1')
file2 = File('file2')
env.Depends(file1, [[file2, 'file3']])
# Verify that a "hidden" file created by another action causes the
# action to run when an explicit Dependency is specified.
-# See http://scons.tigris.org/issues/show_bug.cgi?id=2647
+# https://github.com/SCons/scons/issues/2647
env.Depends('hidden', 'file4.out')
env.Command('file4.out', 'file4.in',
[Copy('$TARGET', '$SOURCE'), Touch('hidden')])
diff --git a/test/Dir/Dir.py b/test/Dir/Dir.py
index 2e8204c..e726b94 100644
--- a/test/Dir/Dir.py
+++ b/test/Dir/Dir.py
@@ -35,7 +35,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(FOO = 'fff', BAR = 'bbb')
+DefaultEnvironment(tools=[])
+env = Environment(tools=[], FOO = 'fff', BAR = 'bbb')
print(Dir('ddd'))
print(Dir('$FOO'))
print(Dir('${BAR}_$BAR'))
@@ -58,12 +59,13 @@ scons: `.' is up to date.
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
import os
def my_mkdir(target=None, source=None, env=None):
os.mkdir(str(target[0]))
MDBuilder = Builder(action=my_mkdir, target_factory=Dir)
-env = Environment()
+env = Environment(tools=[])
env.Append(BUILDERS = {'MD':MDBuilder})
env.MD(target='sub1', source=['SConstruct'])
env.MD(target='sub2', source=['SConstruct'], OVERRIDE='foo')
diff --git a/test/Dir/PyPackageDir/image/SConstruct b/test/Dir/PyPackageDir/image/SConstruct
index 90d2a80..7e841ac 100644
--- a/test/Dir/PyPackageDir/image/SConstruct
+++ b/test/Dir/PyPackageDir/image/SConstruct
@@ -13,17 +13,19 @@ def TestPyPackageDir(env, modname):
relpath = relpath.replace(os.sep, '/')
print(relpath)
+DefaultEnvironment(tools=[])
+
print("Test identification of directory for a given python package")
-env = Environment()
+env = Environment(tools=[])
TestPyPackageDir(env, 'testmod1')
TestPyPackageDir(env, 'testmod2')
TestPyPackageDir(env, 'submod1.testmod3')
TestPyPackageDir(env, 'submod1.submod2.testmod4')
print("Test parameter substitution")
-env = Environment(FOO = 'submod1.submod2.testmod4')
+env = Environment(tools=[], FOO = 'submod1.submod2.testmod4')
TestPyPackageDir(env, '${FOO}')
-env = Environment(FOO = 'submod1.submod2', BAR = 'testmod4')
+env = Environment(tools=[], FOO = 'submod1.submod2', BAR = 'testmod4')
TestPyPackageDir(env, '${FOO}.${BAR}')
sys.path = oldsyspath
diff --git a/test/Dir/mixed-targets.py b/test/Dir/mixed-targets.py
index 9702e40..3389746 100644
--- a/test/Dir/mixed-targets.py
+++ b/test/Dir/mixed-targets.py
@@ -46,12 +46,13 @@ def copier(target, source, env):
shutil.copytree(str(source[0]), 'build')
return 0
+DefaultEnvironment(tools=[])
Copier = Builder(action = copier,
target_scanner = SCons.Defaults.DirEntryScanner,
target_factory = Entry,
source_factory = Entry)
-env = Environment(BUILDERS = {'Copier': Copier})
+env = Environment(tools=[], BUILDERS = {'Copier': Copier})
env.Copier(['build/dir', 'build/file1'], ['src'])
""")
diff --git a/test/Dir/source.py b/test/Dir/source.py
index c272c8f..5fe917d 100644
--- a/test/Dir/source.py
+++ b/test/Dir/source.py
@@ -42,6 +42,7 @@ test.subdir('tstamp', [ 'tstamp', 'subdir' ],
'cmd-content', [ 'cmd-content', 'subdir' ])
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def writeTarget(target, source, env):
f=open(str(target[0]), 'w')
f.write("stuff\\n")
@@ -52,7 +53,7 @@ test_bld_dir = Builder(action=writeTarget,
source_factory=Dir,
source_scanner=DirScanner)
test_bld_file = Builder(action=writeTarget)
-env = Environment()
+env = Environment(tools=[])
env['BUILDERS']['TestDir'] = test_bld_dir
env['BUILDERS']['TestFile'] = test_bld_file
diff --git a/test/Docbook/basedir/htmlchunked/image/manual.xml b/test/Docbook/basedir/htmlchunked/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/basedir/htmlchunked/image/manual.xml
+++ b/test/Docbook/basedir/htmlchunked/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Docbook/basedir/htmlhelp/image/manual.xml b/test/Docbook/basedir/htmlhelp/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/basedir/htmlhelp/image/manual.xml
+++ b/test/Docbook/basedir/htmlhelp/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Docbook/basic/epub/image/manual.xml b/test/Docbook/basic/epub/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/basic/epub/image/manual.xml
+++ b/test/Docbook/basic/epub/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Docbook/basic/html/image/manual.xml b/test/Docbook/basic/html/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/basic/html/image/manual.xml
+++ b/test/Docbook/basic/html/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Docbook/basic/htmlchunked/image/manual.xml b/test/Docbook/basic/htmlchunked/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/basic/htmlchunked/image/manual.xml
+++ b/test/Docbook/basic/htmlchunked/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Docbook/basic/htmlhelp/image/manual.xml b/test/Docbook/basic/htmlhelp/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/basic/htmlhelp/image/manual.xml
+++ b/test/Docbook/basic/htmlhelp/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Docbook/basic/xinclude/xinclude.py b/test/Docbook/basic/xinclude/xinclude.py
index 302c777..9b22c13 100644
--- a/test/Docbook/basic/xinclude/xinclude.py
+++ b/test/Docbook/basic/xinclude/xinclude.py
@@ -44,7 +44,7 @@ test.dir_fixture('image')
# Normal invocation
test.run()
test.must_exist(test.workpath('manual_xi.xml'))
-test.must_contain(test.workpath('manual_xi.xml'),'<para>This is an included text.')
+test.must_contain(test.workpath('manual_xi.xml'),'<para>This is an included text.', mode='r')
# Cleanup
diff --git a/test/Docbook/dependencies/xinclude/xinclude.py b/test/Docbook/dependencies/xinclude/xinclude.py
index 115163c..c3d9e25 100644
--- a/test/Docbook/dependencies/xinclude/xinclude.py
+++ b/test/Docbook/dependencies/xinclude/xinclude.py
@@ -44,7 +44,7 @@ test.dir_fixture('image')
# Normal invocation
test.run()
test.must_exist(test.workpath('manual_xi.xml'))
-test.must_contain(test.workpath('manual_xi.xml'),'<para>This is an included text.')
+test.must_contain(test.workpath('manual_xi.xml'),'<para>This is an included text.', mode='r')
# Change included file
test.write('include.txt', 'This is another text.')
diff --git a/test/Docbook/rootname/htmlchunked/image/manual.xml b/test/Docbook/rootname/htmlchunked/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/rootname/htmlchunked/image/manual.xml
+++ b/test/Docbook/rootname/htmlchunked/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Docbook/rootname/htmlhelp/image/manual.xml b/test/Docbook/rootname/htmlhelp/image/manual.xml
index ca12e0e..067c76e 100644
--- a/test/Docbook/rootname/htmlhelp/image/manual.xml
+++ b/test/Docbook/rootname/htmlhelp/image/manual.xml
@@ -72,7 +72,7 @@
<listitem>
<para>the SCons Tools Wiki page at <ulink
- url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+ url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/test/Execute.py b/test/Execute.py
index edd746e..c40d0d0 100644
--- a/test/Execute.py
+++ b/test/Execute.py
@@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Test the Execute() function for executing actions directly.
"""
-
+import sys
import TestSCons
_python_ = TestSCons._python_
@@ -82,11 +82,12 @@ test.write('k.in', "k.in\n")
test.write('l.in', "l.in\n")
test.write('m.in', "m.in\n")
-import sys
if sys.platform == 'win32' and sys.version_info[0] == 2:
+ # note that nonexistent.in will have a \ on windows with python < 2.7.15
+ # and a / on >= 2.7.15 (The third line below)
expect = r"""scons: \*\*\* Error 1
scons: \*\*\* Error 2
-scons: \*\*\* nonexistent.in/\*\.\*: (The system cannot find the path specified|Das System kann den angegebenen Pfad nicht finden)"""
+scons: \*\*\* nonexistent.in(/|\\)\*\.\*: (The system cannot find the path specified|Das System kann den angegebenen Pfad nicht finden)"""
elif sys.platform == 'win32' and sys.version_info[0] == 3:
expect = r"""scons: \*\*\* Error 1
scons: \*\*\* Error 2
diff --git a/test/ExecuteInvalidateCache.py b/test/ExecuteInvalidateCache.py
index acc7701..f6ed391 100644
--- a/test/ExecuteInvalidateCache.py
+++ b/test/ExecuteInvalidateCache.py
@@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Test the Execute() functions clears the memoized values of affected target Nodes
when used with Delete(). Derived from
-http://scons.tigris.org/issues/show_bug.cgi?id=1307
+https://github.com/SCons/scons/issues/1307
"""
import TestSCons
diff --git a/test/FindSourceFiles.py b/test/FindSourceFiles.py
index 88b9d7e..62b906c 100644
--- a/test/FindSourceFiles.py
+++ b/test/FindSourceFiles.py
@@ -63,7 +63,7 @@ foo_c = env.Substfile('foo.c.in', SUBST_DICT = {'__A__' : '0' })
foo = env.Program(foo_c)
""")
-test.write('src/foo.c.in', """ int main() { return __A__;}
+test.write('src/foo.c.in', """ int main(void) { return __A__;}
""")
test.run(arguments = 'package')
diff --git a/test/Fortran/FORTRANMODDIR.py b/test/Fortran/FORTRANMODDIR.py
index 723efaf..61dcc45 100644
--- a/test/Fortran/FORTRANMODDIR.py
+++ b/test/Fortran/FORTRANMODDIR.py
@@ -24,6 +24,16 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+"""
+Verify the following things:
+* _FORTRANMODFLAG is correctly constructed from FORTRANMODDIRPREFIX and
+ FORTRANMODDIR.
+* The dependency scanner does not expect a module file to be created
+ from a "module procedure" statement.
+* The dependency scanner expects the module files to be created in the correct
+ module directory (this is verified by the test.up_to_date()).
+"""
+
import TestSCons
_python_ = TestSCons._python_
@@ -31,61 +41,59 @@ _exe = TestSCons._exe
test = TestSCons.TestSCons()
-
-
test.write('myfortran.py', r"""
import os.path
import re
import sys
+# case insensitive matching, because Fortran is case insensitive
mod_regex = "(?im)^\\s*MODULE\\s+(?!PROCEDURE)(\\w+)"
contents = open(sys.argv[2]).read()
modules = re.findall(mod_regex, contents)
-modules = [os.path.join(sys.argv[1], m.lower()+'.mod') for m in modules]
+(prefix, moddir) = sys.argv[1].split('=')
+if prefix != 'moduledir':
+ sys.exit(1)
+modules = [os.path.join(moddir, m.lower()+'.mod') for m in modules]
for t in sys.argv[3:] + modules:
open(t, 'wb').write(('myfortran.py wrote %s\n' % os.path.split(t)[1]).encode())
-sys.exit(0)
""")
test.write('SConstruct', """
-env = Environment(FORTRANCOM = r'%(_python_)s myfortran.py $FORTRANMODDIR $SOURCE $TARGET',
- FORTRANMODDIR = 'modules')
-env.Object(target = 'test1.obj', source = 'test1.f')
-env.Object(target = 'sub2/test2.obj', source = 'test1.f',
+env = Environment(F90COM = r'%(_python_)s myfortran.py $_FORTRANMODFLAG $SOURCE $TARGET',
+ FORTRANMODDIRPREFIX='moduledir=', FORTRANMODDIR='modules')
+env.Object(target = 'test1.obj', source = 'test1.f90')
+env.Object(target = 'sub2/test2.obj', source = 'test1.f90',
FORTRANMODDIR='${TARGET.dir}')
-env.Object(target = 'sub3/test3.obj', source = 'test1.f',
- FORTRANCOM = r'%(_python_)s myfortran.py $_FORTRANMODFLAG $SOURCE $TARGET',
+env.Object(target = 'sub3/test3.obj', source = 'test1.f90',
+ F90COM = r'%(_python_)s myfortran.py moduledir=$FORTRANMODDIR $SOURCE $TARGET',
FORTRANMODDIR='${TARGET.dir}')
""" % locals())
-test.write('test1.f', """\
- PROGRAM TEST
- USE MOD_FOO
- USE MOD_BAR
- PRINT *,'TEST.f'
- CALL P
- STOP
- END
- MODULE MOD_FOO
- IMPLICIT NONE
- CONTAINS
- SUBROUTINE P
- PRINT *,'mod_foo'
- END SUBROUTINE P
- END MODULE MOD_FOO
- MODULE PROCEDURE MOD_BAR
- IMPLICIT NONE
- CONTAINS
- SUBROUTINE P
- PRINT *,'mod_bar'
- END SUBROUTINE P
- END MODULE MOD_BAR
+test.write('test1.f90', """\
+module mod_foo
+ implicit none
+ interface q
+ module procedure p
+ end interface q
+ contains
+ subroutine p
+ implicit none
+ print *, 'mod_foo::p'
+ end subroutine p
+end module mod_foo
+program test
+ use mod_foo
+ implicit none
+ print *, 'test1.f90'
+ call p
+ call q
+end
""")
test.run(arguments = '.', stderr = None)
test.must_match('test1.obj', "myfortran.py wrote test1.obj\n")
test.must_match(['modules', 'mod_foo.mod'], "myfortran.py wrote mod_foo.mod\n")
-test.must_not_exist(['modules', 'mod_bar.mod'])
+test.must_not_exist(['modules', 'p.mod'])
test.must_match(['sub2', 'test2.obj'], "myfortran.py wrote test2.obj\n")
test.must_match(['sub2', 'mod_foo.mod'], "myfortran.py wrote mod_foo.mod\n")
@@ -95,8 +103,6 @@ test.must_match(['sub3', 'mod_foo.mod'], "myfortran.py wrote mod_foo.mod\n")
test.up_to_date(arguments = '.')
-
-
test.pass_test()
# Local Variables:
diff --git a/test/Fortran/USE-MODULE-CASEINSENS.py b/test/Fortran/USE-MODULE-CASEINSENS.py
index 44c03fe..4dd115b 100644
--- a/test/Fortran/USE-MODULE-CASEINSENS.py
+++ b/test/Fortran/USE-MODULE-CASEINSENS.py
@@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
# This test tests whether a file that defines a module "a" and
# then uses it with a different case ("A") works. Pre-2.0, this
# gave a spurious dependency cycle error.
-# See http://scons.tigris.org/issues/show_bug.cgi?id=2574
+# See https://github.com/SCons/scons/issues/2574
import TestSCons
diff --git a/test/Fortran/gfortran.py b/test/Fortran/gfortran.py
new file mode 100644
index 0000000..c3dec97
--- /dev/null
+++ b/test/Fortran/gfortran.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that the gfortran tool compiles a .f90 file to an executable,
+one time with and one time without placing module files in a subdirectory
+specified by FORTRANMODDIR.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+_exe = TestSCons._exe
+
+gfortran = test.detect_tool('gfortran')
+
+if not gfortran:
+ test.skip_test("Could not find gfortran tool, skipping test.\n")
+
+test.write('SConstruct', """
+env = Environment(tools=['gfortran','link'])
+env.Program('test1', 'test1.f90')
+""")
+
+test.write('test1.f90', """\
+module test1mod
+ implicit none
+ contains
+ subroutine hello
+ implicit none
+ print *, "hello"
+ end subroutine hello
+end module test1mod
+program main
+ use test1mod
+ implicit none
+ call hello()
+end program main
+""")
+
+test.run(arguments = '.')
+
+test.must_exist('test1' + _exe)
+test.must_exist('test1mod.mod')
+
+test.up_to_date(arguments = '.')
+
+
+test.write('SConstruct', """
+env = Environment(tools=['gfortran','link'], F90PATH='modules', FORTRANMODDIR='modules')
+env.Program('test2', 'test2.f90')
+""")
+
+test.write('test2.f90', """\
+module test2mod
+ implicit none
+ contains
+ subroutine hello
+ implicit none
+ print *, "hello"
+ end subroutine hello
+end module test2mod
+program main
+ use test2mod
+ implicit none
+ call hello()
+end program main
+""")
+
+test.run(arguments = '.')
+
+test.must_exist('test2' + _exe)
+test.must_exist(['modules', 'test2mod.mod'])
+
+test.up_to_date(arguments = '.')
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/GetBuildFailures/option-k.py b/test/GetBuildFailures/option-k.py
index 12ae07b..28e80c8 100644
--- a/test/GetBuildFailures/option-k.py
+++ b/test/GetBuildFailures/option-k.py
@@ -57,6 +57,7 @@ test.write('mypass.py', contents)
test.write('myfail.py', contents)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
Command('f3', 'f3.in', r'@%(_python_)s mypass.py - f3 $TARGET $SOURCE')
Command('f4', 'f4.in', r'@%(_python_)s myfail.py f3 f4 $TARGET $SOURCE')
Command('f5', 'f5.in', r'@%(_python_)s myfail.py f4 f5 $TARGET $SOURCE')
diff --git a/test/GetBuildFailures/parallel.py b/test/GetBuildFailures/parallel.py
index f9503e0..ee8847f 100644
--- a/test/GetBuildFailures/parallel.py
+++ b/test/GetBuildFailures/parallel.py
@@ -73,6 +73,7 @@ test.write('mypass.py', contents)
test.write('myfail.py', contents)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
Command('f3', 'f3.in', r'@%(_python_)s mypass.py - f3 $TARGET $SOURCE')
Command('f4', 'f4.in', r'@%(_python_)s myfail.py f3 f4 $TARGET $SOURCE')
Command('f5', 'f5.in', r'@%(_python_)s myfail.py f4 f5 $TARGET $SOURCE')
diff --git a/test/GetBuildFailures/serial.py b/test/GetBuildFailures/serial.py
index 55a990f..144d8bc 100644
--- a/test/GetBuildFailures/serial.py
+++ b/test/GetBuildFailures/serial.py
@@ -60,6 +60,7 @@ test.write('mypass.py', contents)
test.write('myfail.py', contents)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
Command('f03', 'f03.in', r'@%(_python_)s mypass.py - f03 $TARGET $SOURCE')
Command('f04', 'f04.in', r'@%(_python_)s myfail.py f03 f04 $TARGET $SOURCE')
Command('f05', 'f05.in', r'@%(_python_)s myfail.py f04 f05 $TARGET $SOURCE')
diff --git a/test/GetOption/help.py b/test/GetOption/help.py
index 4f15fe6..f83dc54 100644
--- a/test/GetOption/help.py
+++ b/test/GetOption/help.py
@@ -33,6 +33,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
if GetOption('help'):
print("GetOption('help') set")
else:
diff --git a/test/Glob/Repository.py b/test/Glob/Repository.py
index 22a7f88..3308e62 100644
--- a/test/Glob/Repository.py
+++ b/test/Glob/Repository.py
@@ -47,6 +47,7 @@ work_src_yyy = test.workpath('work', 'src', 'yyy')
opts = "-Y " + test.workpath('repository')
test.write(['repository', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
f = open(target, "wb")
@@ -60,7 +61,7 @@ File('../repository/mmm.in')
m = Glob('m*.in')
assert str(m[0]) == 'mmm.in'
-env = Environment(BUILDERS={'Build':Builder(action=cat)})
+env = Environment(tools=[], BUILDERS={'Build':Builder(action=cat)})
env.Build('aaa.out', Glob('a*.in'))
env.Build('bbb.out', Glob('b*.in'))
env.Build('ccc.out', Glob('c*.in'))
diff --git a/test/Glob/VariantDir.py b/test/Glob/VariantDir.py
index c9c1d07..3beb9ab 100644
--- a/test/Glob/VariantDir.py
+++ b/test/Glob/VariantDir.py
@@ -37,6 +37,7 @@ test.subdir('src')
test.subdir('src/sub1')
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
VariantDir('var1', 'src')
VariantDir('var2', 'src')
@@ -48,7 +49,7 @@ SConscript('src/sub1/SConscript', src_dir = 'src', variant_dir = 'var3', duplica
""")
test.write(['src', 'SConscript'], """\
-env = Environment()
+env = Environment(tools=[])
def concatenate(target, source, env):
fp = open(str(target[0]), 'wb')
@@ -63,7 +64,7 @@ env.Concatenate('fex.out', sorted(Glob('f*.in', exclude = 'f1.in'), key=lambda t
""")
test.write(['src', 'sub1', 'SConscript'], """\
-env = Environment()
+env = Environment(tools=[])
def concatenate(target, source, env):
fp = open(str(target[0]), 'wb')
diff --git a/test/Glob/basic.py b/test/Glob/basic.py
index 9afbbc6..ad998c3 100644
--- a/test/Glob/basic.py
+++ b/test/Glob/basic.py
@@ -33,7 +33,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
def concatenate(target, source, env):
fp = open(str(target[0]), 'wb')
diff --git a/test/Glob/exclude.py b/test/Glob/exclude.py
index fe93b82..bc3e774 100644
--- a/test/Glob/exclude.py
+++ b/test/Glob/exclude.py
@@ -36,7 +36,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
def concatenate(target, source, env):
fp = open(str(target[0]), 'wb')
diff --git a/test/Glob/source.py b/test/Glob/source.py
index f1ea566..3d40d05 100644
--- a/test/Glob/source.py
+++ b/test/Glob/source.py
@@ -37,7 +37,8 @@ test = TestSCons.TestSCons()
test.subdir('src', 'var1', 'var2')
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
def concatenate(target, source, env):
fp = open(str(target[0]), 'wb')
diff --git a/test/Glob/strings.py b/test/Glob/strings.py
index 3e47d10..0780ace 100644
--- a/test/Glob/strings.py
+++ b/test/Glob/strings.py
@@ -37,6 +37,7 @@ test = TestSCons.TestSCons()
test.subdir('src')
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
VariantDir('var1', 'src')
VariantDir('var2', 'src')
@@ -45,7 +46,7 @@ SConscript('var2/SConscript')
""")
test.write(['src', 'SConscript'], """\
-env = Environment()
+env = Environment(tools=[])
def concatenate(target, source, env):
fp = open(str(target[0]), 'wb')
diff --git a/test/Glob/subdir.py b/test/Glob/subdir.py
index 6fc00f6..1227788 100644
--- a/test/Glob/subdir.py
+++ b/test/Glob/subdir.py
@@ -36,7 +36,8 @@ test = TestSCons.TestSCons()
test.subdir('subdir')
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
def concatenate(target, source, env):
fp = open(str(target[0]), 'wb')
diff --git a/test/Glob/subst.py b/test/Glob/subst.py
index e21da81..6a145f1 100644
--- a/test/Glob/subst.py
+++ b/test/Glob/subst.py
@@ -34,7 +34,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-env = Environment(PATTERN = 'f*.in')
+DefaultEnvironment(tools=[])
+env = Environment(tools=[], PATTERN = 'f*.in')
def copy(target, source, env):
fp = open(str(target[0]), 'wb')
diff --git a/test/Install/Clone.py b/test/Install/Clone.py
index da66157..14e0688 100644
--- a/test/Install/Clone.py
+++ b/test/Install/Clone.py
@@ -34,6 +34,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env1 = Environment(DESTDIR='sub1', tools=[])
# Call env1.Install() but not env1.InstallAs() *before* we clone it.
diff --git a/test/Install/INSTALLSTR.py b/test/Install/INSTALLSTR.py
index 0cc5fce..145b81d 100644
--- a/test/Install/INSTALLSTR.py
+++ b/test/Install/INSTALLSTR.py
@@ -37,7 +37,8 @@ test = TestSCons.TestSCons()
test.subdir('install')
test.write('SConstruct', """\
-env = Environment(INSTALLSTR = 'INSTALL $SOURCE => $TARGET!')
+DefaultEnvironment(tools=[])
+env = Environment(tools=[], INSTALLSTR = 'INSTALL $SOURCE => $TARGET!')
env.Install('install', 'file')
""")
diff --git a/test/Install/Install.py b/test/Install/Install.py
index 72a7545..da97d2a 100644
--- a/test/Install/Install.py
+++ b/test/Install/Install.py
@@ -48,6 +48,7 @@ f6_sep = f6_txt.replace(os.sep, '/')
_SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out')
test.write(['work', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
f = open(target, "w")
@@ -60,7 +61,7 @@ def my_install(dest, source, env):
shutil.copy2(source, dest)
open('my_install.out', 'a').write(dest)
-env1 = Environment()
+env1 = Environment(tools=[])
env1.Append(BUILDERS={'Cat':Builder(action=cat)})
env3 = env1.Clone(INSTALL = my_install)
diff --git a/test/Install/InstallAs.py b/test/Install/InstallAs.py
index 537ea3a..47ee9f6 100644
--- a/test/Install/InstallAs.py
+++ b/test/Install/InstallAs.py
@@ -47,7 +47,8 @@ _SUBDIR_file3_in = os.path.join('$SUBDIR', 'file3.in')
#
test.write('SConstruct', r"""
-env = Environment(INSTALLDIR=r'%(install)s', SUBDIR='subdir')
+DefaultEnvironment(tools=[])
+env = Environment(tools=[], INSTALLDIR=r'%(install)s', SUBDIR='subdir')
InstallAs(r'%(install_file1_out)s', 'file1.in')
env.InstallAs([r'%(_INSTALLDIR_file2_out)s', r'%(install_file3_out)s'],
['file2.in', r'%(_SUBDIR_file3_in)s'])
diff --git a/test/Install/dir-exists.py b/test/Install/dir-exists.py
index f981a35..9882d22 100644
--- a/test/Install/dir-exists.py
+++ b/test/Install/dir-exists.py
@@ -35,6 +35,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
Execute(Mkdir('a'))
Execute(Mkdir('b'))
f=Command('a/f', None, 'echo hi > $TARGET')
diff --git a/test/Install/directories.py b/test/Install/directories.py
index 74a7ac5..3ebc713 100644
--- a/test/Install/directories.py
+++ b/test/Install/directories.py
@@ -46,10 +46,12 @@ test.subdir('outside',
['work', 'dir4', 'sub'])
test.write(['work', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
+
Install('../outside', 'dir1')
InstallAs('../outside/d2', 'dir2')
-env = Environment()
env.Install('../outside', 'dir3')
env.InstallAs('../outside/d4', 'dir4')
""")
diff --git a/test/Install/multi-dir/src/SConstruct b/test/Install/multi-dir/src/SConstruct
index e10ec8d..05b46a9 100644
--- a/test/Install/multi-dir/src/SConstruct
+++ b/test/Install/multi-dir/src/SConstruct
@@ -2,7 +2,8 @@
# outside the source tree can cause SCons to fail to create the dest
# dir.
import os, os.path, shutil
-env=Environment()
+DefaultEnvironment(tools=[])
+env=Environment(tools=[])
dst='../build'
env.Install(os.path.join(dst,'__foo/bar/baz'), 'a')
env.Install(os.path.join(dst,'__foo/bar/baz/a/b'), 'x/y')
diff --git a/test/Install/multi.py b/test/Install/multi.py
index a7a6eb8..1716d17 100644
--- a/test/Install/multi.py
+++ b/test/Install/multi.py
@@ -34,7 +34,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
env.Install('install', 'file1')
env.Install('install', 'file1')
""")
diff --git a/test/Install/no-top-relative.py b/test/Install/no-top-relative.py
index 3eb24f7..31c7130 100644
--- a/test/Install/no-top-relative.py
+++ b/test/Install/no-top-relative.py
@@ -39,7 +39,8 @@ test = TestSCons.TestSCons()
test.subdir(['test'])
test.write(['SConstruct'], """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
i = env.Install("#/install", "#/test/#testfile.txt#");
env.Default(i);
""")
diff --git a/test/Install/non-ascii-name.py b/test/Install/non-ascii-name.py
index 186af09..462040d 100644
--- a/test/Install/non-ascii-name.py
+++ b/test/Install/non-ascii-name.py
@@ -39,6 +39,7 @@ test.write('中文.txt',
"test stuff here in file 中文.txt.\n")
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
InstallAs("b", Glob("*.txt"))
""")
test.run(arguments='.')
diff --git a/test/Install/option--install-sandbox.py b/test/Install/option--install-sandbox.py
index 020cd3a..45366c1 100644
--- a/test/Install/option--install-sandbox.py
+++ b/test/Install/option--install-sandbox.py
@@ -49,7 +49,8 @@ file1_out = target+os.path.join( target,
#
test.write('SConstruct', r"""
-env = Environment(SUBDIR='subdir')
+DefaultEnvironment(tools=[])
+env = Environment(tools=[], SUBDIR='subdir')
f1 = env.Install(r'%(destdir)s', 'file1.out')
f2 = env.InstallAs(['file2.out', r'%(_SUBDIR_file3_out)s'],
['file2.in', r'%(_SUBDIR_file3_in)s'])
diff --git a/test/Install/tool.py b/test/Install/tool.py
index 1e49584..ba92d0a 100644
--- a/test/Install/tool.py
+++ b/test/Install/tool.py
@@ -36,6 +36,7 @@ test = TestSCons.TestSCons()
test.subdir('iii')
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(tools = [])
env.Install('iii', 'foo.in')
env.InstallAs('foo.out', 'foo.in')
diff --git a/test/Install/wrap-by-attribute.py b/test/Install/wrap-by-attribute.py
index 02513af..6989fa8 100644
--- a/test/Install/wrap-by-attribute.py
+++ b/test/Install/wrap-by-attribute.py
@@ -42,6 +42,7 @@ test = TestSCons.TestSCons()
test.subdir('outside', 'sub')
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
import os.path
def cat(env, source, target):
@@ -51,7 +52,7 @@ def cat(env, source, target):
f.write(open(str(src), "rb").read())
f.close()
-env = Environment(DESTDIR='dest')
+env = Environment(tools=[], DESTDIR='dest')
env.Append(BUILDERS={'Cat':Builder(action=cat)})
env.SconsInternalInstallFunc = env.Install
diff --git a/test/Interactive/added-include.py b/test/Interactive/added-include.py
index 86a473d..e65cb14 100644
--- a/test/Interactive/added-include.py
+++ b/test/Interactive/added-include.py
@@ -41,7 +41,7 @@ test.write('foo.h.in', """
test.write('foo.c', """
#include <stdio.h>
-int main()
+int main(void)
{
printf("foo.c\\n");
return 0;
@@ -81,7 +81,7 @@ test.write('foo.c', """
#include <stdio.h>
-int main()
+int main(void)
{
printf("%s\\n", FOO_STRING);
return 0;
diff --git a/test/Interactive/implicit-VariantDir.py b/test/Interactive/implicit-VariantDir.py
index 5ef4583..fc52080 100644
--- a/test/Interactive/implicit-VariantDir.py
+++ b/test/Interactive/implicit-VariantDir.py
@@ -74,7 +74,7 @@ test.write(['src', 'foo.c'], """
#define FOO_PRINT_STRING "Hello from foo.c"
-int main()
+int main(void)
{
printf(FOO_PRINT_STRING "\\n");
return 0;
@@ -115,7 +115,7 @@ test.write(['src', 'foo.c'], """
#include "foo.h"
#include <stdio.h>
-int main()
+int main(void)
{
printf(FOO_PRINT_STRING "\\n");
return 0;
diff --git a/test/Java/JAR.py b/test/Java/JAR.py
index da2e72e..faf01a3 100644
--- a/test/Java/JAR.py
+++ b/test/Java/JAR.py
@@ -52,6 +52,7 @@ sys.exit(0)
""")
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(tools = ['jar'],
JAR = r'%(_python_)s myjar.py')
env.Jar(target = 'test1.jar', source = 'test1.class')
@@ -70,6 +71,7 @@ test.must_match('test1.jar', "test1.class\nline 3\n", mode='r')
if os.path.normcase('.class') == os.path.normcase('.CLASS'):
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(tools = ['jar'],
JAR = r'%(_python_)s myjar.py')
env.Jar(target = 'test2.jar', source = 'test2.CLASS')
@@ -95,6 +97,7 @@ sys.exit(0)
""")
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(tools = ['jar'],
JAR = r'%(_python_)s myjar2.py',
JARFLAGS='cvf')
@@ -126,6 +129,7 @@ where_jar = test.java_where_jar()
test.file_fixture('wrapper_with_args.py')
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
foo = Environment(tools = ['javac', 'jar'],
JAVAC = r'%(where_javac)s',
JAR = r'%(where_jar)s')
@@ -249,6 +253,8 @@ test.subdir('testdir2',
# simple SConstruct which passes the 3 .java as source
# and extracts the jars back to classes
test.write(['testdir2', 'SConstruct'], """
+DefaultEnvironment(tools=[])
+
foo = Environment()
foo.Jar(target = 'foobar', source = [
'com/javasource/JavaFile1.java',
@@ -337,6 +343,7 @@ test.must_exist(['testdir2', 'barTest', 'com', 'javasource', 'JavaFile3.class'])
# make some directories to test in
test.subdir('listOfLists',
+ ['manifest_dir'],
['listOfLists', 'src'],
['listOfLists', 'src', 'com'],
['listOfLists', 'src', 'com', 'javasource'],
@@ -344,16 +351,18 @@ test.subdir('listOfLists',
# test varient dir and lists of lists
test.write(['listOfLists', 'SConstruct'], """
+DefaultEnvironment(tools=[])
+
foo = Environment()
foo.VariantDir('build', 'src', duplicate=0)
+foo.VariantDir('test', '../manifest_dir', duplicate=0)
sourceFiles = ["src/com/javasource/JavaFile1.java", "src/com/javasource/JavaFile2.java", "src/com/javasource/JavaFile3.java",]
list_of_class_files = foo.Java('build', source=sourceFiles)
resources = ['build/com/resource/resource1.txt', 'build/com/resource/resource2.txt']
for resource in resources:
foo.Command(resource, list_of_class_files, Copy(resource, resource.replace('build','src')))
-foo.Command('build/MANIFEST.mf', list_of_class_files, Copy('build/MANIFEST.mf', 'MANIFEST.mf'))
contents = [list_of_class_files, resources]
-foo.Jar(target = 'lists', source = contents + ['build/MANIFEST.mf'], JARCHDIR='build')
+foo.Jar(target = 'lists', source = contents + ['test/MANIFEST.mf'], JARCHDIR='build')
foo.Command("listsTest", [], Mkdir("listsTest") )
foo.Command('listsTest/src/com/javasource/JavaFile3.java', 'lists.jar', foo['JAR'] + ' xvf ../lists.jar', chdir='listsTest')
""")
@@ -394,7 +403,7 @@ public class JavaFile3
}
""")
-test.write(['listOfLists', 'MANIFEST.mf'],
+test.write(['manifest_dir','MANIFEST.mf'],
"""Manifest-Version: 1.0
MyManifestTest: Test
""")
@@ -434,6 +443,8 @@ test.subdir('testdir3',
# Create the jars then extract them back to check contents
test.write(['testdir3', 'SConstruct'], """
+DefaultEnvironment(tools=[])
+
foo = Environment()
bar = foo.Clone()
foo.Java(target = 'classes', source = 'com/sub/foo')
diff --git a/test/Java/Java-1.4.py b/test/Java/Java-1.4.py
index 4076783..8bbefaf 100644
--- a/test/Java/Java-1.4.py
+++ b/test/Java/Java-1.4.py
@@ -267,7 +267,7 @@ class Foo { }
""")
# Test private inner class instantiation, courtesy Tilo Prutz:
-# http://scons.tigris.org/issues/show_bug.cgi?id=1594
+# https://github.com/SCons/scons/issues/1594
test.write(['src6', 'TestSCons.java'], """\
class test
{
diff --git a/test/Java/Java-1.5.py b/test/Java/Java-1.5.py
index 6659a16..58513e2 100644
--- a/test/Java/Java-1.5.py
+++ b/test/Java/Java-1.5.py
@@ -267,7 +267,7 @@ class Foo { }
""")
# Test private inner class instantiation, courtesy Tilo Prutz:
-# http://scons.tigris.org/issues/show_bug.cgi?id=1594
+# https://github.com/SCons/scons/issues/1594
test.write(['src6', 'TestSCons.java'], """\
class test
{
diff --git a/test/Java/Java-1.6.py b/test/Java/Java-1.6.py
index be46919..04a9155 100644
--- a/test/Java/Java-1.6.py
+++ b/test/Java/Java-1.6.py
@@ -267,7 +267,7 @@ class Foo { }
""")
# Test private inner class instantiation, courtesy Tilo Prutz:
-# http://scons.tigris.org/issues/show_bug.cgi?id=1594
+# https://github.com/SCons/scons/issues/1594
test.write(['src6', 'TestSCons.java'], """\
class test
{
diff --git a/test/Java/RMIC.py b/test/Java/RMIC.py
index b29a466..19e799e 100644
--- a/test/Java/RMIC.py
+++ b/test/Java/RMIC.py
@@ -108,6 +108,10 @@ if java_version.count('.') == 1:
# If it's 1.8 or higher, we skip the further RMIC test
# because we'll get warnings about the deprecated API...
# it's just not state-of-the-art anymore.
+# Recent java versions (9 and greater) are back to being
+# marketed as a simple version, but java_where_javac() will
+# still return a dotted version, like 10.0. If this changes,
+# will need to rework this rule.
# Note, how we allow simple version strings like "5" and
# "6" to successfully pass this test.
if curver < (1, 8):
diff --git a/test/Java/swig-dependencies.py b/test/Java/swig-dependencies.py
index c72c44a..bd7a576 100644
--- a/test/Java/swig-dependencies.py
+++ b/test/Java/swig-dependencies.py
@@ -130,7 +130,7 @@ except:
# Bug ticket reported also this seems work fine when running outsite
# the test framework
test.skip_test('Throwing no result for this test because of bug ' +
- 'related here: http://scons.tigris.org/issues/show_bug.cgi?id=2907\n')
+ 'related here: https://github.com/SCons/scons/issues/2907\n')
pass
#test.must_exist(['java', 'classes', 'foopack', 'foopack.class'])
#test.must_exist(['java', 'classes', 'foopack', 'foopackJNI.class'])
diff --git a/test/LINK/VersionedLib-VariantDir.py b/test/LINK/VersionedLib-VariantDir.py
index 0350c6e..340fee0 100644
--- a/test/LINK/VersionedLib-VariantDir.py
+++ b/test/LINK/VersionedLib-VariantDir.py
@@ -65,7 +65,7 @@ test.write(['src','bin','main.c'], """
__declspec(dllimport)
#endif
int foo();
-int main()
+int main(void)
{
return foo();
}
diff --git a/test/LINK/VersionedLib-j2.py b/test/LINK/VersionedLib-j2.py
index 4646a37..ed3b7ff 100644
--- a/test/LINK/VersionedLib-j2.py
+++ b/test/LINK/VersionedLib-j2.py
@@ -57,7 +57,7 @@ test.write('main.c', """
__declspec(dllimport)
#endif
int foo();
-int main() { return foo(); }
+int main(void) { return foo(); }
""")
test.write('SConstruct', """
diff --git a/test/LINK/VersionedLib-subdir.py b/test/LINK/VersionedLib-subdir.py
index 91f3011..2271a54 100644
--- a/test/LINK/VersionedLib-subdir.py
+++ b/test/LINK/VersionedLib-subdir.py
@@ -58,7 +58,7 @@ test.write('main.c', """
__declspec(dllimport)
#endif
int foo();
-int main()
+int main(void)
{
return foo();
}
diff --git a/test/LINK/applelink.py b/test/LINK/applelink.py
new file mode 100644
index 0000000..3419fc1
--- /dev/null
+++ b/test/LINK/applelink.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+
+import TestSCons
+
+_python_ = TestSCons._python_
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+
+test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("foo.c\n");
+ exit (0);
+}
+""")
+
+# Test issue # 2580
+test.write('SConstruct', """
+DefaultEnvironment(tools=[])
+env = Environment(PLATFORM='darwin')
+env.Object(
+ target = '#foo.o',
+ source = ['foo.c'],
+ FRAMEWORKS = ['Ogre'],
+ FRAMEWORKPATH = ['#frameworks']
+)
+""" % locals())
+
+test.run(arguments='-Q -n', stdout='gcc -o foo.o -c -Fframeworks foo.c\n')
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Libs/Library.py b/test/Libs/Library.py
index b603926..50fe68b 100644
--- a/test/Libs/Library.py
+++ b/test/Libs/Library.py
@@ -152,7 +152,7 @@ void nrd() {
test.write('uses-nrd.c', r"""
void nrd();
-int main() {
+int main(void) {
nrd();
return 0;
}
diff --git a/test/Libs/SharedLibrary-update-deps.py b/test/Libs/SharedLibrary-update-deps.py
index 076e3ad..3abce83 100644
--- a/test/Libs/SharedLibrary-update-deps.py
+++ b/test/Libs/SharedLibrary-update-deps.py
@@ -26,7 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Test that SharedLibrary() updates when a different lib is linked, even if it has the same md5.
-This is http://scons.tigris.org/issues/show_bug.cgi?id=2903
+This is https://github.com/SCons/scons/issues/2903
"""
import sys
diff --git a/test/M4/M4.py b/test/M4/M4.py
index 76010e6..82c084c 100644
--- a/test/M4/M4.py
+++ b/test/M4/M4.py
@@ -46,7 +46,8 @@ sys.exit(0)
""")
test.write('SConstruct', """
-env = Environment(tools=['default', 'm4'],
+DefaultEnvironment(tools=[])
+env = Environment(tools=['m4'],
M4 = r'%(_python_)s mym4.py')
env.M4(target = 'aaa.x', source = 'aaa.x.m4')
""" % locals())
@@ -76,10 +77,11 @@ if m4:
test.file_fixture('wrapper.py')
test.write('SConstruct', """
-foo = Environment(tools=['default', 'm4'],
+DefaultEnvironment(tools=[])
+foo = Environment(tools=['m4'],
M4=r'%(m4)s', M4FLAGS='-DFFF=fff')
m4 = foo.Dictionary('M4')
-bar = Environment(tools=['default', 'm4'],
+bar = Environment(tools=['m4'],
M4 = r'%(_python_)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb')
foo.M4(target = 'foo.x', source = 'foo.x.m4')
bar.M4(target = 'bar', source = 'bar.m4')
diff --git a/test/M4/M4COM.py b/test/M4/M4COM.py
index 5a2f076..4e95419 100644
--- a/test/M4/M4COM.py
+++ b/test/M4/M4COM.py
@@ -47,7 +47,8 @@ sys.exit(0)
""")
test.write('SConstruct', """
-env = Environment(tools=['default', 'm4'],
+DefaultEnvironment(tools=[])
+env = Environment(tools=['m4'],
M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES')
env.M4(target = 'aaa.out', source = 'aaa.in')
""" % locals())
diff --git a/test/M4/M4COMSTR.py b/test/M4/M4COMSTR.py
index da01e6c..0e6725b 100644
--- a/test/M4/M4COMSTR.py
+++ b/test/M4/M4COMSTR.py
@@ -48,7 +48,8 @@ sys.exit(0)
""")
test.write('SConstruct', """
-env = Environment(tools=['default', 'm4'],
+DefaultEnvironment(tools=[])
+env = Environment(tools=['m4'],
M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES',
M4COMSTR = 'M4ing $TARGET from $SOURCE')
env.M4(target = 'aaa.out', source = 'aaa.in')
diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir.py b/test/MSVC/MSVC_BATCH-spaces-targetdir.py
new file mode 100644
index 0000000..298e10e
--- /dev/null
+++ b/test/MSVC/MSVC_BATCH-spaces-targetdir.py
@@ -0,0 +1,11 @@
+import TestSCons
+
+
+
+test = TestSCons.TestSCons()
+
+test.skip_if_not_msvc()
+
+
+test.dir_fixture('MSVC_BATCH-spaces-targetdir')
+test.run() \ No newline at end of file
diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct b/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct
new file mode 100644
index 0000000..da8002b
--- /dev/null
+++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct
@@ -0,0 +1,8 @@
+import os.path
+
+env=Environment(MSVC_BATCH=True)
+
+td='tar ge tdir'
+VariantDir(td,'src')
+env.Program(os.path.join(td,'test_program'),
+ [os.path.join(td,a) for a in ['a.c','b.c','c.c']])
diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c
new file mode 100644
index 0000000..1741de8
--- /dev/null
+++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+extern void myfuncb();
+extern void myfuncc();
+
+
+void myfunca() {
+ printf("myfunca\n");
+}
+
+int main(int argc, char *argv[]) {
+ myfunca();
+ myfuncb();
+ myfuncc();
+} \ No newline at end of file
diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c
new file mode 100644
index 0000000..e03c5d0
--- /dev/null
+++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+void myfuncb() {
+ printf("myfuncb\n");
+} \ No newline at end of file
diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c
new file mode 100644
index 0000000..1c262d3
--- /dev/null
+++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+void myfuncc() {
+ printf("myfuncc\n");
+} \ No newline at end of file
diff --git a/test/MSVC/PCH-source.py b/test/MSVC/PCH-source.py
index 6015fec..ccab66d 100644
--- a/test/MSVC/PCH-source.py
+++ b/test/MSVC/PCH-source.py
@@ -28,7 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
Test use of pre-compiled headers when the source .cpp file shows
up in both the env.PCH() and the env.Program() source list.
-Issue 2505: http://scons.tigris.org/issues/show_bug.cgi?id=2505
+Issue 2505: http://github.com/SCons/scons/issues/2505
"""
import TestSCons
diff --git a/test/MSVC/batch.py b/test/MSVC/batch.py
index 8b7945b..0d3063f 100644
--- a/test/MSVC/batch.py
+++ b/test/MSVC/batch.py
@@ -32,6 +32,7 @@ explicit suffix settings so that the test should work when run on any
platform.
"""
+import os
import TestSCons
test = TestSCons.TestSCons()
@@ -72,6 +73,7 @@ for infile in sys.argv[2:]:
""")
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
cccom = r'%(_python_)s fake_cl.py $_MSVC_OUTPUT_FLAG $CHANGED_SOURCES'
linkcom = r'%(_python_)s fake_link.py ${TARGET.windows} $SOURCES'
env = Environment(tools=['msvc', 'mslink'],
@@ -96,8 +98,8 @@ test.run(arguments = 'MSVC_BATCH=1 .')
test.must_match('prog.exe', "prog.c\nf1.c\nf2.c\n", mode='r')
test.must_match('fake_cl.log', """\
-/Fo. prog.c f1.c f2.c
-""", mode='r')
+/Fo.%s prog.c f1.c f2.c
+"""%os.sep, mode='r')
test.up_to_date(options = 'MSVC_BATCH=1', arguments = '.')
@@ -109,9 +111,9 @@ test.run(arguments = 'MSVC_BATCH=1 .')
test.must_match('prog.exe', "prog.c\nf1.c 2\nf2.c\n", mode='r')
test.must_match('fake_cl.log', """\
-/Fo. prog.c f1.c f2.c
-/Fo. f1.c
-""", mode='r')
+/Fo.%s prog.c f1.c f2.c
+/Fo.%s f1.c
+"""%(os.sep, os.sep), mode='r')
test.up_to_date(options = 'MSVC_BATCH=1', arguments = '.')
diff --git a/test/MSVC/pch-basics.py b/test/MSVC/pch-basics.py
index 45735ed..ebee0da 100644
--- a/test/MSVC/pch-basics.py
+++ b/test/MSVC/pch-basics.py
@@ -39,7 +39,7 @@ test.skip_if_not_msvc()
test.write('Main.cpp', """\
#include "Precompiled.h"
-int main()
+int main(void)
{
return testf();
}
diff --git a/test/MSVC/pch-spaces-subdir.py b/test/MSVC/pch-spaces-subdir.py
index 3a65b44..65595fc 100644
--- a/test/MSVC/pch-spaces-subdir.py
+++ b/test/MSVC/pch-spaces-subdir.py
@@ -39,7 +39,7 @@ test.skip_if_not_msvc()
test.write('Main.cpp', """\
#include "Precompiled.h"
-int main()
+int main(void)
{
return testf();
}
diff --git a/test/MSVS/CPPPATH-Dirs.py b/test/MSVS/CPPPATH-Dirs.py
index 45ec846..53c7a8b 100644
--- a/test/MSVS/CPPPATH-Dirs.py
+++ b/test/MSVS/CPPPATH-Dirs.py
@@ -68,7 +68,7 @@ test.write('SConstruct', SConscript_contents)
test.write('main.cpp', """\
#include <stdio.h>
-int main() {
+int main(void) {
printf("hello, world!\\n");
}
""")
diff --git a/test/MSVS/vs-10.0-exec.py b/test/MSVS/vs-10.0-exec.py
index 1a4b59a..090bde8 100644
--- a/test/MSVS/vs-10.0-exec.py
+++ b/test/MSVS/vs-10.0-exec.py
@@ -55,11 +55,15 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-print("os.environ.update(%%s)" %% repr(env['ENV']))
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
-exec(test.stdout())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+exec(test.stdout())
test.subdir('sub dir')
diff --git a/test/MSVS/vs-10.0Exp-exec.py b/test/MSVS/vs-10.0Exp-exec.py
index a63f6c4..d6114bd 100644
--- a/test/MSVS/vs-10.0Exp-exec.py
+++ b/test/MSVS/vs-10.0Exp-exec.py
@@ -55,10 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-11.0-exec.py b/test/MSVS/vs-11.0-exec.py
index 21645f5..48acd1c 100644
--- a/test/MSVS/vs-11.0-exec.py
+++ b/test/MSVS/vs-11.0-exec.py
@@ -55,10 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-11.0Exp-exec.py b/test/MSVS/vs-11.0Exp-exec.py
index be48971..6a288a5 100644
--- a/test/MSVS/vs-11.0Exp-exec.py
+++ b/test/MSVS/vs-11.0Exp-exec.py
@@ -55,10 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-14.0-exec.py b/test/MSVS/vs-14.0-exec.py
index f2a826c..d2b7112 100644
--- a/test/MSVS/vs-14.0-exec.py
+++ b/test/MSVS/vs-14.0-exec.py
@@ -55,10 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-6.0-clean.py b/test/MSVS/vs-6.0-clean.py
index 6b9bd98..0cbadba 100644
--- a/test/MSVS/vs-6.0-clean.py
+++ b/test/MSVS/vs-6.0-clean.py
@@ -72,7 +72,7 @@ env.MSVSSolution(target = 'Test.dsw',
variant = 'Release')
"""%{'HOST_ARCH':host_arch})
-test.run(arguments=".")
+test.run()
test.must_exist(test.workpath('Test.dsp'))
dsp = test.read('Test.dsp', 'r')
diff --git a/test/MSVS/vs-6.0-exec.py b/test/MSVS/vs-6.0-exec.py
index d017790..0864f76 100644
--- a/test/MSVS/vs-6.0-exec.py
+++ b/test/MSVS/vs-6.0-exec.py
@@ -54,10 +54,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-7.0-exec.py b/test/MSVS/vs-7.0-exec.py
index e62ee77..e95ca83 100644
--- a/test/MSVS/vs-7.0-exec.py
+++ b/test/MSVS/vs-7.0-exec.py
@@ -54,10 +54,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-7.1-exec.py b/test/MSVS/vs-7.1-exec.py
index 42f6ae8..11ea617 100644
--- a/test/MSVS/vs-7.1-exec.py
+++ b/test/MSVS/vs-7.1-exec.py
@@ -54,10 +54,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-8.0-exec.py b/test/MSVS/vs-8.0-exec.py
index 96c4c29..4b0a6dd 100644
--- a/test/MSVS/vs-8.0-exec.py
+++ b/test/MSVS/vs-8.0-exec.py
@@ -55,9 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-print("os.environ.update(%%s)" %% repr(env['ENV']))
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-8.0Exp-exec.py b/test/MSVS/vs-8.0Exp-exec.py
index 66196f1..0e4396d 100644
--- a/test/MSVS/vs-8.0Exp-exec.py
+++ b/test/MSVS/vs-8.0Exp-exec.py
@@ -55,10 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-9.0-exec.py b/test/MSVS/vs-9.0-exec.py
index 7b544aa..3f823fa 100644
--- a/test/MSVS/vs-9.0-exec.py
+++ b/test/MSVS/vs-9.0-exec.py
@@ -55,10 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MSVS/vs-9.0Exp-exec.py b/test/MSVS/vs-9.0Exp-exec.py
index caa763e..5a65faf 100644
--- a/test/MSVS/vs-9.0Exp-exec.py
+++ b/test/MSVS/vs-9.0Exp-exec.py
@@ -55,10 +55,14 @@ if not msvs_version in test.msvs_versions():
test.run(arguments = '-n -q -Q -f -', stdin = """\
env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
-sconsEnv = repr(env['ENV'])
-print("os.environ.update(" + sconsEnv + ")")
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
""" % locals())
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
exec(test.stdout())
diff --git a/test/MinGW/MinGWSharedLibrary.py b/test/MinGW/MinGWSharedLibrary.py
index dcebd45..86ddd43 100644
--- a/test/MinGW/MinGWSharedLibrary.py
+++ b/test/MinGW/MinGWSharedLibrary.py
@@ -32,8 +32,11 @@ when using MinGW.
import sys
import TestSCons
+import SCons.Tool
import SCons.Tool.mingw
import SCons.Defaults
+from SCons.Platform.mingw import MINGW_DEFAULT_PATHS
+from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS
_python_ = TestSCons._python_
@@ -42,10 +45,10 @@ test = TestSCons.TestSCons()
if sys.platform not in ('cygwin','win32',):
test.skip_test("Skipping mingw test on non-Windows %s platform."%sys.platform)
-if not SCons.Tool.mingw.find(SCons.Defaults.DefaultEnvironment()):
+gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS )
+if not gcc:
test.skip_test("Skipping mingw test, no MinGW found.\n")
-
test.write('foobar.cc', """
int abc(int a) {
return (a+1);
diff --git a/test/MinGW/WINDOWS_INSERT_DEF.py b/test/MinGW/WINDOWS_INSERT_DEF.py
index 67d3e9b..f82ebd8 100644
--- a/test/MinGW/WINDOWS_INSERT_DEF.py
+++ b/test/MinGW/WINDOWS_INSERT_DEF.py
@@ -31,8 +31,11 @@ Make sure that WINDOWS_INSERT_DEF isn't ignored when using MinGW.
import sys
import TestSCons
+import SCons.Tool
import SCons.Tool.mingw
import SCons.Defaults
+from SCons.Platform.mingw import MINGW_DEFAULT_PATHS
+from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS
test = TestSCons.TestSCons()
@@ -40,7 +43,8 @@ if sys.platform not in ('cygwin', 'win32'):
test.skip_test(
"Skipping mingw test on non-Windows platform: %s" % sys.platform)
-if not SCons.Tool.mingw.find(SCons.Defaults.DefaultEnvironment()):
+gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS )
+if not gcc:
test.skip_test("Skipping mingw test, no MinGW found.\n")
test.write('hello.c', r"""
diff --git a/test/QT/CPPPATH-appended.py b/test/QT/CPPPATH-appended.py
index 2780921..98baad8 100644
--- a/test/QT/CPPPATH-appended.py
+++ b/test/QT/CPPPATH-appended.py
@@ -57,7 +57,7 @@ env.Program(target = 'aaa', source = 'aaa.cpp')
test.write(['sub', 'aaa.cpp'], r"""
#include "aaa.h"
-int main() { aaa(); return 0; }
+int main(void) { aaa(); return 0; }
""")
test.write(['sub', 'aaa.h'], r"""
diff --git a/test/QT/CPPPATH.py b/test/QT/CPPPATH.py
index 4ea42bd..5de41d9 100644
--- a/test/QT/CPPPATH.py
+++ b/test/QT/CPPPATH.py
@@ -47,7 +47,7 @@ env.Program(target = 'aaa', source = 'aaa.cpp', CPPPATH=['$CPPPATH', './local_in
test.write('aaa.cpp', r"""
#include "aaa.h"
-int main() { aaa(); return 0; }
+int main(void) { aaa(); return 0; }
""")
test.write('aaa.h', r"""
diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py
index 8d266ad..61a1d87 100644
--- a/test/QT/QTFLAGS.py
+++ b/test/QT/QTFLAGS.py
@@ -127,7 +127,7 @@ test.write(['work1', 'main.cpp'], """
#include "uic-another_ui_file.hpp"
void mocFromCpp();
-int main() {
+int main(void) {
mocFromH();
mocFromCpp();
an_ui_file();
@@ -189,7 +189,7 @@ env2.Program('main.cpp')
""" % {'QTDIR':QT})
test.write(['work2', 'main.cpp'], """
-int main() { return 0; }
+int main(void) { return 0; }
""")
# Ignore stderr, because if Qt is not installed,
diff --git a/test/QT/empty-env.py b/test/QT/empty-env.py
index 77547e7..b7867e5 100644
--- a/test/QT/empty-env.py
+++ b/test/QT/empty-env.py
@@ -46,7 +46,7 @@ env.Program('main', 'main.cpp', CPPDEFINES=['FOO'], LIBS=[])
test.write('main.cpp', r"""
#include "foo6.h"
-int main() { foo6(); return 0; }
+int main(void) { foo6(); return 0; }
""")
test.write(['qt', 'include', 'foo6.h'], """\
diff --git a/test/QT/generated-ui.py b/test/QT/generated-ui.py
index e4632b1..4692a82 100644
--- a/test/QT/generated-ui.py
+++ b/test/QT/generated-ui.py
@@ -61,7 +61,7 @@ import SCons.Defaults
def ExpHeaderScanner(node, env, path):
return []
def generate(env):
- HeaderAction=SCons.Action.Action([SCons.Defaults.Copy('$TARGET','$SOURCE'),SCons.Defaults.Chmod('$TARGET',0755)])
+ HeaderAction=SCons.Action.Action([SCons.Defaults.Copy('$TARGET','$SOURCE'),SCons.Defaults.Chmod('$TARGET',0o755)])
HeaderBuilder= SCons.Builder.Builder(action=HeaderAction)
env['BUILDERS']['ExportHeaders'] = HeaderBuilder
def exists(env):
diff --git a/test/QT/manual.py b/test/QT/manual.py
index 1f140ae..c5cf74e 100644
--- a/test/QT/manual.py
+++ b/test/QT/manual.py
@@ -119,7 +119,7 @@ test.write('main.cpp', r"""
#include "eee.h"
#include "uic_fff.hpp"
-int main() {
+int main(void) {
aaa(); bbb(); ccc(); ddd(); eee(); fff(); return 0;
}
""")
diff --git a/test/QT/moc-from-header.py b/test/QT/moc-from-header.py
index 41b1b3d..4151cba 100644
--- a/test/QT/moc-from-header.py
+++ b/test/QT/moc-from-header.py
@@ -61,7 +61,7 @@ if env['PLATFORM'] == 'darwin':
test.write('aaa.cpp', r"""
#include "aaa.h"
-int main() { aaa(); return 0; }
+int main(void) { aaa(); return 0; }
""")
test.write('aaa.h', r"""
diff --git a/test/QT/reentrant.py b/test/QT/reentrant.py
index be464b9..af19af9 100644
--- a/test/QT/reentrant.py
+++ b/test/QT/reentrant.py
@@ -56,7 +56,7 @@ env.Program('main', 'main.cpp', CPPDEFINES=['FOO'], LIBS=[])
test.write('main.cpp', r"""
#include "foo5.h"
-int main() { foo5(); return 0; }
+int main(void) { foo5(); return 0; }
""")
test.run()
diff --git a/test/QT/up-to-date.py b/test/QT/up-to-date.py
index 21c758e..7a7e565 100644
--- a/test/QT/up-to-date.py
+++ b/test/QT/up-to-date.py
@@ -66,7 +66,7 @@ import SCons.Defaults
def ExpHeaderScanner(node, env, path):
return []
def generate(env):
- HeaderAction=SCons.Action.Action([SCons.Defaults.Copy('$TARGET','$SOURCE'),SCons.Defaults.Chmod('$TARGET',0755)])
+ HeaderAction=SCons.Action.Action([SCons.Defaults.Copy('$TARGET','$SOURCE'),SCons.Defaults.Chmod('$TARGET',0o755)])
HeaderBuilder= SCons.Builder.Builder(action=HeaderAction)
env['BUILDERS']['ExportHeaders'] = HeaderBuilder
def exists(env):
diff --git a/test/README b/test/README
index 2c8423f..be75398 100644
--- a/test/README
+++ b/test/README
@@ -4,7 +4,7 @@ This directory contains our end-to-end SCons tests.
They are all meant to be run essentially standalone, with the exception
of the TestSCons.py module and the other modules imported by the various
-tests. These modules are in the QMTest/ subdirectory, and PYTHONPATH
+tests. These modules are in the testing/framework/ subdirectory, and PYTHONPATH
needs to be set up correctly so that the test scripts can find them,
and so that the SCons script itself can find the build engine modules.
@@ -56,4 +56,4 @@ semblance of uniformity, here are the naming conventions for tests:
For some more information about running the tests and writing them, please
refer to the documentation for the testing framework. It can be found in
-the 'QMTest' folder, as file 'test-framework.rst'.
+the 'testing/framework' folder, as file 'test-framework.rst'.
diff --git a/test/RPATH.py b/test/RPATH.py
index 4e13bb1..754abfe 100644
--- a/test/RPATH.py
+++ b/test/RPATH.py
@@ -46,7 +46,7 @@ Program('foo', 'foo.c', LIBS='bar', LIBPATH='bar', RPATH='bar')
test.write('foo.c', """\
#include <stdlib.h>
-int main() {
+int main(void) {
void bar();
bar();
exit (0);
diff --git a/test/Repository/Java.py b/test/Repository/Java.py
index fce85cd..290d742 100644
--- a/test/Repository/Java.py
+++ b/test/Repository/Java.py
@@ -59,7 +59,7 @@ opts = '-Y ' + test.workpath('rep1')
#
test.write(['rep1', 'SConstruct'], """
env = Environment(tools = ['javac'],
- JAVAC = r'%s')
+ JAVAC = r'"%s"')
env.Java(target = 'classes', source = 'src')
""" % javac)
diff --git a/test/Repository/JavaH.py b/test/Repository/JavaH.py
index ee196cf..1cb5078 100644
--- a/test/Repository/JavaH.py
+++ b/test/Repository/JavaH.py
@@ -63,8 +63,8 @@ opts = '-Y ' + test.workpath('rep1')
#
test.write(['rep1', 'SConstruct'], """
env = Environment(tools = ['javac', 'javah'],
- JAVAC = r'%s',
- JAVAH = r'%s')
+ JAVAC = r'"%s"',
+ JAVAH = r'"%s"')
classes = env.Java(target = 'classes', source = 'src')
env.JavaH(target = 'outdir', source = classes)
""" % (javac, javah))
@@ -207,8 +207,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
#
test.write(['work3', 'SConstruct'], """
env = Environment(tools = ['javac', 'javah'],
- JAVAC = r'%s',
- JAVAH = r'%s')
+ JAVAC = r'"%s"',
+ JAVAH = r'"%s"')
classes = env.Java(target = 'classes', source = 'src')
hfiles = env.JavaH(target = 'outdir', source = classes)
Local(hfiles)
diff --git a/test/Repository/RMIC.py b/test/Repository/RMIC.py
index 886ccdb..433890f 100644
--- a/test/Repository/RMIC.py
+++ b/test/Repository/RMIC.py
@@ -29,6 +29,7 @@ Test building Java applications when using Repositories.
"""
import TestSCons
+import os
python = TestSCons.python
@@ -50,6 +51,10 @@ if java_version.count('.') == 1:
# If it's 1.8 or higher, we skip the further RMIC test
# because we'll get warnings about the deprecated API...
# it's just not state-of-the-art anymore.
+# Recent java versions (9 and greater) are back to being
+# marketed as a simple version, but java_where_javac() will
+# still return a dotted version, like 10.0. If this changes,
+# will need to rework this rule.
# Note, how we allow simple version strings like "5" and
# "6" to successfully pass this test.
if curver >= (1, 8):
@@ -82,8 +87,8 @@ opts = '-Y ' + test.workpath('rep1')
#
test.write(['rep1', 'SConstruct'], """
env = Environment(tools = ['javac', 'rmic'],
- JAVAC = r'%s',
- RMIC = r'%s')
+ JAVAC = r'"%s"',
+ RMIC = r'"%s"')
classes = env.Java(target = 'classes', source = 'src')
# Brute-force removal of the "Hello" class.
classes = [c for c in classes if str(c).find('Hello') == -1]
@@ -302,7 +307,7 @@ public class Foo2 extends UnicastRemoteObject implements Hello {
test.run(chdir = 'work1', options = opts, arguments = ".")
expect = [
- ' src/Foo1.java src/Foo2.java',
+ ' src' + os.sep + 'Foo1.java src' + os.sep + 'Foo2.java',
' com.sub.foo.Foo1 com.sub.foo.Foo2',
]
@@ -350,8 +355,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
#
test.write(['work3', 'SConstruct'], """
env = Environment(tools = ['javac', 'rmic'],
- JAVAC = r'%s',
- RMIC = r'%s')
+ JAVAC = r'"%s"',
+ RMIC = r'"%s"')
classes = env.Java(target = 'classes', source = 'src')
# Brute-force removal of the "Hello" class.
classes = [c for c in classes if str(c).find('Hello') == -1]
diff --git a/test/SConscript/must_exist.py b/test/SConscript/must_exist.py
new file mode 100644
index 0000000..3faf0ce
--- /dev/null
+++ b/test/SConscript/must_exist.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+'''
+Test handling of must_exist flag and global setting requiring the
+file to exist in an SConscript call
+'''
+
+import os
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+# catch the exception if is raised, send it on as a warning
+# this gives us traceability of the line responsible
+SConstruct_path = test.workpath('SConstruct')
+test.write(SConstruct_path, """\
+import SCons
+from SCons.Warnings import _warningOut
+import sys
+
+# 1. call should succeed with deprecation warning
+try:
+ SConscript('missing/SConscript')
+except SCons.Errors.UserError as e:
+ if _warningOut:
+ _warningOut(e)
+# 2. call should succeed with warning
+try:
+ SConscript('missing/SConscript')
+except SCons.Errors.UserError as e:
+ if _warningOut:
+ _warningOut(e)
+# 3. call should raise exception
+try:
+ SConscript('missing/SConscript', must_exist=True)
+except SCons.Errors.UserError as e:
+ if _warningOut:
+ _warningOut(e)
+# 4. call should succeed with warning
+try:
+ SConscript('missing/SConscript', must_exist=False)
+except SCons.Errors.UserError as e:
+ if _warningOut:
+ _warningOut(e)
+SCons.Script.set_missing_sconscript_error()
+# 5. with system setting changed, should raise exception
+try:
+ SConscript('missing/SConscript')
+except SCons.Errors.UserError as e:
+ if _warningOut:
+ _warningOut(e)
+# 6. must_exist=False overrides system setting, should emit warning
+try:
+ SConscript('missing/SConscript', must_exist=False)
+except SCons.Errors.UserError as e:
+ if _warningOut:
+ _warningOut(e)
+""")
+
+# we should see two exceptions as "Fatal" and
+# and see four warnings, the first having the depr message
+# need to build the path in the expected msg in an OS-agnostic way
+missing = os.path.normpath('missing/SConscript')
+warn1 = """
+scons: warning: Calling missing SConscript without error is deprecated.
+Transition by adding must_exist=0 to SConscript calls.
+Missing SConscript '{}'
+""".format(missing) + test.python_file_line(SConstruct_path, 7)
+
+warn2 = """
+scons: warning: Ignoring missing SConscript '{}'
+""".format(missing) + test.python_file_line(SConstruct_path, 13)
+
+err1 = """
+scons: warning: Fatal: missing SConscript '{}'
+""".format(missing) + test.python_file_line(SConstruct_path, 22)
+
+warn3 = """
+scons: warning: Ignoring missing SConscript '{}'
+""".format(missing) + test.python_file_line(SConstruct_path, 25)
+
+err2 = """
+scons: warning: Fatal: missing SConscript '{}'
+""".format(missing) + test.python_file_line(SConstruct_path, 35)
+
+warn4 = """
+scons: warning: Ignoring missing SConscript '{}'
+""".format(missing) + test.python_file_line(SConstruct_path, 38)
+
+expect_stderr = warn1 + warn2 + err1 + warn3 + err2 + warn4
+test.run(arguments = ".", stderr = expect_stderr)
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/SConstruct.py b/test/SConstruct.py
index cebdf04..8bc8617 100644
--- a/test/SConstruct.py
+++ b/test/SConstruct.py
@@ -39,6 +39,33 @@ scons: \*\*\* No SConstruct file found.
wpath = test.workpath()
+test.write('sconstruct.py', """
+import os
+print("sconstruct.py "+os.getcwd())
+""")
+
+test.run(arguments = ".",
+ stdout = test.wrap_stdout(read_str = 'sconstruct.py %s\n' % wpath,
+ build_str = "scons: `.' is up to date.\n"))
+
+test.write('Sconstruct.py', """
+import os
+print("sconstruct.py "+os.getcwd())
+""")
+
+test.run(arguments = ".",
+ stdout = test.wrap_stdout(read_str = 'sconstruct.py %s\n' % wpath,
+ build_str = "scons: `.' is up to date.\n"))
+
+test.write('SConstruct.py', """
+import os
+print("SConstruct.py "+os.getcwd())
+""")
+
+test.run(arguments = ".",
+ stdout = test.wrap_stdout(read_str = 'SConstruct.py %s\n' % wpath,
+ build_str = "scons: `.' is up to date.\n"))
+
test.write('sconstruct', """
import os
print("sconstruct "+os.getcwd())
diff --git a/test/SWIG/SWIGOUTDIR-python.py b/test/SWIG/SWIGOUTDIR-python.py
index db0cc95..8d6703f 100644
--- a/test/SWIG/SWIGOUTDIR-python.py
+++ b/test/SWIG/SWIGOUTDIR-python.py
@@ -30,7 +30,6 @@ that Python files are created in the specified output directory.
"""
import TestSCons
-import os
import sys
test = TestSCons.TestSCons()
@@ -40,10 +39,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# On Windows, build a 32-bit exe if on 32-bit python.
if sys.platform == 'win32' and sys.maxsize <= 2**32:
diff --git a/test/SWIG/SWIGPATH.py b/test/SWIG/SWIGPATH.py
index 55e8d7e..d516c0c 100644
--- a/test/SWIG/SWIGPATH.py
+++ b/test/SWIG/SWIGPATH.py
@@ -40,7 +40,8 @@ python = test.where_is('python')
if not python:
test,skip_test('Can not find installed "python", skipping test.\n')
-
+swig = swig.replace('\\','/')
+python = python.replace('\\','/')
test.subdir('inc1', 'inc2')
test.write(['inc2', 'dependency.i'], """\
@@ -95,4 +96,4 @@ test.pass_test()
# tab-width:4
# indent-tabs-mode:nil
# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
+# vim: set expandtab tabstop=4 shiftwidth=4: \ No newline at end of file
diff --git a/test/SWIG/build-dir.py b/test/SWIG/build-dir.py
index eba3fea..d268c87 100644
--- a/test/SWIG/build-dir.py
+++ b/test/SWIG/build-dir.py
@@ -29,7 +29,6 @@ Make sure SWIG works when a VariantDir (or variant_dir) is used.
Test case courtesy Joe Maruszewski.
"""
-import os.path
import sys
import TestSCons
@@ -50,10 +49,7 @@ else:
test.subdir(['source'])
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
if sys.platform == 'win32' and sys.maxsize <= 2**32:
swig_arch_var="TARGET_ARCH='x86',"
diff --git a/test/SWIG/generated_swigfile.py b/test/SWIG/generated_swigfile.py
index d09b473..145349b 100644
--- a/test/SWIG/generated_swigfile.py
+++ b/test/SWIG/generated_swigfile.py
@@ -29,7 +29,6 @@ Verify that SCons realizes the -noproxy option means no .py file will
be created.
"""
-import os
import sys
import TestSCons
@@ -55,10 +54,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# handle testing on other platforms:
ldmodule_prefix = '_'
diff --git a/test/SWIG/implicit-dependencies.py b/test/SWIG/implicit-dependencies.py
index 465a0d6..8664bf6 100644
--- a/test/SWIG/implicit-dependencies.py
+++ b/test/SWIG/implicit-dependencies.py
@@ -40,7 +40,8 @@ python = test.where_is('python')
if not python:
test.skip_test('Can not find installed "python", skipping test.\n')
-
+swig = swig.replace('\\','/')
+python = python.replace('\\','/')
test.write("dependency.i", """\
%module dependency
""")
@@ -75,4 +76,4 @@ test.pass_test()
# tab-width:4
# indent-tabs-mode:nil
# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
+# vim: set expandtab tabstop=4 shiftwidth=4: \ No newline at end of file
diff --git a/test/SWIG/live.py b/test/SWIG/live.py
index 05971aa..a64defe 100644
--- a/test/SWIG/live.py
+++ b/test/SWIG/live.py
@@ -28,7 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
Test SWIG behavior with a live, installed SWIG.
"""
-import os.path
+import os
import sys
import TestSCons
@@ -47,10 +47,13 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
+
+swig = swig.replace('\\','/')
+python = python.replace('\\','/')
+python_include = python_include.replace('\\','/')
+python_libpath = python_libpath.replace('\\','/')
+python_lib = python_lib.replace('\\','/')
# handle testing on other platforms:
ldmodule_prefix = '_'
@@ -142,7 +145,7 @@ test.up_to_date(arguments = ldmodule_prefix+'foo' + _dll)
test.run(arguments = ldmodule_prefix+'bar' + _dll)
-test.must_match('wrapper.out', "wrapper.py\n")
+test.must_match('wrapper.out', "wrapper.py" + os.linesep)
test.run(program = python, stdin = """\
from __future__ import print_function
diff --git a/test/SWIG/module-deduced-name.py b/test/SWIG/module-deduced-name.py
index bdaef4f..14d23a2 100644
--- a/test/SWIG/module-deduced-name.py
+++ b/test/SWIG/module-deduced-name.py
@@ -31,7 +31,6 @@ emitter should return the basename of the module only.
"""
import TestSCons
-import os
import sys
test = TestSCons.TestSCons()
@@ -41,10 +40,7 @@ if not swig:
test.skip_test('Cannot find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Cannot find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# On Windows, build a 32-bit exe if on 32-bit python.
if sys.platform == 'win32' and sys.maxsize <= 2**32:
diff --git a/test/SWIG/module-parens.py b/test/SWIG/module-parens.py
index d8c1744..4ce7511 100644
--- a/test/SWIG/module-parens.py
+++ b/test/SWIG/module-parens.py
@@ -29,7 +29,6 @@ Verify that we handle %module(directors="1") statements, both with and
without white space before the opening parenthesis.
"""
-import os.path
import sys
import TestSCons
@@ -40,10 +39,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# swig-python expects specific filenames.
# the platform specific suffix won't necessarily work.
diff --git a/test/SWIG/module-quoted.py b/test/SWIG/module-quoted.py
index 6f4b891..60bc0b0 100644
--- a/test/SWIG/module-quoted.py
+++ b/test/SWIG/module-quoted.py
@@ -29,7 +29,6 @@ Verify that we correctly parse quoted module names; e.g. %module "test"
(SWIG permits double-quoted names but not single-quoted ones.)
"""
-import os.path
import sys
import TestSCons
@@ -40,10 +39,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# swig-python expects specific filenames.
# the platform specific suffix won't necessarily work.
diff --git a/test/SWIG/module-spaces.py b/test/SWIG/module-spaces.py
index 2833dff..6a3f270 100644
--- a/test/SWIG/module-spaces.py
+++ b/test/SWIG/module-spaces.py
@@ -29,7 +29,6 @@ Verify that we correctly parse module names with spaces on the line after
the module name ; e.g. "%module test "
"""
-import os.path
import sys
import TestSCons
@@ -40,10 +39,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# swig-python expects specific filenames.
# the platform specific suffix won't necessarily work.
diff --git a/test/SWIG/noproxy.py b/test/SWIG/noproxy.py
index 1aaeb08..f94f553 100644
--- a/test/SWIG/noproxy.py
+++ b/test/SWIG/noproxy.py
@@ -29,7 +29,6 @@ Verify that SCons realizes the -noproxy option means no .py file will
be created.
"""
-import os
import sys
import TestSCons
@@ -48,10 +47,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# handle testing on other platforms:
ldmodule_prefix = '_'
diff --git a/test/SWIG/recursive-includes-cpp.py b/test/SWIG/recursive-includes-cpp.py
index dbcac6d..3999cc3 100644
--- a/test/SWIG/recursive-includes-cpp.py
+++ b/test/SWIG/recursive-includes-cpp.py
@@ -30,7 +30,9 @@ in cases of recursive inclusion.
"""
import os
+import sys
import TestSCons
+import TestCmd
from SCons.Defaults import DefaultEnvironment
DefaultEnvironment( tools = [ 'swig' ] )
@@ -42,6 +44,14 @@ for pre_req in ['swig', 'python']:
if not test.where_is(pre_req):
test.skip_test('Can not find installed "' + pre_req + '", skipping test.%s' % os.linesep)
+python, python_include, python_libpath, python_lib = \
+ test.get_platform_python_info(python_h_required=True)
+
+if sys.platform == 'win32':
+ python_lib = os.path.dirname(sys.executable) + "/libs/" + ('python%d%d'%(sys.version_info[0],sys.version_info[1])) + '.lib'
+ if( not os.path.isfile(python_lib)):
+ test.skip_test('Can not find python lib at "' + python_lib + '", skipping test.%s' % os.linesep)
+
test.write("recursive.h", """\
/* An empty header file. */
""")
@@ -62,27 +72,40 @@ test.write("mod.i", """\
#include "main.h"
""")
+
+if TestCmd.IS_WINDOWS:
+ if TestCmd.IS_64_BIT:
+ TARGET_ARCH = "TARGET_ARCH = 'x86_64',"
+ else:
+ TARGET_ARCH = "TARGET_ARCH = 'x86',"
+else:
+ TARGET_ARCH = ""
test.write('SConstruct', """\
-import distutils.sysconfig
+import sysconfig
import sys
-
-DefaultEnvironment( tools = [ 'swig' ] )
+import os
env = Environment(
+ """ + TARGET_ARCH + """
SWIGFLAGS = [
'-python'
],
CPPPATH = [
- distutils.sysconfig.get_python_inc()
+ sysconfig.get_config_var("INCLUDEPY")
],
- SHLIBPREFIX = ""
+ SHLIBPREFIX = "",
+ tools = [ 'default', 'swig' ]
)
if sys.platform == 'darwin':
env['LIBS']=['python%d.%d'%(sys.version_info[0],sys.version_info[1])]
+ env.Append(LIBPATH=[sysconfig.get_config_var("LIBDIR")])
+elif sys.platform == 'win32':
+ env.Append(LIBS=['python%d%d'%(sys.version_info[0],sys.version_info[1])])
+ env.Append(LIBPATH=[os.path.dirname(sys.executable) + "/libs"])
env.SharedLibrary(
- 'mod.so',
+ 'mod',
[
"mod.i",
"main.c",
@@ -90,27 +113,33 @@ env.SharedLibrary(
)
""")
+if sys.platform == 'win32':
+ object_suffix = ".obj"
+else:
+ object_suffix = ".os"
+
expectMain = """\
-+-main.os
++-main%s
+-main.c
+-main.h
- +-recursive.h"""
+ +-recursive.h""" % object_suffix
expectMod = """\
-+-mod_wrap.os
++-mod_wrap%s
+-mod_wrap.c
| +-mod.i
| +-main.h
- | +-recursive.h"""
+ | +-recursive.h""" % object_suffix
# Validate that the recursive dependencies are found with SWIG scanning first.
-test.run( arguments = '--tree=all mod_wrap.os main.os' )
+test.run( arguments = '--tree=all mod_wrap'+object_suffix +' main'+object_suffix)
test.must_contain_all( test.stdout(), expectMain )
test.must_contain_all( test.stdout(), expectMod )
+
# Validate that the recursive dependencies are found consistently.
-test.run( arguments = '--tree=all main.os mod_wrap.os' )
+test.run( arguments = '--tree=all main'+object_suffix +' mod_wrap'+object_suffix)
test.must_contain_all( test.stdout(), expectMain )
test.must_contain_all( test.stdout(), expectMod )
diff --git a/test/SWIG/remove-modules.py b/test/SWIG/remove-modules.py
index f5ce60d..a4d7b16 100644
--- a/test/SWIG/remove-modules.py
+++ b/test/SWIG/remove-modules.py
@@ -29,7 +29,6 @@ Verify that swig-generated modules are removed.
The %module directive specifies the module name.
"""
-import os.path
import sys
import TestSCons
@@ -48,10 +47,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# handle testing on other platforms:
ldmodule_prefix = '_'
diff --git a/test/SWIG/subdir.py b/test/SWIG/subdir.py
index e23b858..6951753 100644
--- a/test/SWIG/subdir.py
+++ b/test/SWIG/subdir.py
@@ -29,7 +29,6 @@ Verify that we expect the .py file created by the -python flag to be in
the same subdirectory as the taget.
"""
-import os
import sys
import TestSCons
@@ -50,10 +49,7 @@ if not swig:
test.skip_test('Can not find installed "swig", skipping test.\n')
python, python_include, python_libpath, python_lib = \
- test.get_platform_python_info()
-Python_h = os.path.join(python_include, 'Python.h')
-if not os.path.exists(Python_h):
- test.skip_test('Can not find %s, skipping test.\n' % Python_h)
+ test.get_platform_python_info(python_h_required=True)
# handle testing on other platforms:
ldmodule_prefix = '_'
diff --git a/test/Scanner/Dir.py b/test/Scanner/Dir.py
index 86b80e9..fa4f6c9 100644
--- a/test/Scanner/Dir.py
+++ b/test/Scanner/Dir.py
@@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Verify that a simple scanner that returns Dir nodes works correctly.
-Submitted as http://scons.tigris.org/issues/show_bug.cgi?id=2534
+Submitted as https://github.com/SCons/scons/issues/2534
"""
import TestSCons
diff --git a/test/SideEffect/Issues/3013/files/SConscript b/test/SideEffect/Issues/3013/files/SConscript
new file mode 100644
index 0000000..27da7bb
--- /dev/null
+++ b/test/SideEffect/Issues/3013/files/SConscript
@@ -0,0 +1,5 @@
+Import('env')
+
+primary = env.make_file('output', 'test.cpp')
+this_causes_problems = env.SideEffect('output_side_effect', 'output')
+
diff --git a/test/SideEffect/Issues/3013/files/SConstruct b/test/SideEffect/Issues/3013/files/SConstruct
new file mode 100644
index 0000000..d01a4b7
--- /dev/null
+++ b/test/SideEffect/Issues/3013/files/SConstruct
@@ -0,0 +1,21 @@
+env = Environment()
+
+def make_file(target, source, env):
+ with open(str(target[0]), 'w') as f:
+ f.write('gobldygook')
+ with open(str(target[0]) + '_side_effect', 'w') as side_effect:
+ side_effect.write('anything')
+
+env.Append(
+ BUILDERS={'make_file': Builder(action=Action(make_file))}
+)
+
+env.objdir = 'build'
+
+SConscript(
+ 'SConscript',
+ variant_dir=env.objdir,
+ exports={'env':env},
+ duplicate=0
+)
+
diff --git a/test/SideEffect/Issues/3013/files/test.cpp b/test/SideEffect/Issues/3013/files/test.cpp
new file mode 100644
index 0000000..27424b0
--- /dev/null
+++ b/test/SideEffect/Issues/3013/files/test.cpp
@@ -0,0 +1,2 @@
+void some_function() {}
+
diff --git a/test/SideEffect/Issues/3013/sideffect_with_variantdir.py b/test/SideEffect/Issues/3013/sideffect_with_variantdir.py
new file mode 100644
index 0000000..9ca3eca
--- /dev/null
+++ b/test/SideEffect/Issues/3013/sideffect_with_variantdir.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test materials for Github Issue 3013 submitted by Stefan Ross:
+https://github.com/SCons/scons/issues/3013
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.dir_fixture('files')
+
+test.run(
+ arguments = '-j2'
+)
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
+
diff --git a/test/Subst/Literal.py b/test/Subst/Literal.py
new file mode 100644
index 0000000..dec243d
--- /dev/null
+++ b/test/Subst/Literal.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that Literal objects expand correctly in ${_concat()}.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """\
+env = Environment(PRE='pre=', MID=Literal('\$$ORIGIN'), SUF='')
+print(env.subst('${_concat(PRE, MID, SUF, __env__)}'))
+""")
+
+test.run()
+
+expect = """\
+pre=\$ORIGIN
+"""
+
+test.run(arguments='-Q -q', stdout=expect)
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/VariantDir/include-subdir.py b/test/VariantDir/include-subdir.py
index d616bba..fe26c0a 100644
--- a/test/VariantDir/include-subdir.py
+++ b/test/VariantDir/include-subdir.py
@@ -32,7 +32,7 @@ we have to make sure that the file gets copied to the variant dir. (This
was not the case for 0.98.5 and earlier)
Test case supplied by Jared Grubb, based on a minimal example supplied
-by Ali Tofigh, filed as http://scons.tigris.org/issues/show_bug.cgi?id=2121
+by Ali Tofigh, filed as https://github.com/SCons/scons/issues/2121
"""
import TestSCons
diff --git a/test/YACC/YACC-fixture/myyacc.py b/test/YACC/YACC-fixture/myyacc.py
index c2e1abf..756c98f 100644
--- a/test/YACC/YACC-fixture/myyacc.py
+++ b/test/YACC/YACC-fixture/myyacc.py
@@ -4,10 +4,10 @@ cmd_opts, args = getopt.getopt(sys.argv[1:], 'o:', [])
output = None
opt_string = ''
for opt, arg in cmd_opts:
- if opt == '-o': output = open(arg, 'wb')
+ if opt == '-o': output = open(arg, 'w')
else: opt_string = opt_string + ' ' + opt
for a in args:
- contents = open(a, 'rb').read()
- output.write(contents.replace(b'YACC', b'myyacc.py'))
+ contents = open(a, 'r').read()
+ output.write(contents.replace('YACC', 'myyacc.py'))
output.close()
sys.exit(0)
diff --git a/test/YACC/YACC.py b/test/YACC/YACC.py
index 3fc1f7c..b27c2a7 100644
--- a/test/YACC/YACC.py
+++ b/test/YACC/YACC.py
@@ -53,10 +53,10 @@ env.CFile(target = 'ddd', source = 'ddd.ym')
test.run(arguments = '.', stderr = None)
-test.must_match('aaa.c', "aaa.y\nmyyacc.py\n")
-test.must_match('bbb.c', "bbb.yacc\nmyyacc.py\n")
-test.must_match('ccc.cc', "ccc.yacc\nmyyacc.py\n")
-test.must_match('ddd.m', "ddd.yacc\nmyyacc.py\n")
+test.must_match('aaa.c', "aaa.y" + os.linesep + "myyacc.py" + os.linesep)
+test.must_match('bbb.c', "bbb.yacc" + os.linesep + "myyacc.py" + os.linesep)
+test.must_match('ccc.cc', "ccc.yacc" + os.linesep + "myyacc.py" + os.linesep)
+test.must_match('ddd.m', "ddd.yacc" + os.linesep + "myyacc.py" + os.linesep)
diff --git a/test/YACC/live-check-output-cleaned.py b/test/YACC/live-check-output-cleaned.py
index a6240c9..8329b94 100644
--- a/test/YACC/live-check-output-cleaned.py
+++ b/test/YACC/live-check-output-cleaned.py
@@ -40,7 +40,7 @@ if not yacc:
test.skip_test('No yacc or bison found; skipping test.\n')
test.write('SConstruct', """
-foo = Environment(YACCFLAGS='-v -d')
+foo = Environment(YACCFLAGS='-v -d', tools = ['default', 'yacc'])
foo.CFile(source = 'foo.y')
""" % locals())
diff --git a/test/YACC/live.py b/test/YACC/live.py
index 253a387..35f6c37 100644
--- a/test/YACC/live.py
+++ b/test/YACC/live.py
@@ -29,6 +29,8 @@ Test YACC and YACCFLAGS with a live yacc compiler.
"""
import TestSCons
+import sys
+import os
_exe = TestSCons._exe
_python_ = TestSCons._python_
@@ -40,12 +42,16 @@ yacc = test.where_is('yacc') or test.where_is('bison')
if not yacc:
test.skip_test('No yacc or bison found; skipping test.\n')
+if sys.platform == 'win32':
+ if not test.where_is('gcc'):
+ test.skip_test('No gcc found on windows; skipping test.\n')
+
test.file_fixture('wrapper.py')
test.write('SConstruct', """
-foo = Environment(YACCFLAGS='-d')
+foo = Environment(YACCFLAGS='-d', tools = ['default', 'yacc'])
yacc = foo.Dictionary('YACC')
-bar = Environment(YACC = r'%(_python_)s wrapper.py ' + yacc)
+bar = Environment(YACC = r'%(_python_)s wrapper.py ' + yacc, tools = ['default', 'yacc'])
foo.Program(target = 'foo', source = 'foo.y')
bar.Program(target = 'bar', source = 'bar.y')
foo.Program(target = 'hello', source = ['hello.cpp'])
@@ -60,7 +66,7 @@ extern int yyparse();
int yyerror(char *s);
int yylex();
-int main()
+int main(void)
{
return yyparse();
}
@@ -108,7 +114,7 @@ file_hpp = 'file.hpp'
test.write("hello.cpp", """\
#include "%(file_hpp)s"
-int main()
+int main(void)
{
}
""" % locals())
@@ -152,7 +158,7 @@ test.run(arguments = 'bar' + _exe)
test.up_to_date(arguments = 'bar' + _exe)
-test.must_match(test.workpath('wrapper.out'), "wrapper.py\n")
+test.must_match(test.workpath('wrapper.out'), "wrapper.py" + os.linesep)
test.run(program = test.workpath('bar'), stdin = "b\n", stdout = "bar.y\n")
diff --git a/test/explain/alias-order.py b/test/explain/alias-order.py
index 611c512..bdb8154 100644
--- a/test/explain/alias-order.py
+++ b/test/explain/alias-order.py
@@ -38,7 +38,8 @@ args = '--debug=explain target2.dat'
test.subdir('src')
test.write(['src', 'SConstruct'],"""
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
def action( source, target, env ):
f = open( str(target[0]), 'wb' )
diff --git a/test/explain/basic.py b/test/explain/basic.py
index ec7238e..19fc328 100644
--- a/test/explain/basic.py
+++ b/test/explain/basic.py
@@ -81,6 +81,7 @@ sys.exit(0)
SConstruct_contents = """\
+DefaultEnvironment(tools=[])
import re
include_re = re.compile(r'^include\s+(\S+)$', re.M)
@@ -98,7 +99,7 @@ kscan = Scanner(name = 'kfile',
cat = Builder(action = [[r'%(python)s', r'%(cat_py)s', '$TARGET', '$SOURCES']])
one_cat = Builder( action = [[r'%(python)s', r'%(cat_py)s', '$TARGET', '${SOURCES[0]}']])
-env = Environment()
+env = Environment(tools=[])
env.Append(BUILDERS = {'Cat':cat, 'OneCat':one_cat},
SCANNERS = kscan)
env.PrependENVPath('PATHEXT', '.PY')
diff --git a/test/explain/function-actions.py b/test/explain/function-actions.py
index bd3ad01..076b24e 100644
--- a/test/explain/function-actions.py
+++ b/test/explain/function-actions.py
@@ -38,9 +38,10 @@ test = TestSCons.TestSCons()
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
import shutil
-env = Environment()
+env = Environment(tools=[])
mode = int(ARGUMENTS.get('mode'))
if mode:
def DifferentCopy(target, source, env):
diff --git a/test/explain/get_csig.py b/test/explain/get_csig.py
index 8a0266a..b193797 100644
--- a/test/explain/get_csig.py
+++ b/test/explain/get_csig.py
@@ -39,7 +39,8 @@ test = TestSCons.TestSCons()
args = "--debug=explain"
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
def action( source, target, env ):
target[0].get_csig()
diff --git a/test/explain/save-info.py b/test/explain/save-info.py
index 048ee8d..08255e0 100644
--- a/test/explain/save-info.py
+++ b/test/explain/save-info.py
@@ -69,6 +69,7 @@ sys.exit(0)
""")
test.write(['src', 'SConstruct'], """\
+DefaultEnvironment(tools=[])
import re
include_re = re.compile(r'^include\s+(\S+)$', re.M)
@@ -85,7 +86,7 @@ kscan = Scanner(name = 'kfile',
cat = Builder(action = r'%(_python_)s %(cat_py)s $TARGET $SOURCES')
-env = Environment()
+env = Environment(tools=[])
env.Append(BUILDERS = {'Cat':cat},
SCANNERS = kscan)
diff --git a/test/implicit-cache/DualTargets.py b/test/implicit-cache/DualTargets.py
index 45174ea..8612d1a 100644
--- a/test/implicit-cache/DualTargets.py
+++ b/test/implicit-cache/DualTargets.py
@@ -34,6 +34,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
import os.path
def emitter(target, source, env):
@@ -49,7 +50,7 @@ def source_scan(node, env, path):
return [base + '.lib']
-env = Environment()
+env = Environment(tools=[])
env['BUILDERS']['DualTarget'] = Builder(
action = Action(
[
diff --git a/test/implicit-cache/GetOption.py b/test/implicit-cache/GetOption.py
index 818784a..561c21b 100644
--- a/test/implicit-cache/GetOption.py
+++ b/test/implicit-cache/GetOption.py
@@ -34,6 +34,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
assert not GetOption('implicit_cache')
SetOption('implicit_cache', 1)
assert GetOption('implicit_cache')
@@ -42,6 +43,7 @@ assert GetOption('implicit_cache')
test.run()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
assert GetOption('implicit_cache')
SetOption('implicit_cache', 0)
assert GetOption('implicit_cache')
diff --git a/test/implicit-cache/RemoveImplicitDep.py b/test/implicit-cache/RemoveImplicitDep.py
index 6a9b873..c65dfec 100644
--- a/test/implicit-cache/RemoveImplicitDep.py
+++ b/test/implicit-cache/RemoveImplicitDep.py
@@ -37,11 +37,12 @@ test = TestSCons.TestSCons()
test.subdir(['src'])
SConstruct_contents = """\
+DefaultEnvironment(tools=[])
import SCons.Script
SetOption( 'implicit_cache', 1 )
-env = Environment()
+env = Environment(tools=[])
act = Action([Touch('${TARGETS[0]}'),Touch('${TARGETS[1]}')])
env.Append(BUILDERS = {'BuildMe':Builder(action=act,source_scanner=SCons.Script.SourceFileScanner)} )
diff --git a/test/implicit-cache/SetOption.py b/test/implicit-cache/SetOption.py
index 41a7fb6..f86ad47 100644
--- a/test/implicit-cache/SetOption.py
+++ b/test/implicit-cache/SetOption.py
@@ -36,6 +36,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
SetOption('implicit_cache', 1)
env=Environment(CPPPATH=['i1', 'i2'])
env.Object('foo.c')
diff --git a/test/implicit-cache/basic.py b/test/implicit-cache/basic.py
index a3a6546..b7cd984 100644
--- a/test/implicit-cache/basic.py
+++ b/test/implicit-cache/basic.py
@@ -53,6 +53,7 @@ test = TestSCons.TestSCons()
test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2')
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(CPPPATH = Split('inc2 include'))
obj = env.Object(target='prog', source='subdir/prog.c')
env.Program(target='prog', source=obj)
diff --git a/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py b/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py
index 2c9fd08..3d05fe3 100644
--- a/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py
+++ b/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py
@@ -64,9 +64,11 @@ extra = ''
test.write('generate_build_py.py', generate_build_py_py_contents % locals())
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
generate = Builder(action = r'%(_python_)s $GENERATE $TARGET')
build = Builder(action = r'$BUILD_PY $TARGET $SOURCES')
-env = Environment(BUILDERS = {
+env = Environment(tools=[],
+ BUILDERS = {
'GenerateBuild' : generate,
'BuildFile' : build,
},
diff --git a/test/implicit/asynchronous-modification.py b/test/implicit/asynchronous-modification.py
index fac8ef5..90a6392 100644
--- a/test/implicit/asynchronous-modification.py
+++ b/test/implicit/asynchronous-modification.py
@@ -39,7 +39,8 @@ test = TestSCons.TestSCons()
test.write(['SConstruct'], """\
import SCons.Defaults
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
env['BUILDERS']['C'] = Builder(action = Copy('$TARGET', '$SOURCE'),
source_scanner = SCons.Defaults.CScan)
env['BUILDERS']['Mod'] = Builder(action = r'%(_python_)s mod.py')
diff --git a/test/implicit/changed-node.py b/test/implicit/changed-node.py
index 4f879c0..8b818ba 100644
--- a/test/implicit/changed-node.py
+++ b/test/implicit/changed-node.py
@@ -40,6 +40,7 @@ test.subdir('d',
['d', '3'])
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
SetOption('implicit_cache', 1)
SetOption('max_drift', 1)
diff --git a/test/import.py b/test/import.py
index b6e5a8d..9799850 100644
--- a/test/import.py
+++ b/test/import.py
@@ -63,6 +63,7 @@ platforms = [
for platform in platforms:
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
print("Platform %(platform)s")
env = Environment(platform = '%(platform)s', tools=[])
import SCons.Platform.%(platform)s
@@ -75,6 +76,8 @@ ignore = ('__init__.py',
'386asm.py', 'linkloc.py',
# Directory of common stuff for MSVC and MSVS
'MSCommon',
+ # clang common
+ "clangCommon",
# Sun pkgchk and pkginfo common stuff
'sun_pkg.py',
# RPM utilities
@@ -150,22 +153,24 @@ error_output = {
# An SConstruct for importing Tool names that have illegal characters
# for Python variable names.
indirect_import = """\
+DefaultEnvironment(tools=[])
print("Tool %(tool)s (indirect)")
env = Environment(tools = ['%(tool)s'])
SCons = __import__('SCons.Tool.%(tool)s', globals(), locals(), [])
m = getattr(SCons.Tool, '%(tool)s')
-env = Environment()
+env = Environment(tools=[])
m.generate(env)
"""
# An SConstruct for importing Tool names "normally."
direct_import = """\
+DefaultEnvironment(tools=[])
print("Tool %(tool)s (direct)")
env = Environment(tools = ['%(tool)s'])
import SCons.Tool.%(tool)s
-env = Environment()
+env = Environment(tools=[])
SCons.Tool.%(tool)s.exists(env)
SCons.Tool.%(tool)s.generate(env)
"""
diff --git a/test/long-lines/signature.py b/test/long-lines/signature.py
index ce38bec..af234a3 100644
--- a/test/long-lines/signature.py
+++ b/test/long-lines/signature.py
@@ -54,11 +54,13 @@ fp.write('TIMESTAMP=%s\\n' % args[3])
os.chmod(build_py, 0o755)
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
arg = 'a_long_ignored_argument'
extra_arguments = arg
while len(extra_arguments) <= 1024:
extra_arguments = extra_arguments + ' ' + arg
-env = Environment(FILECOM=[r'%(build_py)s',
+env = Environment(tools=[],
+ FILECOM=[r'%(build_py)s',
'$TARGET', '$SOURCE',
'$FILEFLAG',
'$(', '$TIMESTAMP', '$)',
diff --git a/test/option-f.py b/test/option-f.py
index 21afacb..46e2686 100644
--- a/test/option-f.py
+++ b/test/option-f.py
@@ -97,9 +97,12 @@ test.run(arguments = '-f Build2 -f SConscript .', stdout=expect)
test.run(arguments = '-f no_such_file .',
stdout = test.wrap_stdout("scons: `.' is up to date.\n"),
stderr = None)
-test.fail_test(not test.match_re(test.stderr(), """
-scons: warning: Ignoring missing SConscript 'no_such_file'
-""" + TestSCons.file_expr))
+expect = """
+scons: warning: Calling missing SConscript without error is deprecated.
+Transition by adding must_exist=0 to SConscript calls.
+Missing SConscript 'no_such_file'"""
+stderr = test.stderr()
+test.must_contain_all(test.stderr(), expect)
test.pass_test()
diff --git a/test/option/d.py b/test/option/d.py
index 055769a..36be02b 100644
--- a/test/option/d.py
+++ b/test/option/d.py
@@ -32,7 +32,7 @@ import TestSCons
test = TestSCons.TestSCons()
-test.write('SConstruct', "")
+test.write('SConstruct', "DefaultEnvironment(tools=[])\n")
test.run(arguments = '-d .',
stderr = "Warning: ignoring -d option\n")
@@ -44,6 +44,7 @@ test.pass_test()
test.subdir('subdir')
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment()
env.Program(target = 'aaa', source = 'aaa.c')
env.Program(target = 'bbb', source = 'bbb.c')
diff --git a/test/option/debug-count.py b/test/option/debug-count.py
index b82a434..2b5b745 100644
--- a/test/option/debug-count.py
+++ b/test/option/debug-count.py
@@ -44,6 +44,7 @@ except ImportError:
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def cat(target, source, env):
open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))})
diff --git a/test/option/debug-duplicate.py b/test/option/debug-duplicate.py
index df2723e..8b9810d 100644
--- a/test/option/debug-duplicate.py
+++ b/test/option/debug-duplicate.py
@@ -33,7 +33,8 @@ test = TestSCons.TestSCons()
test.subdir('sub1')
test.write('SConstruct', """\
-env=Environment()
+DefaultEnvironment(tools=[])
+env=Environment(tools=[])
Export('env')
env.SConscript('SConscript', variant_dir='Build')
""")
diff --git a/test/option/debug-findlibs.py b/test/option/debug-findlibs.py
index 9d5c82a..78ecee9 100644
--- a/test/option/debug-findlibs.py
+++ b/test/option/debug-findlibs.py
@@ -42,6 +42,7 @@ ofp.close()
""")
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx',
LIBPATH = ['sub1', 'sub2', '.'],
LIBS = ['iii', 'jjj', 'kkk', 'lll', 'mmm'],
diff --git a/test/option/debug-includes.py b/test/option/debug-includes.py
index 0982a20..e5c8e0a 100644
--- a/test/option/debug-includes.py
+++ b/test/option/debug-includes.py
@@ -34,6 +34,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(OBJSUFFIX = '.obj',
SHOBJSUFFIX = '.shobj',
LIBPREFIX = '',
diff --git a/test/option/debug-memoizer.py b/test/option/debug-memoizer.py
index 222ba67..f65bcb8 100644
--- a/test/option/debug-memoizer.py
+++ b/test/option/debug-memoizer.py
@@ -36,9 +36,10 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def cat(target, source, env):
open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
-env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=Action(cat))})
env.Cat('file.out', 'file.in')
""")
diff --git a/test/option/debug-memory.py b/test/option/debug-memory.py
index c9165ed..6d395d6 100644
--- a/test/option/debug-memory.py
+++ b/test/option/debug-memory.py
@@ -47,9 +47,10 @@ except ImportError:
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def cat(target, source, env):
open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
-env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=Action(cat))})
env.Cat('file.out', 'file.in')
""")
diff --git a/test/option/debug-multiple.py b/test/option/debug-multiple.py
index f121a2c..23af13b 100644
--- a/test/option/debug-multiple.py
+++ b/test/option/debug-multiple.py
@@ -36,6 +36,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def cat(target, source, env):
open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))})
diff --git a/test/option/debug-objects.py b/test/option/debug-objects.py
index 6a919a4..e86684a 100644
--- a/test/option/debug-objects.py
+++ b/test/option/debug-objects.py
@@ -41,9 +41,10 @@ except ImportError:
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def cat(target, source, env):
open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
-env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))})
+env = Environment(tools=[], BUILDERS={'Cat':Builder(action=Action(cat))})
env.Cat('file.out', 'file.in')
""")
diff --git a/test/option/debug-pdb.py b/test/option/debug-pdb.py
index d4d285c..ec303a5 100644
--- a/test/option/debug-pdb.py
+++ b/test/option/debug-pdb.py
@@ -29,7 +29,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
""")
test.run(arguments = "--debug=pdb", stdin = "n\ns\nq\n")
diff --git a/test/option/debug-prepare.py b/test/option/debug-prepare.py
index 350c352..0ed95f9 100644
--- a/test/option/debug-prepare.py
+++ b/test/option/debug-prepare.py
@@ -31,7 +31,8 @@ _python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """\
-env=Environment()
+DefaultEnvironment(tools=[])
+env=Environment(tools=[])
dest=env.Command('foo.out', 'SConstruct',
[Copy('$TARGET', '$SOURCE'),
Copy('${TARGET}.extra', '$SOURCE')])
diff --git a/test/option/debug-presub.py b/test/option/debug-presub.py
index 28eeb83..0b0555a 100644
--- a/test/option/debug-presub.py
+++ b/test/option/debug-presub.py
@@ -37,6 +37,7 @@ sys.exit(0)
""")
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def cat(env, source, target):
target = str(target[0])
f = open(target, "wb")
@@ -47,7 +48,8 @@ FILE = Builder(action="$FILECOM")
TEMP = Builder(action="$TEMPCOM")
LIST = Builder(action="$LISTCOM")
FUNC = Builder(action=cat)
-env = Environment(PYTHON=r'%(_python_)s',
+env = Environment(tools=[],
+ PYTHON=r'%(_python_)s',
BUILDERS = {'FILE':FILE, 'TEMP':TEMP, 'LIST':LIST, 'FUNC':FUNC},
FILECOM="$PYTHON cat.py $SOURCES $TARGET",
TEMPCOM="$PYTHON cat.py $SOURCES temp\\n$PYTHON cat.py temp $TARGET",
diff --git a/test/option/debug-stacktrace.py b/test/option/debug-stacktrace.py
index fcc4c1b..490fecf 100644
--- a/test/option/debug-stacktrace.py
+++ b/test/option/debug-stacktrace.py
@@ -33,6 +33,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
def kfile_scan(node, env, target):
raise Exception("kfile_scan error")
@@ -40,7 +41,7 @@ kscan = Scanner(name = 'kfile',
function = kfile_scan,
skeys = ['.k'])
-env = Environment()
+env = Environment(tools=[])
env.Append(SCANNERS = [kscan])
env.Command('foo', 'foo.k', Copy('$TARGET', '$SOURCE'))
diff --git a/test/option/debug-time.py b/test/option/debug-time.py
index 7dd17fe..987e49f 100644
--- a/test/option/debug-time.py
+++ b/test/option/debug-time.py
@@ -44,7 +44,9 @@ sys.exit(0)
""")
test.write('SConstruct', """
-env = Environment(PYTHON = r'%(_python_)s',
+DefaultEnvironment(tools=[])
+env = Environment(tools=[],
+ PYTHON = r'%(_python_)s',
SLEEP_CAT = r'sleep_cat.py',
CATCOM = '$PYTHON $SLEEP_CAT $SECONDS $TARGET $SOURCES',
SECONDS = ARGUMENTS.get('SLEEP', '0'))
diff --git a/test/option/environment-overrides.py b/test/option/environment-overrides.py
index 8680e2c..fe2ac24 100644
--- a/test/option/environment-overrides.py
+++ b/test/option/environment-overrides.py
@@ -32,7 +32,7 @@ import TestSCons
test = TestSCons.TestSCons()
-test.write('SConstruct', "")
+test.write('SConstruct', "DefaultEnvironment(tools=[])\n")
test.run(arguments = '-e .',
stderr = "Warning: ignoring -e option\n")
diff --git a/test/option/help-options.py b/test/option/help-options.py
index e14eff2..1835a62 100644
--- a/test/option/help-options.py
+++ b/test/option/help-options.py
@@ -34,7 +34,7 @@ import TestSCons
test = TestSCons.TestSCons()
-test.write('SConstruct', "")
+test.write('SConstruct', "DefaultEnvironment(tools=[])\n")
test.run(arguments = '-H')
diff --git a/test/option/md5-chunksize.py b/test/option/md5-chunksize.py
index dbb2615..708143f 100644
--- a/test/option/md5-chunksize.py
+++ b/test/option/md5-chunksize.py
@@ -39,9 +39,10 @@ file.close()
""")
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
SetOption('md5_chunksize', 128)
B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
f1 = env.B(target = 'f1.out', source = 'f1.in')
f2 = env.B(target = 'f2.out', source = 'f2.in')
Requires(f2, f1)
@@ -102,13 +103,14 @@ get_stat(["test.stat"], ["test.big"])
""")
test2.write('SConstruct', """
+DefaultEnvironment(tools=[])
import os
def get_stat(target, source, env):
stat = os.stat(source[0].get_abspath())
dest = open(target[0].get_abspath(),'w')
dest.write(str(stat))
dest.close()
-env = Environment()
+env = Environment(tools=[])
env.Command('test.big', 'SConstruct', 'dd if=/dev/zero of=test.big seek=100 bs=1M count=0 2>/dev/null')
env.AlwaysBuild('test.big')
env.Command('test.stat', 'test.big', Action(get_stat))
diff --git a/test/option/no-print-directory.py b/test/option/no-print-directory.py
index 850a484..2a5857e 100644
--- a/test/option/no-print-directory.py
+++ b/test/option/no-print-directory.py
@@ -32,7 +32,7 @@ import TestSCons
test = TestSCons.TestSCons()
-test.write('SConstruct', "")
+test.write('SConstruct', "DefaultEnvironment(tools=[])\n")
test.run(arguments = '--no-print-directory .',
stderr = "Warning: ignoring --no-print-directory option\n")
diff --git a/test/option/option_profile.py b/test/option/option_profile.py
index cb9d22c..4538e0e 100644
--- a/test/option/option_profile.py
+++ b/test/option/option_profile.py
@@ -48,6 +48,7 @@ except ImportError:
test.skip_test('No pstats module, skipping test.\n')
test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
Command('file.out', 'file.in', Copy("$TARGET", "$SOURCE"))
""")
diff --git a/test/option/print-directory.py b/test/option/print-directory.py
index 96d9d7b..79d81d9 100644
--- a/test/option/print-directory.py
+++ b/test/option/print-directory.py
@@ -32,7 +32,7 @@ import TestSCons
test = TestSCons.TestSCons()
-test.write('SConstruct', "")
+test.write('SConstruct', "DefaultEnvironment(tools=[])\n")
test.run(arguments = '-w .',
stderr = "Warning: ignoring -w option\n")
diff --git a/test/option/repository.py b/test/option/repository.py
index a71e71e..392c421 100644
--- a/test/option/repository.py
+++ b/test/option/repository.py
@@ -37,7 +37,8 @@ test.subdir('repository', 'work1')
repository = test.workpath('repository')
test.write(['repository', 'SConstruct'], """\
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
""")
diff --git a/test/option/srcdir.py b/test/option/srcdir.py
index 0a92f13..15c8f95 100644
--- a/test/option/srcdir.py
+++ b/test/option/srcdir.py
@@ -37,7 +37,8 @@ test.subdir('repository', 'work1')
repository = test.workpath('repository')
test.write(['repository', 'SConstruct'], r"""
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
""")
diff --git a/test/option/stack-size.py b/test/option/stack-size.py
index 3d7a715..febec5a 100644
--- a/test/option/stack-size.py
+++ b/test/option/stack-size.py
@@ -49,8 +49,9 @@ file.close()
test.write(['work1', 'SConstruct'], """
+DefaultEnvironment(tools=[])
B = Builder(action = r'%(_python_)s ../build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
f1 = env.B(target = 'f1.out', source = 'f1.in')
f2 = env.B(target = 'f2.out', source = 'f2.in')
Requires(f2, f1)
diff --git a/test/option/taskmastertrace.py b/test/option/taskmastertrace.py
index c426692..b38645f 100644
--- a/test/option/taskmastertrace.py
+++ b/test/option/taskmastertrace.py
@@ -33,7 +33,8 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
# We name the files 'Tfile' so that they will sort after the SConstruct
# file regardless of whether the test is being run on a case-sensitive
diff --git a/test/option/tree-all.py b/test/option/tree-all.py
index fc0f689..6222ba1 100644
--- a/test/option/tree-all.py
+++ b/test/option/tree-all.py
@@ -39,6 +39,7 @@ LINK = test.detect('LINK')
if LINK is None: LINK = CC
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx')
env.Program('Foo', Split('Foo.c Bar.c'))
""")
diff --git a/test/option/tree-derived.py b/test/option/tree-derived.py
index 8490612..84d30fc 100644
--- a/test/option/tree-derived.py
+++ b/test/option/tree-derived.py
@@ -34,6 +34,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx')
env.Program('foo', Split('foo.c bar.c'))
""")
diff --git a/test/option/tree-lib.py b/test/option/tree-lib.py
index 2dc5fb0..1e6df02 100644
--- a/test/option/tree-lib.py
+++ b/test/option/tree-lib.py
@@ -30,7 +30,7 @@ the dependency on the library. (On earlier versions of the Microsoft
toolchain this wouldn't show up unless the library already existed
on disk.)
-Issue 1363: http://scons.tigris.org/issues/show_bug.cgi?id=1363
+Issue 1363: https://github.com/SCons/scons/issues/1363
"""
import TestSCons
@@ -38,6 +38,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
env = Environment(LIBPREFIX='',
LIBSUFFIX='.lib',
OBJSUFFIX='.obj',
diff --git a/test/option/warn-dependency.py b/test/option/warn-dependency.py
index ca0c2aa..dca3815 100644
--- a/test/option/warn-dependency.py
+++ b/test/option/warn-dependency.py
@@ -34,12 +34,13 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
test.write("SConstruct", """\
+DefaultEnvironment(tools=[])
import SCons.Defaults
def build(target, source, env):
pass
-env=Environment()
+env=Environment(tools=[])
env['BUILDERS']['test'] = Builder(action=build,
source_scanner=SCons.Defaults.ObjSourceScan)
env.test(target='foo', source='foo.c')
diff --git a/test/option/warn-duplicate-environment.py b/test/option/warn-duplicate-environment.py
index 09ced2d..1509e41 100644
--- a/test/option/warn-duplicate-environment.py
+++ b/test/option/warn-duplicate-environment.py
@@ -34,6 +34,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
@@ -44,7 +45,7 @@ if WARN:
SetOption('warn', WARN)
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env2 = env.Clone(DIFFERENT_VARIABLE = 'true')
env.B(target = 'file1.out', source = 'file1a.in')
env2.B(target = 'file1.out', source = 'file1b.in')
diff --git a/test/option/warn-misleading-keywords.py b/test/option/warn-misleading-keywords.py
index 67bc965..ca934e5 100644
--- a/test/option/warn-misleading-keywords.py
+++ b/test/option/warn-misleading-keywords.py
@@ -34,6 +34,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
test.write('SConstruct', """
+DefaultEnvironment(tools=[])
def build(env, target, source):
file = open(str(target[0]), 'wb')
for s in source:
@@ -44,7 +45,7 @@ if WARN:
SetOption('warn', WARN)
B = Builder(action=build, multi=1)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(tools=[], BUILDERS = { 'B' : B })
env.B(targets = 'file3a.out', source = 'file3a.in')
env.B(target = 'file3b.out', sources = 'file3b.in')
""")
diff --git a/test/option/warn-missing-sconscript.py b/test/option/warn-missing-sconscript.py
index 4f1f8bd..f5e697b 100644
--- a/test/option/warn-missing-sconscript.py
+++ b/test/option/warn-missing-sconscript.py
@@ -34,10 +34,11 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
test.write("SConstruct", """\
+DefaultEnvironment(tools=[])
def build(target, source, env):
pass
-env=Environment()
+env=Environment(tools=[])
env['BUILDERS']['test'] = Builder(action=build)
env.test(target='foo', source='foo.c')
WARN = ARGUMENTS.get('WARN')
@@ -51,16 +52,23 @@ test.write("foo.c","""
""")
expect = r"""
-scons: warning: Ignoring missing SConscript 'no_such_file'
+scons: warning: Calling missing SConscript without error is deprecated.
+Transition by adding must_exist=0 to SConscript calls.
+Missing SConscript 'no_such_file'
""" + TestSCons.file_expr
+# this is the old message:
+#expect = r"""
+#scons: warning: Ignoring missing SConscript 'no_such_file'
+"" + TestSCons.file_expr
+
test.run(arguments = '--warn=missing-sconscript .', stderr = expect)
test.run(arguments = '--warn=no-missing-sconscript .', stderr = "")
test.run(arguments = 'WARN=missing-sconscript .', stderr = expect)
-test.run(arguments = 'WARN=no-missing-sconscript .')
+test.run(arguments = 'WARN=no-missing-sconscript .', stderr = "")
test.pass_test()
diff --git a/test/packaging/guess-package-name.py b/test/packaging/guess-package-name.py
index 33c3329..8ba4c9e 100644
--- a/test/packaging/guess-package-name.py
+++ b/test/packaging/guess-package-name.py
@@ -81,9 +81,9 @@ env.Package( NAME = 'libfoo',
source = [ 'src/main.c', 'SConstruct' ] )
""")
-test.run(stderr = None)
+test.run(stderr=None)
-test.must_exist( 'src.tar.gz' )
+test.must_exist('src.tar.gz')
#
# TEST: default package name creation with overridden packager.
@@ -98,9 +98,26 @@ env.Package( NAME = 'libfoo',
source = [ 'src/main.c', 'SConstruct' ] )
""")
-test.run(stderr = None)
+test.run(stderr=None)
-test.must_exist( 'libfoo-1.2.3.tar.bz2' )
+test.must_exist('libfoo-1.2.3.tar.bz2')
+
+#
+# TEST: default package name creation with another packager.
+#
+
+test.write('SConstruct', """
+env=Environment(tools=['default', 'packaging'])
+env.Program( 'src/main.c' )
+env.Package( NAME = 'libfoo',
+ VERSION = '1.2.3',
+ PACKAGETYPE = 'src_tarxz',
+ source = [ 'src/main.c', 'SConstruct' ] )
+""")
+
+test.run(stderr=None)
+
+test.must_exist('libfoo-1.2.3.tar.xz')
test.pass_test()
diff --git a/test/packaging/option--package-type.py b/test/packaging/option--package-type.py
index c8f22ca..7ff8535 100644
--- a/test/packaging/option--package-type.py
+++ b/test/packaging/option--package-type.py
@@ -26,6 +26,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Test the --package-type option.
+
+Side effect: also tests that we can produce a noarch package
+by supplying the ARCHITECTURE tag.
"""
import TestSCons
@@ -63,12 +66,13 @@ env.Package( NAME = 'foo',
X_RPM_INSTALL = r'%(_python_)s %(scons)s --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
DESCRIPTION = 'this should be really long',
source = [ prog ],
- SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz'
+ SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz',
+ ARCHITECTURE = 'noarch'
)
""" % locals())
src_rpm = 'foo-1.2.3-0.src.rpm'
-machine_rpm = 'foo-1.2.3-0.%s.rpm' % SCons.Tool.rpmutils.defaultMachine()
+machine_rpm = 'foo-1.2.3-0.noarch.rpm'
test.run(arguments='package PACKAGETYPE=rpm', stderr = None)
diff --git a/test/packaging/rpm/cleanup.py b/test/packaging/rpm/cleanup.py
index b77dfd1..7483750 100644
--- a/test/packaging/rpm/cleanup.py
+++ b/test/packaging/rpm/cleanup.py
@@ -28,6 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
Assert that files created by the RPM packager will be removed by 'scons -c'.
"""
+import os
import TestSCons
import SCons.Tool.rpmutils
@@ -47,13 +48,8 @@ if not rpm:
rpm_build_root = test.workpath('rpm_build_root')
test.subdir('src')
-
-test.write( [ 'src', 'main.c' ], r"""
-int main( int argc, char* argv[] )
-{
- return 0;
-}
-""")
+mainpath = os.path.join('src', 'main.c')
+test.file_fixture(mainpath, mainpath)
test.write('SConstruct', """
env=Environment(tools=['default', 'packaging'])
diff --git a/test/packaging/rpm/explicit-target.py b/test/packaging/rpm/explicit-target.py
index c383b57..e8fbd39 100644
--- a/test/packaging/rpm/explicit-target.py
+++ b/test/packaging/rpm/explicit-target.py
@@ -28,6 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
Test the ability to create a rpm package from a explicit target name.
"""
+import os
import TestSCons
_python_ = TestSCons._python_
@@ -44,13 +45,8 @@ if not rpm:
rpm_build_root = test.workpath('rpm_build_root')
test.subdir('src')
-
-test.write( [ 'src', 'main.c' ], r"""
-int main( int argc, char* argv[] )
-{
- return 0;
-}
-""")
+mainpath = os.path.join('src', 'main.c')
+test.file_fixture(mainpath, mainpath)
test.write('SConstruct', """
import os
diff --git a/test/packaging/rpm/internationalization.py b/test/packaging/rpm/internationalization.py
index 2ef0dfd..ad77f40 100644
--- a/test/packaging/rpm/internationalization.py
+++ b/test/packaging/rpm/internationalization.py
@@ -33,7 +33,6 @@ These are x-rpm-Group, description, summary and the lang_xx file tag.
import os
import SCons.Tool.rpmutils
-
import TestSCons
_python_ = TestSCons._python_
@@ -52,12 +51,7 @@ rpm_build_root = test.workpath('rpm_build_root')
#
# test INTERNATIONAL PACKAGE META-DATA
#
-test.write( [ 'main.c' ], r"""
-int main( int argc, char* argv[] )
-{
- return 0;
-}
-""")
+test.file_fixture('src/main.c', 'main.c')
test.write('SConstruct', """
# -*- coding: utf-8 -*-
@@ -123,13 +117,8 @@ test.fail_test( out != 'Application/office-hello-this should be really long' )
#
# test INTERNATIONAL PACKAGE TAGS
#
-
-test.write( [ 'main.c' ], r"""
-int main( int argc, char* argv[] )
-{
- return 0;
-}
-""")
+mainpath = os.path.join('src', 'main.c')
+test.file_fixture(mainpath)
test.write( ['man.de'], '' )
test.write( ['man.en'], '' )
diff --git a/test/packaging/rpm/multipackage.py b/test/packaging/rpm/multipackage.py
index ab8734d..fd67a09 100644
--- a/test/packaging/rpm/multipackage.py
+++ b/test/packaging/rpm/multipackage.py
@@ -47,13 +47,8 @@ if not rpm:
rpm_build_root = test.workpath('rpm_build_root')
test.subdir('src')
-
-test.write( [ 'src', 'main.c' ], r"""
-int main( int argc, char* argv[] )
-{
- return 0;
-}
-""")
+mainpath = os.path.join('src', 'main.c')
+test.file_fixture(mainpath, mainpath)
test.write('SConstruct', """
import os
@@ -109,8 +104,10 @@ test.must_exist( machine_rpm2 )
test.must_exist( src_rpm2 )
test.must_not_exist( 'bin/main' )
-test.fail_test( not os.popen('rpm -qpl %s' % machine_rpm).read()=='/bin/main\n')
-test.fail_test( not os.popen('rpm -qpl %s' % src_rpm).read()=='foo-1.2.3.spec\nfoo-1.2.3.tar.gz\n')
+out = os.popen( 'rpm -qpl %s' % machine_rpm).read()
+test.must_contain_all_lines( out, '/bin/main')
+out = os.popen( 'rpm -qpl %s' % src_rpm).read()
+test.fail_test( not out == 'foo-1.2.3.spec\nfoo-1.2.3.tar.gz\n')
test.pass_test()
diff --git a/test/packaging/rpm/package.py b/test/packaging/rpm/package.py
index d8c2785..2ba66b9 100644
--- a/test/packaging/rpm/package.py
+++ b/test/packaging/rpm/package.py
@@ -46,13 +46,8 @@ if not rpm:
rpm_build_root = test.workpath('rpm_build_root')
test.subdir('src')
-
-test.write( [ 'src', 'main.c' ], r"""
-int main( int argc, char* argv[] )
-{
- return 0;
-}
-""")
+mainpath = os.path.join('src', 'main.c')
+test.file_fixture(mainpath, mainpath)
test.write('SConstruct', """
import os
@@ -88,8 +83,10 @@ machine_rpm = 'foo-1.2.3-0.%s.rpm' % SCons.Tool.rpmutils.defaultMachine()
test.must_exist( machine_rpm )
test.must_exist( src_rpm )
test.must_not_exist( 'bin/main' )
-test.fail_test( not os.popen('rpm -qpl %s' % machine_rpm).read()=='/bin/main\n')
-test.fail_test( not os.popen('rpm -qpl %s' % src_rpm).read()=='foo-1.2.3.spec\nfoo-1.2.3.tar.gz\n')
+out = os.popen( 'rpm -qpl %s' % machine_rpm).read()
+test.must_contain_all_lines( out, '/bin/main')
+out = os.popen( 'rpm -qpl %s' % src_rpm).read()
+test.fail_test( not out == 'foo-1.2.3.spec\nfoo-1.2.3.tar.gz\n')
test.pass_test()
diff --git a/test/packaging/rpm/src/main.c b/test/packaging/rpm/src/main.c
new file mode 100644
index 0000000..49e8969
--- /dev/null
+++ b/test/packaging/rpm/src/main.c
@@ -0,0 +1,5 @@
+
+int main( int argc, char* argv[] )
+{
+ return 0;
+}
diff --git a/test/packaging/rpm/tagging.py b/test/packaging/rpm/tagging.py
index a558242..b685c91 100644
--- a/test/packaging/rpm/tagging.py
+++ b/test/packaging/rpm/tagging.py
@@ -30,7 +30,6 @@ Test the ability to add file tags
import os
import SCons.Tool.rpmutils
-
import TestSCons
_python_ = TestSCons._python_
@@ -50,13 +49,8 @@ rpm_build_root = test.workpath('rpm_build_root')
# Test adding an attr tag to the built program.
#
test.subdir('src')
-
-test.write( [ 'src', 'main.c' ], r"""
-int main( int argc, char* argv[] )
-{
-return 0;
-}
-""")
+mainpath = os.path.join('src', 'main.c')
+test.file_fixture(mainpath, mainpath)
test.write('SConstruct', """
import os
@@ -91,9 +85,12 @@ src_rpm = 'foo-1.2.3-0.src.rpm'
machine_rpm = 'foo-1.2.3-0.%s.rpm' % SCons.Tool.rpmutils.defaultMachine()
test.must_exist( machine_rpm )
+out = os.popen('rpm -qpl %s' % machine_rpm).read()
+test.must_contain_all_lines( out, '/bin/main')
+
test.must_exist( src_rpm )
-test.fail_test( not os.popen('rpm -qpl %s' % machine_rpm).read()=='/bin/main\n')
-test.fail_test( not os.popen('rpm -qpl %s' % src_rpm).read()=='foo-1.2.3.spec\nfoo-1.2.3.tar.gz\n')
+out = os.popen('rpm -qpl %s' % src_rpm).read()
+test.fail_test( not out == 'foo-1.2.3.spec\nfoo-1.2.3.tar.gz\n')
expect = '(0755, root, users) /bin/main'
test.must_contain_all_lines(test.read('foo-1.2.3.spec',mode='r'), [expect])
diff --git a/test/packaging/strip-install-dir.py b/test/packaging/strip-install-dir.py
index 92f0361..b81a6b4 100644
--- a/test/packaging/strip-install-dir.py
+++ b/test/packaging/strip-install-dir.py
@@ -27,6 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Test stripping the InstallBuilder of the Package source file.
"""
+import os
import TestSCons
@@ -52,10 +53,10 @@ env.Package( NAME = 'foo',
expected = """scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
-Copy file(s): "main.c" to "foo-1.2.3/bin/main.c"
-tar -zc -f foo-1.2.3.tar.gz foo-1.2.3/bin/main.c
+Copy file(s): "main.c" to "foo-1.2.3{os_sep}bin{os_sep}main.c"
+tar -zc -f foo-1.2.3.tar.gz foo-1.2.3{os_sep}bin{os_sep}main.c
scons: done building targets.
-"""
+""".format(os_sep=os.sep)
test.run(arguments='', stderr = None, stdout=expected)
diff --git a/test/packaging/tar/bz2_packaging.py b/test/packaging/tar/bz2_packaging.py
index 1552fd1..2a8b506 100644
--- a/test/packaging/tar/bz2_packaging.py
+++ b/test/packaging/tar/bz2_packaging.py
@@ -36,18 +36,23 @@ python = TestSCons.python
test = TestSCons.TestSCons()
tar = test.detect('TAR', 'tar')
+if not tar:
+ test.skip_test('tar not found, skipping test\n')
-if tar:
- test.subdir('src')
+bz2 = test.where_is('bzip2')
+if not bz2:
+ test.skip_test('tar found, but helper bzip2 not found, skipping test\n')
- test.write( [ 'src', 'main.c' ], r"""
+test.subdir('src')
+
+test.write([ 'src', 'main.c'], r"""
int main( int argc, char* argv[] )
{
return 0;
}
""")
- test.write('SConstruct', """
+test.write('SConstruct', """
Program( 'src/main.c' )
env=Environment(tools=['default', 'packaging'])
env.Package( PACKAGETYPE = 'src_tarbz2',
@@ -56,9 +61,9 @@ env.Package( PACKAGETYPE = 'src_tarbz2',
source = [ 'src/main.c', 'SConstruct' ] )
""")
- test.run(arguments='', stderr = None)
+test.run(arguments='', stderr=None)
- test.must_exist( 'src.tar.bz2' )
+test.must_exist('src.tar.bz2')
test.pass_test()
diff --git a/test/packaging/tar/gz.py b/test/packaging/tar/gz.py
index f841c59..05661b7 100644
--- a/test/packaging/tar/gz.py
+++ b/test/packaging/tar/gz.py
@@ -36,18 +36,19 @@ python = TestSCons.python
test = TestSCons.TestSCons()
tar = test.detect('TAR', 'tar')
+if not tar:
+ test.skip_test('tar not found, skipping test\n')
-if tar:
- test.subdir('src')
+test.subdir('src')
- test.write( [ 'src', 'main.c' ], r"""
+test.write(['src', 'main.c'], r"""
int main( int argc, char* argv[] )
{
return 0;
}
""")
- test.write('SConstruct', """
+test.write('SConstruct', """
Program( 'src/main.c' )
env=Environment(tools=['default', 'packaging'])
env.Package( PACKAGETYPE = 'src_targz',
@@ -56,9 +57,9 @@ env.Package( PACKAGETYPE = 'src_targz',
source = [ 'src/main.c', 'SConstruct' ] )
""")
- test.run(arguments='', stderr = None)
+test.run(arguments='', stderr=None)
- test.must_exist( 'src.tar.gz' )
+test.must_exist('src.tar.gz')
test.pass_test()
diff --git a/test/packaging/tar/xz_packaging.py b/test/packaging/tar/xz_packaging.py
new file mode 100644
index 0000000..194b110
--- /dev/null
+++ b/test/packaging/tar/xz_packaging.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+This tests the SRC xz packager, which does the following:
+ - create a tar package from the specified files
+"""
+
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+tar = test.detect('TAR', 'tar')
+if not tar:
+ test.skip_test('tar not found, skipping test\n')
+
+xz = test.where_is('xz')
+if not xz:
+ test.skip_test('tar found, but helper xz not found, skipping test\n')
+
+test.subdir('src')
+
+test.write([ 'src', 'main.c'], r"""
+int main( int argc, char* argv[] )
+{
+ return 0;
+}
+""")
+
+test.write('SConstruct', """
+Program( 'src/main.c' )
+env=Environment(tools=['default', 'packaging'])
+env.Package( PACKAGETYPE = 'src_tarxz',
+ target = 'src.tar.xz',
+ PACKAGEROOT = 'test',
+ source = [ 'src/main.c', 'SConstruct' ] )
+""")
+
+test.run(arguments='', stderr=None)
+
+test.must_exist('src.tar.xz')
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/update-release-info/update-release-info.py b/test/update-release-info/update-release-info.py
index 970bcce..d0242a8 100644
--- a/test/update-release-info/update-release-info.py
+++ b/test/update-release-info/update-release-info.py
@@ -34,7 +34,7 @@ import TestRuntest
# Needed to ensure we're using the correct year
this_year=time.localtime()[0]
-TestSCons = 'QMTest/TestSCons.py' .split('/')
+TestSCons = 'testing/framework/TestSCons.py' .split('/')
README = 'README.rst' .split('/')
ReleaseConfig = 'ReleaseConfig' .split('/')
SConstruct = 'SConstruct' .split('/')
diff --git a/testing/buildbot.yml b/testing/buildbot.yml
index 81c2143..7e6bb1a 100644
--- a/testing/buildbot.yml
+++ b/testing/buildbot.yml
@@ -9,7 +9,7 @@
# ansible-playbook -i hosts buildbot.yml -e 'botuser=sconsy'
#
# Tested with Ansible 1.5.0, based on
-# http://scons.org/wiki/InstallingBuildbotSlaves
+# https://github.com/SCons/scons/wiki/InstallingBuildbotSlaves
# Send questions to:
#
# anatoly techtonik <techtonik@gmail.com>
diff --git a/testing/framework/.TestCommonTests.py.swp b/testing/framework/.TestCommonTests.py.swp
new file mode 100644
index 0000000..fcee08e
--- /dev/null
+++ b/testing/framework/.TestCommonTests.py.swp
Binary files differ
diff --git a/QMTest/README.txt b/testing/framework/README.txt
index 7750bc7..7750bc7 100644
--- a/QMTest/README.txt
+++ b/testing/framework/README.txt
diff --git a/QMTest/SConscript b/testing/framework/SConscript
index 1db7301..0d3832e 100644
--- a/QMTest/SConscript
+++ b/testing/framework/SConscript
@@ -50,9 +50,9 @@ def copy(target, source, env):
for file in files:
# Guarantee that real copies of these files always exist in
- # build/QMTest. If there's a symlink there, then this is an Aegis
+ # build/testing/framework. If there's a symlink there, then this is an Aegis
# build and we blow them away now so that they'll get "built" later.
- p = os.path.join(build_dir, 'QMTest', file)
+ p = os.path.join(build_dir, 'testing','framework', file)
if os.path.islink(p):
os.unlink(p)
if not os.path.isabs(p):
diff --git a/QMTest/TestCmd.py b/testing/framework/TestCmd.py
index 0aab9a8..9499ff4 100644
--- a/QMTest/TestCmd.py
+++ b/testing/framework/TestCmd.py
@@ -309,7 +309,7 @@ import types
IS_PY3 = sys.version_info[0] == 3
IS_WINDOWS = sys.platform == 'win32'
-
+IS_64_BIT = sys.maxsize > 2**32
class null(object):
pass
@@ -1247,9 +1247,11 @@ class TestCmd(object):
if mode[0] != 'r':
raise ValueError("mode must begin with 'r'")
if IS_PY3 and 'b' not in mode:
- return open(file, mode, newline=newline).read()
+ with open(file, mode, newline=newline) as f:
+ return f.read()
else:
- return open(file, mode).read()
+ with open(file, mode) as f:
+ return f.read()
def rmdir(self, dir):
"""Removes the specified dir name.
diff --git a/QMTest/TestCmdTests.py b/testing/framework/TestCmdTests.py
index b9226fd..b9226fd 100644
--- a/QMTest/TestCmdTests.py
+++ b/testing/framework/TestCmdTests.py
diff --git a/QMTest/TestCommon.py b/testing/framework/TestCommon.py
index 47a149b..6b4b0bd 100644
--- a/QMTest/TestCommon.py
+++ b/testing/framework/TestCommon.py
@@ -206,6 +206,28 @@ def separate_files(flist):
missing.append(f)
return existing, missing
+def contains(seq, subseq, find):
+ # Returns True or False.
+ if find is None:
+ return subseq in seq
+ else:
+ f = find(seq, subseq)
+ return f not in (None, -1) and f is not False
+
+def find_index(seq, subseq, find):
+ # Returns either an index of the subseq within the seq, or None.
+ # Accepts a function find(seq, subseq), which returns an integer on success
+ # and either: None, False, or -1, on failure.
+ if find is None:
+ try:
+ return seq.index(subseq)
+ except ValueError:
+ return None
+ else:
+ i = find(seq, subseq)
+ return None if (i in (None, -1) or i is False) else i
+
+
if os.name == 'posix':
def _failed(self, status = 0):
if self.status is None or status is None:
@@ -265,24 +287,35 @@ class TestCommon(TestCmd):
print("Unwritable files: `%s'" % "', `".join(unwritable))
self.fail_test(missing + unwritable)
- def must_contain(self, file, required, mode = 'rb', find = None):
- """Ensures that the specified file contains the required text.
+ def must_contain(self, file, required, mode='rb', find=None):
+ """Ensures specified file contains the required text.
+
+ Args:
+ file (string): name of file to search in.
+ required (string): text to search for. For the default
+ find function, type must match the return type from
+ reading the file; current implementation will convert.
+ mode (string): file open mode.
+ find (func): optional custom search routine. Must take the
+ form "find(output, line)" non-negative integer on success
+ and None, False, or -1, on failure.
+
+ Calling test exits FAILED if search result is false
"""
+ if 'b' in mode:
+ # Python 3: reading a file in binary mode returns a
+ # bytes object. We cannot find the index of a different
+ # (str) type in that, so convert.
+ required = to_bytes(required)
file_contents = self.read(file, mode)
- if find is None:
- def find(o, l):
- try:
- return o.index(l)
- except ValueError:
- return None
- contains = find(file_contents, required)
- if not contains:
+
+ if not contains(file_contents, required, find):
print("File `%s' does not contain required string." % file)
print(self.banner('Required string '))
print(required)
print(self.banner('%s contents ' % file))
print(file_contents)
- self.fail_test(not contains)
+ self.fail_test()
def must_contain_all(self, output, input, title=None, find=None):
"""Ensures that the specified output string (first argument)
@@ -292,20 +325,13 @@ class TestCommon(TestCmd):
of output being searched, and only shows up in failure output.
An optional fourth argument can be used to supply a different
- function, of the form "find(line, output), to use when searching
+ function, of the form "find(output, line)", to use when searching
for lines in the output.
"""
- if find is None:
- def find(o, i):
- try:
- return o.index(i)
- except ValueError:
- return None
-
if is_List(output):
output = os.newline.join(output)
- if find(output, input) is None:
+ if not contains(output, input, find):
if title is None:
title = 'output'
print('Missing expected input from {}:'.format(title))
@@ -322,21 +348,15 @@ class TestCommon(TestCmd):
of output being searched, and only shows up in failure output.
An optional fourth argument can be used to supply a different
- function, of the form "find(line, output), to use when searching
+ function, of the form "find(output, line)", to use when searching
for lines in the output.
"""
- if find is None:
- def find(o, l):
- try:
- return o.index(l)
- except ValueError:
- return None
missing = []
if is_List(output):
output = '\n'.join(output)
for line in lines:
- if find(output, line) is None:
+ if not contains(output, line, find):
missing.append(line)
if missing:
@@ -357,17 +377,11 @@ class TestCommon(TestCmd):
of output being searched, and only shows up in failure output.
An optional fourth argument can be used to supply a different
- function, of the form "find(line, output), to use when searching
+ function, of the form "find(output, line)", to use when searching
for lines in the output.
"""
- if find is None:
- def find(o, l):
- try:
- return o.index(l)
- except ValueError:
- return None
for line in lines:
- if find(output, line) is not None:
+ if contains(output, line, find):
return
if title is None:
@@ -388,7 +402,7 @@ class TestCommon(TestCmd):
of output being searched, and only shows up in failure output.
An optional fourth argument can be used to supply a different
- function, of the form "find(line, output), to use when searching
+ function, of the form "find(output, line)", to use when searching
for lines in the output. The function must return the index
of the found line in the output, or None if the line is not found.
"""
@@ -400,19 +414,13 @@ class TestCommon(TestCmd):
if sorted(out) == sorted(exp):
# early out for exact match
return
- if find is None:
- def find(o, l):
- try:
- return o.index(l)
- except ValueError:
- return None
missing = []
for line in exp:
- found = find(out, line)
- if found is None:
+ i = find_index(out, line, find)
+ if i is None:
missing.append(line)
else:
- out.pop(found)
+ out.pop(i)
if not missing and not out:
# all lines were matched
@@ -491,20 +499,14 @@ class TestCommon(TestCmd):
"""Ensures that the specified file doesn't contain the banned text.
"""
file_contents = self.read(file, mode)
- if find is None:
- def find(o, l):
- try:
- return o.index(l)
- except ValueError:
- return None
- contains = find(file_contents, banned)
- if contains:
+
+ if contains(file_contents, banned, find):
print("File `%s' contains banned string." % file)
print(self.banner('Banned string '))
print(banned)
print(self.banner('%s contents ' % file))
print(file_contents)
- self.fail_test(contains)
+ self.fail_test()
def must_not_contain_any_line(self, output, lines, title=None, find=None):
"""Ensures that the specified output string (first argument)
@@ -514,18 +516,12 @@ class TestCommon(TestCmd):
of output being searched, and only shows up in failure output.
An optional fourth argument can be used to supply a different
- function, of the form "find(line, output), to use when searching
+ function, of the form "find(output, line)", to use when searching
for lines in the output.
"""
- if find is None:
- def find(o, l):
- try:
- return o.index(l)
- except ValueError:
- return None
unexpected = []
for line in lines:
- if find(output, line) is not None:
+ if contains(output, line, find):
unexpected.append(line)
if unexpected:
diff --git a/QMTest/TestCommonTests.py b/testing/framework/TestCommonTests.py
index 7949cb8..c54f33f 100644
--- a/QMTest/TestCommonTests.py
+++ b/testing/framework/TestCommonTests.py
@@ -306,6 +306,23 @@ class must_contain_TestCase(TestCommonTestCase):
stderr = run_env.stderr()
assert stderr == "PASSED\n", stderr
+ def test_success_index_0(self):
+ """Test must_contain(): success at index 0"""
+ run_env = self.run_env
+
+ script = lstrip("""\
+ from TestCommon import TestCommon
+ tc = TestCommon(workdir='')
+ tc.write('file1', "file1 contents\\n")
+ tc.must_contain('file1', "file1 c")
+ tc.pass_test()
+ """)
+ run_env.run(program=sys.executable, stdin=script)
+ stdout = run_env.stdout()
+ assert stdout == "", stdout
+ stderr = run_env.stderr()
+ assert stderr == "PASSED\n", stderr
+
def test_file_missing(self):
"""Test must_contain(): file missing"""
run_env = self.run_env
@@ -1145,6 +1162,9 @@ class must_match_TestCase(TestCommonTestCase):
""")
expect = lstrip("""\
+ match_re: mismatch at line 0:
+ search re='^file1$'
+ line='file1 does not match'
Unexpected contents of `file1'
contents =======================================================================
1c1
@@ -1324,6 +1344,31 @@ class must_not_contain_TestCase(TestCommonTestCase):
stderr = run_env.stderr()
assert stderr.find("FAILED") != -1, stderr
+ def test_failure_index_0(self):
+ """Test must_not_contain(): failure at index 0"""
+ run_env = self.run_env
+
+ script = lstrip("""\
+ from TestCommon import TestCommon
+ tc = TestCommon(workdir='')
+ tc.write('file1', "file1 does contain contents\\n")
+ tc.must_not_contain('file1', "file1 does")
+ tc.run()
+ """)
+ expect = lstrip("""\
+ File `file1' contains banned string.
+ Banned string ==================================================================
+ file1 does
+ file1 contents =================================================================
+ file1 does contain contents
+
+ """)
+ run_env.run(program=sys.executable, stdin=script)
+ stdout = run_env.stdout()
+ assert stdout == expect, repr(stdout)
+ stderr = run_env.stderr()
+ assert stderr.find("FAILED") != -1, stderr
+
def test_mode(self):
"""Test must_not_contain(): mode"""
run_env = self.run_env
@@ -1812,6 +1857,7 @@ class run_TestCase(TestCommonTestCase):
""")
expect_stdout = lstrip("""\
+ match_re: expected 1 lines, found 2
STDOUT =========================================================================
STDERR =========================================================================
@@ -2024,6 +2070,9 @@ class run_TestCase(TestCommonTestCase):
""")
expect_stdout = lstrip("""\
+ match_re: mismatch at line 0:
+ search re='^Not found$'
+ line='%(pass_script)s: STDOUT: []'
STDOUT =========================================================================
1c1
< Not found
@@ -2053,6 +2102,9 @@ class run_TestCase(TestCommonTestCase):
""")
expect_stdout = lstrip("""\
+ match_re: mismatch at line 0:
+ search re='^Not found$'
+ line='%(stderr_script)s: STDERR: []'
STDOUT =========================================================================
STDERR =========================================================================
@@ -2286,14 +2338,14 @@ class variables_TestCase(TestCommonTestCase):
'dll_suffix',
]
- script = "from __future__ import print_function" + \
+ script = "from __future__ import print_function\n" + \
"import TestCommon\n" + \
'\n'.join([ "print(TestCommon.%s)\n" % v for v in variables ])
run_env.run(program=sys.executable, stdin=script)
stderr = run_env.stderr()
assert stderr == "", stderr
- script = "from __future__ import print_function" + \
+ script = "from __future__ import print_function\n" + \
"from TestCommon import *\n" + \
'\n'.join([ "print(%s)" % v for v in variables ])
run_env.run(program=sys.executable, stdin=script)
diff --git a/QMTest/TestLiteral.py b/testing/framework/TestLiteral.py
index 4004c3a..4004c3a 100644
--- a/QMTest/TestLiteral.py
+++ b/testing/framework/TestLiteral.py
diff --git a/QMTest/TestRuntest.py b/testing/framework/TestRuntest.py
index 68563da..7b3bb52 100644
--- a/QMTest/TestRuntest.py
+++ b/testing/framework/TestRuntest.py
@@ -97,7 +97,7 @@ class TestRuntest(TestCommon):
The superclass TestCommon.__init__() will change directory (chdir)
to the workspace directory, so an explicit "chdir = '.'" on all
of the run() method calls is not necessary. This initialization
- also copies the runtest.py and QMTest/ subdirectory tree to the
+ also copies the runtest.py and testing/framework/ subdirectory tree to the
temporary directory, duplicating how this test infrastructure
appears in a normal workspace.
"""
@@ -115,7 +115,7 @@ class TestRuntest(TestCommon):
except KeyError:
things_to_copy = [
'runtest.py',
- 'QMTest',
+ 'testing/framework',
]
else:
del kw['things_to_copy']
diff --git a/QMTest/TestSCons.py b/testing/framework/TestSCons.py
index ef907d8..bf6aabb 100644
--- a/QMTest/TestSCons.py
+++ b/testing/framework/TestSCons.py
@@ -42,7 +42,7 @@ python_version_deprecated = (2, 7, 0)
# In the checked-in source, the value of SConsVersion in the following
# line must remain "__ VERSION __" (without the spaces) so the built
-# version in build/QMTest/TestSCons.py contains the actual version
+# version in build/testing/framework/TestSCons.py contains the actual version
# string of the packages that have been built.
SConsVersion = '__VERSION__'
if SConsVersion == '__' + 'VERSION' + '__':
@@ -564,7 +564,7 @@ class TestSCons(TestCommon):
Returns a Python error line for output comparisons.
The exec of the traceback line gives us the correct format for
- this version of Python.
+ this version of Python.
File "<string>", line 1, <module>
@@ -607,7 +607,7 @@ class TestSCons(TestCommon):
pattern = to_bytes(pattern)
repl = to_bytes(repl)
return re.sub(pattern, repl, str, count, flags)
-
+
def normalize_pdf(self, s):
s = self.to_bytes_re_sub(r'/(Creation|Mod)Date \(D:[^)]*\)',
r'/\1Date (D:XXXX)', s)
@@ -692,20 +692,29 @@ class TestSCons(TestCommon):
env = SCons.Environment.Environment()
self._java_env[version] = env
-
if version:
- patterns = [
- '/usr/java/jdk%s*/bin' % version,
- '/usr/lib/jvm/*-%s*/bin' % version,
- '/usr/local/j2sdk%s*/bin' % version,
- ]
+ if sys.platform == 'win32':
+ patterns = [
+ 'C:/Program Files*/Java/jdk%s*/bin'%version,
+ ]
+ else:
+ patterns = [
+ '/usr/java/jdk%s*/bin' % version,
+ '/usr/lib/jvm/*-%s*/bin' % version,
+ '/usr/local/j2sdk%s*/bin' % version,
+ ]
java_path = self.paths(patterns) + [env['ENV']['PATH']]
else:
- patterns = [
- '/usr/java/latest/bin',
- '/usr/lib/jvm/*/bin',
- '/usr/local/j2sdk*/bin',
- ]
+ if sys.platform == 'win32':
+ patterns = [
+ 'C:/Program Files*/Java/jdk*/bin',
+ ]
+ else:
+ patterns = [
+ '/usr/java/latest/bin',
+ '/usr/lib/jvm/*/bin',
+ '/usr/local/j2sdk*/bin',
+ ]
java_path = self.paths(patterns) + [env['ENV']['PATH']]
env['ENV']['PATH'] = os.pathsep.join(java_path)
@@ -802,7 +811,7 @@ class TestSCons(TestCommon):
where_jar = self.where_is('jar', ENV['PATH'])
if not where_jar:
self.skip_test("Could not find Java jar, skipping test(s).\n")
- elif sys.platform == "darwin":
+ elif sys.platform == "darwin":
self.java_mac_check(where_jar, 'jar')
return where_jar
@@ -876,7 +885,7 @@ class TestSCons(TestCommon):
self.skip_test("Could not find Java rmic, skipping non-simulated test(s).\n")
return where_rmic
-
+
def java_get_class_files(self, dir):
result = []
for dirpath, dirnames, filenames in os.walk(dir):
@@ -1069,7 +1078,7 @@ SConscript( sconscript )
doCheckLog=True, doCheckStdout=True):
"""
Used to verify the expected output from using Configure()
- via the contents of one or both of stdout or config.log file.
+ via the contents of one or both of stdout or config.log file.
The checks, results, cached parameters all are zipped together
for use in comparing results.
@@ -1151,19 +1160,19 @@ SConscript( sconscript )
sconstruct = sconstruct
log = r'file\ \S*%s\,line \d+:' % re.escape(sconstruct) + ls
- if doCheckLog:
+ if doCheckLog:
lastEnd = matchPart(log, logfile, lastEnd)
log = "\t" + re.escape("Configure(confdir = %s)" % sconf_dir) + ls
- if doCheckLog:
+ if doCheckLog:
lastEnd = matchPart(log, logfile, lastEnd)
-
+
rdstr = ""
cnt = 0
for check,result,cache_desc in zip(checks, results, cached):
log = re.escape("scons: Configure: " + check) + ls
- if doCheckLog:
+ if doCheckLog:
lastEnd = matchPart(log, logfile, lastEnd)
log = ""
@@ -1208,7 +1217,7 @@ SConscript( sconscript )
rdstr = rdstr + re.escape(check) + re.escape(result) + "\n"
log=log + re.escape("scons: Configure: " + result) + ls + ls
- if doCheckLog:
+ if doCheckLog:
lastEnd = matchPart(log, logfile, lastEnd)
log = ""
@@ -1247,41 +1256,74 @@ SConscript( sconscript )
# see also sys.prefix documentation
return python_minor_version_string()
- def get_platform_python_info(self):
+ def get_platform_python_info(self, python_h_required=False):
"""
Returns a path to a Python executable suitable for testing on
- this platform and its associated include path, library path,
- and library name.
+ this platform and its associated include path, library path and
+ library name.
+
+ If the Python executable or Python header (if required)
+ is not found, the test is skipped.
+
+ Returns a tuple:
+ (path to python, include path, library path, library name)
"""
- python = self.where_is('python')
+ python = os.environ.get('python_executable', self.where_is('python'))
if not python:
self.skip_test('Can not find installed "python", skipping test.\n')
- self.run(program = python, stdin = """\
-import os, sys
+ # construct a program to run in the intended environment
+ # in order to fetch the characteristics of that Python.
+ # Windows Python doesn't store all the info in config vars.
+ if sys.platform == 'win32':
+ self.run(program=python, stdin="""\
+import sysconfig, sys, os.path
try:
- if sys.platform == 'win32':
py_ver = 'python%d%d' % sys.version_info[:2]
- else:
- py_ver = 'python%d.%d' % sys.version_info[:2]
except AttributeError:
py_ver = 'python' + sys.version[:3]
# print include and lib path
try:
import distutils.sysconfig
exec_prefix = distutils.sysconfig.EXEC_PREFIX
- print(distutils.sysconfig.get_python_inc())
+ include = distutils.sysconfig.get_python_inc()
+ print(include)
lib_path = os.path.join(exec_prefix, 'libs')
if not os.path.exists(lib_path):
lib_path = os.path.join(exec_prefix, 'lib')
print(lib_path)
except:
- print(os.path.join(sys.prefix, 'include', py_ver))
+ include = os.path.join(sys.prefix, 'include', py_ver)
+ print(include)
print(os.path.join(sys.prefix, 'lib', py_ver, 'config'))
print(py_ver)
+Python_h = os.path.join(include, "Python.h")
+if os.path.exists(Python_h):
+ print(Python_h)
+else:
+ print("False")
+""")
+ else:
+ self.run(program=python, stdin="""\
+import sys, sysconfig, os.path
+include = sysconfig.get_config_var("INCLUDEPY")
+print(include)
+print(sysconfig.get_config_var("LIBDIR"))
+py_library_ver = sysconfig.get_config_var("LDVERSION")
+if not py_library_ver:
+ py_library_ver = '%d.%d' % sys.version_info[:2]
+print("python"+py_library_ver)
+Python_h = os.path.join(include, "Python.h")
+if os.path.exists(Python_h):
+ print(Python_h)
+else:
+ print("False")
""")
+ incpath, libpath, libname, python_h = self.stdout().strip().split('\n')
+ if python_h == "False" and python_h_required:
+ self.skip_test('Can not find required "Python.h", skipping test.\n')
- return [python] + self.stdout().strip().split('\n')
+ return (python, incpath, libpath, libname)
def start(self, *args, **kw):
"""
diff --git a/QMTest/TestSConsMSVS.py b/testing/framework/TestSConsMSVS.py
index 1e879d9..1e879d9 100644
--- a/QMTest/TestSConsMSVS.py
+++ b/testing/framework/TestSConsMSVS.py
diff --git a/QMTest/TestSCons_time.py b/testing/framework/TestSCons_time.py
index bc116ec..bc116ec 100644
--- a/QMTest/TestSCons_time.py
+++ b/testing/framework/TestSCons_time.py
diff --git a/QMTest/TestSConsign.py b/testing/framework/TestSConsign.py
index a48b648..a48b648 100644
--- a/QMTest/TestSConsign.py
+++ b/testing/framework/TestSConsign.py
diff --git a/QMTest/__init__.py b/testing/framework/__init__.py
index e69de29..e69de29 100644
--- a/QMTest/__init__.py
+++ b/testing/framework/__init__.py
diff --git a/testing/framework/test-framework.rst b/testing/framework/test-framework.rst
new file mode 100644
index 0000000..cb6b8e1
--- /dev/null
+++ b/testing/framework/test-framework.rst
@@ -0,0 +1,523 @@
+=======================
+SCons Testing Framework
+=======================
+
+SCons uses extensive automated tests to ensure quality. The primary goal
+is that users be able to upgrade from version to version without
+any surprise changes in behavior.
+
+In general, no change goes into SCons unless it has one or more new
+or modified tests that demonstrably exercise the bug being fixed or
+the feature being added. There are exceptions to this guideline, but
+they should be just that, ''exceptions''. When in doubt, make sure
+it's tested.
+
+Test Organization
+=================
+
+There are three types of SCons tests:
+
+*End-to-End Tests*
+ End-to-end tests of SCons are Python scripts (``*.py``) underneath the
+ ``test/`` subdirectory. They use the test infrastructure modules in
+ the ``testing/framework`` subdirectory. They build set up complete
+ projects and call scons to execute them, checking that the behavior is
+ as expected.
+
+*Unit Tests*
+ Unit tests for individual SCons modules live underneath the
+ ``src/engine/`` subdirectory and are the same base name as the module
+ to be tests, with ``Tests`` appended before the ``.py``. For example,
+ the unit tests for the ``Builder.py`` module are in the
+ ``BuilderTests.py`` script. Unit tests tend to be based on assertions.
+
+*External Tests*
+ For the support of external Tools (in the form of packages, preferably),
+ the testing framework is extended so it can run in standalone mode.
+ You can start it from the top-level folder of your Tool's source tree,
+ where it then finds all Python scripts (``*.py``) underneath the local
+ ``test/`` directory. This implies that Tool tests have to be kept in
+ a folder named ``test``, like for the SCons core.
+
+
+Contrasting End-to-End and Unit Tests
+#####################################
+
+In general, functionality with end-to-end tests
+should be considered a hardened part of the public interface (that is,
+something that a user might do) and should not be broken. Unit tests
+are now considered more malleable, more for testing internal interfaces
+that can change so long as we don't break users' ``SConscript`` files.
+(This wasn't always the case, and there's a lot of meaty code in many
+of the unit test scripts that does, in fact, capture external interface
+behavior. In general, we should try to move those things to end-to-end
+scripts as we find them.)
+
+End-to-end tests are by their nature harder to debug.
+You can drop straight into the Python debugger on the unit test
+scripts by using the ``runtest.py --pdb`` option, but the end-to-end
+tests treat an SCons invocation as a "black box" and just look for
+external effects; simple methods like inserting ``print`` statements
+in the SCons code itself can disrupt those external effects.
+See `Debugging End-to-End Tests`_ for some more thoughts.
+
+Naming Conventions
+##################
+
+The end-to-end tests, more or less, stick to the following naming
+conventions:
+
+#. All tests end with a .py suffix.
+
+#. In the *General* form we use
+
+ ``Feature.py``
+ for the test of a specified feature; try to keep this description
+ reasonably short
+
+ ``Feature-x.py``
+ for the test of a specified feature using option ``x``
+#. The *command line option* tests take the form
+
+ ``option-x.py``
+ for a lower-case single-letter option
+
+ ``option--X.py``
+ upper-case single-letter option (with an extra hyphen, so the
+ file names will be unique on case-insensitive systems)
+
+ ``option--lo.py``
+ long option; abbreviate the long option name to a few characters
+
+
+Running Tests
+=============
+
+The standard set of SCons tests are run from the top-level source
+directory by the ``runtest.py`` script.
+
+Help is available through the ``-h`` option::
+
+ $ python runtest.py -h
+
+To simply run all the tests, use the ``-a`` option::
+
+ $ python runtest.py -a
+
+By default, ``runtest.py`` prints a count and percentage message for each
+test case, along with the name of the test file. If you need the output
+to be more silent, have a look at the ``-q``, ``-s`` and ``-k`` options.
+
+You may specifically list one or more tests to be run::
+
+ $ python runtest.py src/engine/SCons/BuilderTests.py
+ $ python runtest.py test/option-j.py test/Program.py
+
+Folder names are allowed arguments as well, so you can do::
+
+ $ python runtest.py test/SWIG
+
+to run all SWIG tests only.
+
+You can also use the ``-f`` option to execute just the tests listed in
+a specified text file::
+
+ $ cat testlist.txt
+ test/option-j.py
+ test/Program.py
+ $ python runtest.py -f testlist.txt
+
+One test must be listed per line, and any lines that begin with '#'
+will be ignored (the intent being to allow you, for example, to comment
+out tests that are currently passing and then uncomment all of the tests
+in the file for a final validation run).
+
+If more than one test is run, the ``runtest.py`` script prints a summary
+of how many tests passed, failed, or yielded no result, and lists any
+unsuccessful tests.
+
+The above invocations all test directly the files underneath the ``src/``
+subdirectory, and do not require that a packaging build be performed
+first. The ``runtest.py`` script supports additional options to run
+tests against unpacked packages in the ``build/test-*/`` subdirectories.
+
+If you are testing a separate Tool outside of the SCons source tree, you
+have to call the ``runtest.py`` script in *external* (stand-alone) mode::
+
+ $ python ~/scons/runtest.py -e -a
+
+This ensures that the testing framework doesn't try to access SCons
+classes needed for some of the *internal* test cases.
+
+Note, that the actual tests are carried out in a temporary folder each,
+which gets deleted afterwards. This ensures that your source directories
+don't get clobbered with temporary files from the test runs. It also
+means that you can't simply change into a folder to "debug things" after
+a test has gone wrong. For a way around this, check out the ``PRESERVE``
+environment variable. It can be seen in action in
+`How to convert old tests`_ below.
+
+Not Running Tests
+=================
+
+If you simply want to check which tests would get executed, you can call
+the ``runtest.py`` script with the ``-l`` option::
+
+ $ python runtest.py -l
+
+Then there is also the ``-n`` option, which prints the command line for
+each single test, but doesn't actually execute them::
+
+ $ python runtest.py -n
+
+Finding Tests
+=============
+
+When started in *standard* mode::
+
+ $ python runtest.py -a
+
+``runtest.py`` assumes that it is run from the SCons top-level source
+directory. It then dives into the ``src`` and ``test`` folders, where
+it tries to find filenames
+
+``*Test.py``
+ for the ``src`` directory
+
+``*.py``
+ for the ``test`` folder
+
+When using fixtures, you may quickly end up in a position where you have
+supporting Python script files in a subfolder, but they shouldn't get
+picked up as test scripts. In this case you have two options:
+
+#. Add a file with the name ``sconstest.skip`` to your subfolder. This
+ lets ``runtest.py`` skip the contents of the directory completely.
+#. Create a file ``.exclude_tests`` in each folder in question, and in
+ it list line-by-line the files to get excluded from testing.
+
+The same rules apply when testing external Tools by using the ``-e``
+option.
+
+
+Example End-to-End Test Script
+==============================
+
+To illustrate how the end-to-end test scripts work, let's walk through
+a simple "Hello, world!" example::
+
+ #!python
+ import TestSCons
+
+ test = TestSCons.TestSCons()
+
+ test.write('SConstruct', """\
+ Program('hello.c')
+ """)
+
+ test.write('hello.c', """\
+ int
+ main(int argc, char *argv[])
+ {
+ printf("Hello, world!\\n");
+ exit (0);
+ }
+ """)
+
+ test.run()
+
+ test.run(program='./hello', stdout="Hello, world!\n")
+
+ test.pass_test()
+
+
+``import TestSCons``
+ Imports the main infrastructure for writing SCons tests. This is
+ normally the only part of the infrastructure that needs importing.
+ Sometimes other Python modules are necessary or helpful, and get
+ imported before this line.
+
+``test = TestSCons.TestSCons()``
+ This initializes an object for testing. A fair amount happens under
+ the covers when the object is created, including:
+
+ * A temporary directory is created for all the in-line files that will
+ get created.
+
+ * The temporary directory's removal is arranged for when
+ the test is finished.
+
+ * The test does ``os.chdir()`` to the temporary directory.
+
+``test.write('SConstruct', ...)``
+ This line creates an ``SConstruct`` file in the temporary directory,
+ to be used as input to the ``scons`` run(s) that we're testing.
+ Note the use of the Python triple-quote syntax for the contents
+ of the ``SConstruct`` file. Because input files for tests are all
+ created from in-line data like this, the tests can sometimes get
+ a little confusing to read, because some of the Python code is found
+
+``test.write('hello.c', ...)``
+ This lines creates an ``hello.c`` file in the temporary directory.
+ Note that we have to escape the ``\\n`` in the
+ ``"Hello, world!\\n"`` string so that it ends up as a single
+ backslash in the ``hello.c`` file on disk.
+
+``test.run()``
+ This actually runs SCons. Like the object initialization, things
+ happen under the covers:
+
+ * The exit status is verified; the test exits with a failure if
+ the exit status is not zero.
+ * The error output is examined, and the test exits with a failure
+ if there is any.
+
+``test.run(program='./hello', stdout="Hello, world!\n")``
+ This shows use of the ``TestSCons.run()`` method to execute a program
+ other than ``scons``, in this case the ``hello`` program we just
+ presumably built. The ``stdout=`` keyword argument also tells the
+ ``TestSCons.run()`` method to fail if the program output does not
+ match the expected string ``"Hello, world!\n"``. Like the previous
+ ``test.run()`` line, it will also fail the test if the exit status is
+ non-zero, or there is any error output.
+
+``test.pass_test()``
+ This is always the last line in a test script. It prints ``PASSED``
+ on the screen and makes sure we exit with a ``0`` status to indicate
+ the test passed. As a side effect of destroying the ``test`` object,
+ the created temporary directory will be removed.
+
+Working with Fixtures
+=====================
+
+In the simple example above, the files to set up the test are created
+on the fly by the test program. We give a filename to the ``TestSCons.write()``
+method, and a string holding its contents, and it gets written to the test
+folder right before starting..
+
+This technique can still be seen throughout most of the end-to-end tests,
+but there is a better way. To create a test, you need to create the
+files that will be used, then when they work reasonably, they need to
+be pasted into the script. The process repeats for maintenance. Once
+a test gets more complex and/or grows many steps, the test script gets
+harder to read. Why not keep the files as is?
+
+In testing parlance, a fixture is a repeatable test setup. The scons
+test harness allows the use of saved files or directories to be used
+in that sense: "the fixture for this test is foo", instead of writing
+a whole bunch of strings to create files. Since these setups can be
+reusable across multiple tests, the *fixture* terminology applies well.
+
+Directory Fixtures
+##################
+
+The function ``dir_fixture(self, srcdir, dstdir=None)`` in the ``TestCmd``
+class copies the contents of the specified folder ``srcdir`` from
+the directory of the called test script to the current temporary test
+directory. The ``srcdir`` name may be a list, in which case the elements
+are concatenated with the ``os.path.join()`` method. The ``dstdir``
+is assumed to be under the temporary working directory, it gets created
+automatically, if it does not already exist.
+
+A short syntax example::
+
+ test = TestSCons.TestSCons()
+ test.dir_fixture('image')
+ test.run()
+
+would copy all files and subfolders from the local ``image`` folder,
+to the temporary directory for the current test.
+
+To see a real example for this in action, refer to the test named
+``test/packaging/convenience-functions/convenience-functions.py``.
+
+File Fixtures
+#############
+
+Like for directory fixtures, ``file_fixture(self, srcfile, dstfile=None)``
+copies the file ``srcfile`` from the directory of the called script,
+to the temporary test directory. The ``dstfile`` is assumed to be
+under the temporary working directory, unless it is an absolute path
+name. If ``dstfile`` is specified, its target directory gets created
+automatically if it doesn't already exist.
+
+With the following code::
+
+ test = TestSCons.TestSCons()
+ test.file_fixture('SConstruct')
+ test.file_fixture(['src','main.cpp'],['src','main.cpp'])
+ test.run()
+
+The files ``SConstruct`` and ``src/main.cpp`` are copied to the
+temporary test directory. Notice the second ``file_fixture`` line
+preserves the path of the original, otherwise ``main.cpp``
+would have landed in the top level of the test directory.
+
+Again, a reference example can be found in the current revision
+of SCons, it is ``test/packaging/sandbox-test/sandbox-test.py``.
+
+For even more examples you should check out
+one of the external Tools, e.g. the *Qt4* Tool at
+https://bitbucket.org/dirkbaechle/scons_qt4. Also visit the SCons Tools
+Index at https://github.com/SCons/scons/wiki/ToolsIndex for a complete
+list of available Tools, though not all may have tests yet.
+
+How to Convert Old Tests to Use Fixures
+#######################################
+
+Tests using the inline ``TestSCons.write()`` method can easily be
+converted to the fixture based approach. For this, we need to get at the
+files as they are written to each temporary test folder.
+
+``runtest.py`` checks for the existence of an environment
+variable named ``PRESERVE``. If it is set to a non-zero value, the testing
+framework preserves the test folder instead of deleting it, and prints
+its name to the screen.
+
+So, you should be able to give the commands::
+
+ $ PRESERVE=1 python runtest.py test/packaging/sandbox-test.py
+
+assuming Linux and a bash-like shell. For a Windows ``cmd`` shell, use
+``set PRESERVE=1`` (that will leave it set for the duration of the
+``cmd`` session, unless manually deleted).
+
+The output should then look something like this::
+
+ 1/1 (100.00%) /usr/bin/python -tt test/packaging/sandbox-test.py
+ PASSED
+ Preserved directory /tmp/testcmd.4060.twlYNI
+
+You can now copy the files from that folder to your new
+*fixture* folder. Then, in the test script you simply remove all the
+tedious ``TestSCons.write()`` statements and replace them by a single
+``TestSCons.dir_fixture()``.
+
+Finally, don't forget to clean up and remove the temporary test
+directory. ``;)``
+
+When Not to Use a Fixture
+#########################
+
+Note that some files are not appropriate for use in a fixture as-is:
+fixture files should be static. If the creation of the file involves
+interpolating data discovered during the run of the test script,
+that process should stay in the script. Here is an example of this
+kind of usage that does not lend itself to a fixture::
+
+ import TestSCons
+ _python_ = TestSCons._python_
+
+ test.write('SConstruct', """
+ cc = Environment().Dictionary('CC')
+ env = Environment(LINK = r'%(_python_)s mylink.py',
+ LINKFLAGS = [],
+ CC = r'%(_python_)s mycc.py',
+ CXX = cc,
+ CXXFLAGS = [])
+ env.Program(target = 'test1', source = 'test1.c')
+ """ % locals())
+
+Here the value of ``_python_`` is picked out of the script's
+``locals`` dictionary and interpolated into the string that
+will be written to ``SConstruct``.
+
+The other files created in this test may still be candidates for
+use in a fixture, however.
+
+Debugging End-to-End Tests
+==========================
+
+Most of the end to end tests have expectations for standard output
+and error from the test runs. The expectation could be either
+that there is nothing on that stream, or that it will contain
+very specific text which the test matches against. So adding
+``print()`` calls, or ``sys,stderr.write()`` or similar will
+emit data that the tests do not expect, and cause further failures.
+Say you have three different tests in a script, and the third
+one is unexpectedly failing. You add some debug prints to the
+part of scons that is involved, and now the first test of the
+three starts failing, aborting the test run before it gets
+to the third test you were trying to debug.
+
+Still, there are some techniques to help debugging.
+
+Probably the most effective technique is to use the internal
+``SCons.Debug.Trace()`` function, which prints output to
+``/dev/tty`` on Linux/UNIX systems and ``con`` on Windows systems,
+so you can see what's going on.
+
+If you do need to add informational messages in scons code
+to debug a problem, you can use logging and send the messages
+to a file instead, so they don't interrupt the test expectations.
+
+Part of the technique discussed in the section
+`How to Convert Old Tests to Use Fixures`_ can also be helpful
+for debugging purposes. If you have a failing test, try::
+
+ $ PRESERVE=1 python runtest.py test/failing-test.py
+
+You can now go to the save directory reported from this run
+and invoke the test manually to see what it is doing, without
+the presence of the test infrastructure which would otherwise
+"swallow" output you may be interested in. In this case,
+adding debug prints may be more useful.
+
+
+Test Infrastructure
+===================
+
+The main test API in the ``TestSCons.py`` class. ``TestSCons``
+is a subclass of ``TestCommon``, which is a subclass of ``TestCmd``.
+All those classes are defined in python files of the same name
+in ``testing/framework``. Start in
+``testing/framework/TestCmd.py`` for the base API definitions, like how
+to create files (``test.write()``) and run commands (``test.run()``).
+
+Use ``TestSCons`` for the end-to-end tests in ``test``, but use
+``TestCmd`` for the unit tests in the ``src`` folder.
+
+The match functions work like this:
+
+``TestSCons.match_re``
+ match each line with a RE
+
+ * Splits the lines into a list (unless they already are)
+ * splits the REs at newlines (unless already a list) and puts ^..$ around each
+ * then each RE must match each line. This means there must be as many
+ REs as lines.
+
+``TestSCons.match_re_dotall``
+ match all the lines against a single RE
+
+ * Joins the lines with newline (unless already a string)
+ * joins the REs with newline (unless it's a string) and puts ``^..$``
+ around the whole thing
+ * then whole thing must match with python re.DOTALL.
+
+Use them in a test like this::
+
+ test.run(..., match=TestSCons.match_re, ...)
+
+or::
+
+ test.must_match(..., match=TestSCons.match_re, ...)
+
+Avoiding Tests Based on Tool Existence
+======================================
+
+Here's a simple example::
+
+ #!python
+ intelc = test.detect_tool('intelc', prog='icpc')
+ if not intelc:
+ test.skip_test("Could not load 'intelc' Tool; skipping test(s).\n")
+
+See ``testing/framework/TestSCons.py`` for the ``detect_tool`` method.
+It calls the tool's ``generate()`` method, and then looks for the given
+program (tool name by default) in ``env['ENV']['PATH']``.
+
+The ``where_is`` method can be used to look for programs that
+are do not have tool specifications. The existing test code
+will have many samples of using either or both of these to detect
+if it is worth even proceeding with a test.
diff --git a/timings/README.txt b/timings/README.txt
index 3c0baff..9921208 100644
--- a/timings/README.txt
+++ b/timings/README.txt
@@ -5,8 +5,8 @@ This directory contains timing configurations for SCons.
Each configuration exists in a subdirectory. The controlling script
is named TimeSCons-run.py for the configuration. The TimeSCons-run.py
scripts use TestSCons.TimeSCons, a subclass of TestSCons.TestSCons (both
-defined in ../QMTest/TestSCons.py), to manage execution of the timing
-runs.
+defined in ../testing/framework/TestSCons.py), to manage execution of the
+timing runs.
Unlike the TestSCons.TestSCons base class, the TestSCons.TimeSCons
subclass copies the contents of its containing directory to the temporary
diff --git a/www/bug-submission.html b/www/bug-submission.html
deleted file mode 100644
index abc855b..0000000
--- a/www/bug-submission.html
+++ /dev/null
@@ -1,234 +0,0 @@
-<html>
-<head>
-<title>Bug Submission</title>
-</head>
-<body>
-
-<div id="apphead">
-<h1><small>scons</small><br />Bug Submission</h1>
-
-<p>
-<strong>You must now
-<a href="http://www.tigris.org/servlets/Login">log in</a>
-to a <a href="http://www.tigris.org">tigris.org</a> account
-before submitting a new bug report!</strong>
-</p>
-
-<p>
-Bugs should be reported at the
-<a href="http://scons.tigris.org/issues/enter_bug.cgi?component=scons&subcomponent=scons&issue_type=DEFECT">"Enter Issue" page</a>.
-Please follow the <a href="bug-submission.html#guidelines">submission guidelines</a> below
-to make sure your bug report contains the necessary information.
-A more detailed set of <a href="bug-submission.html#steps">submission steps</a>
-can be found below.
-</p>
-
-<p>
-The above URL is set up for reporting a bug in SCons itself.
-If you are reporting a problem in some other aspect of the SCons Project
-(such as the documentation, or any of the web pages),
-you must change the Subcomponent field of the submission form
-to some other appropriate value.
-</p>
-
-</div>
-
-<div class="h2 app" style="border-left: 0px" id="customcontent">
-
-<h2 id="guidelines">Guidelines for a Useful Bug Report</h2>
-
-<p>
-Your bug will be much more likely to get diagnosed and fixed
-if you supply all the necessary information to make it easy to do so.
-</p>
-
-<ul>
-<li>
-<strong>
-<a href="http://www.tigris.org/servlets/Login">Log in</a>
-to your tigris.org account before submitting a bug report
-</strong>
-<p>
-If you do not already have a tigris.org account,
-register for one at
-<a href="http://www.tigris.org/servlets/Join">http://www.tigris.org/servlets/Join</a>.
-</p>
-<p>
-We no longer accept anonymous bug reports,
-due to spambot abuse of the open-door policy.
-</p>
-</li>
-<li>
-<strong>Specify the version of SCons in which you observed the problem</strong>
-<p>
-This helps avoid wasted time trying to pinpoint the version,
-and also allows us to confirm if a later released version
-has already fixed your problem.
-</p>
-</li>
-<li>
-<strong>Provide SConscript files or other configuration that reproduce the problem</strong>
-<p>
-If you can, simplify the configuration to just the
-minimal subset that demonstrates the problem.
-It's much harder to diagnose a problem
-if the incorrect behavor is due to
-one particular item out of a thousand
-in a large configuration.
-</p>
-<p>
-That said, it's most convenient if you can provide
-an actual configuration (set of SConscript files
-and/or other input files)
-that can be downloaded and run to demonstrate the bug.
-The easiest way is to attach a .tar.gz or .zip file
-to the bug report.
-Note that the tigris.org Issue Tracker
-doesn't let you attach a file like this
-when you initially submit the report.
-You must first create the bug report,
-and then attach a file to it as a separate step.
-See below for the detailed steps.
-</p>
-<p>
-If your problem is evident from a few specific SConscript lines,
-it's perfectly acceptable just to
-paste the lines into the Description field of the bug report.
-</p>
-</li>
-<li>
-<strong>Describe specifically the incorrect behavor you observed</strong>
-<p>
-It's best if you can cut and paste the output from SCons,
-especially any error messages.
-Otherwise,
-Vague descriptions like,
-"SCons errors out," or "Product XYZ doesn't compile"
-are extremely difficult to diagnose,
-because the different installed tools on someone else's system
-may cause SCons to behave differently
-and not demonstrate your bug.
-</p>
-</li>
-<li>
-<strong>Describe what you expected to happen</strong>
-<p>
-This isn't always obvious, especially if the
-bug does not involve an SCons failure or error message.
-Describing the behavior you expected
-helps speed up the diagnosis.
-</p>
-</li>
-</ul>
-
-<h2 id="steps">Steps for Submitting a Bug Report</h2>
-
-<p>
-The following guides you step-by-step through the
-process of submitting a new SCons bug report.
-</p>
-
-<p>
-NOTE: Creating a bug report with an attached file or files
-(such as a .tar.gz or .zip file containing a sample configuration)
-is a two-step process in the tigris.org Issue Tracker.
-You must first create the bug report,
-and then attach the file(s) in a separate step,
-as described below.
-</p>
-
-<ul>
-<li>
-<strong><a href="http://www.tigris.org/servlets/Login">Log in</a> at tigris.org</strong>
-<p>
-If you do not already have a tigris.org account,
-register for one at
-<a href="http://www.tigris.org/servlets/Join">http://www.tigris.org/servlets/Join</a>.
-</p>
-<p>
-We no longer accept anonymous bug reports,
-due to spambot abuse of the open-door policy.
-</p>
-</li>
-<li>
-<strong>Go to the
-<a href="http://scons.tigris.org/issues/enter_bug.cgi?component=scons&subcomponent=scons&issue_type=DEFECT">"Enter issue" page</a>
-</strong>
-<p>
-By default, the "scons" subcomponent is selected;
-if this bug is for a different subcomponent, select that instead.
-</p>
-</li>
-<li>
-<strong>Specify the version of SCons in which you found the bug</strong>
-<p>
-</p>
-</li>
-<li>
-<strong>Specify the Subcomponent (if the bug is not in SCons itself)</strong>
-<p>
-The URL two steps above assumes that you're reporting
-a bug in the behavior of SCons itself.
-If you're reporting a problem in some other aspect of the SCons Project
-(such as the documentation, or the packaging),
-please change the Subcomponent field to reflect that.
-</p>
-</li>
-<li>
-<strong>Specify the Platform and OS</strong>
-<p>
-The Platform field is less important here
-(SCons doesn't have many behavioral difference
-due to different hardware platforms)
-but the OS field is important.
-</p>
-</li>
-<li>
-<strong>Fill in a good Summary line describing the bug</strong>
-<p>
-This line is what shows up in summary reports,
-so it should be descriptive but not too long.
-Avoid overly-general things like "SCons error," etc.
-</p>
-</li>
-<li>
-<strong>Fill in the Description field</strong>
-<p>
-This is where you should go into detail
-about the configuration,
-the exact error you see,
-what you expected to happen, etc.
-When in doubt, include more information rather than less.
-</p>
-</li>
-<li>
-<strong>Press the "Submit issue" to submit your report</strong>
-<p>
-You will now receive a <tt>Posting issue</tt> page
-that gives you the number of the issue you submitted.
-</p>
-</li>
-<li>
-<strong>If you have a .tar.gz, .zip or other file to attach:</strong>
-<ul>
-<li>
-<strong>Click the "Attach a file to this issue" link</strong>
-</li>
-<li>
-<strong>Fill in the "File" field with the path to the file you want to upload</strong>
-(You can also do this through the <tt>Browse...</tt> button.)
-</li>
-<li>
-<strong>Fill in the Description field</strong>
-</li>
-<li>
-<strong>Click the "Submit" button</strong>
-</li>
-</ul>
-</li>
-</ul>
-
-</div>
-
-</body>
-</html>
diff --git a/www/cn-project-pages/Administrivia/snippets/HtmlSnippet1.html b/www/cn-project-pages/Administrivia/snippets/HtmlSnippet1.html
deleted file mode 100644
index a311062..0000000
--- a/www/cn-project-pages/Administrivia/snippets/HtmlSnippet1.html
+++ /dev/null
@@ -1 +0,0 @@
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><ul><li><a title="Messages pending approval" href="/ds/viewPendingApprovalMessages.do">Messages pending approval</a></li><li><a title="Deleted discussions" href="/ds/viewDeletedForums.do">Deleted discussions</a> <br /></li></ul> \ No newline at end of file
diff --git a/www/cn-project-pages/Administrivia/snippets/description.txt b/www/cn-project-pages/Administrivia/snippets/description.txt
deleted file mode 100644
index 08c477b..0000000
--- a/www/cn-project-pages/Administrivia/snippets/description.txt
+++ /dev/null
@@ -1 +0,0 @@
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Administrative information and links \ No newline at end of file
diff --git a/www/cn-project-pages/Administrivia/snippets/page.xml b/www/cn-project-pages/Administrivia/snippets/page.xml
deleted file mode 100644
index 7086b8d..0000000
--- a/www/cn-project-pages/Administrivia/snippets/page.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<page visibility="1">
- <component_list>
- <component visibility="2" type="Html" order="1">
- <title localize="false">Administrative links</title>
- <filename>HtmlSnippet1.html</filename>
- </component>
- </component_list>
-</page>
-
diff --git a/www/cn-project-pages/snippets/page.xml b/www/cn-project-pages/snippets/page.xml
deleted file mode 100644
index 005b144..0000000
--- a/www/cn-project-pages/snippets/page.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<page visibility="1">
- <component_list>
- <component visibility="1" type="ProjectMetadata" order="1">
- <title localize="false" />
- </component>
- <component visibility="1" type="Html" order="2">
- <title localize="false" />
- <filename>index.html</filename>
- </component>
- <component visibility="1" type="Subproject" order="3">
- <title localize="true">Subprojects</title>
- </component>
- </component_list>
-</page>
-
diff --git a/www/cn-project-pages/structure.xml b/www/cn-project-pages/structure.xml
deleted file mode 100644
index 2c1f3bb..0000000
--- a/www/cn-project-pages/structure.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<structure>
- <page>
- <id>g2uyOi</id>
- <name>Administrivia</name>
- <directory>Administrivia</directory>
- <ordinal>1</ordinal>
- </page>
-</structure>
-
diff --git a/www/favicon.ico b/www/favicon.ico
deleted file mode 100644
index 1541e5b..0000000
--- a/www/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/www/feature-request.html b/www/feature-request.html
deleted file mode 100644
index e644a16..0000000
--- a/www/feature-request.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<html>
-<head>
-<title>Feature Requests</title>
-</head>
-<body>
-
-<div id="apphead">
-<h1><small>scons</small><br />Feature Requests</h1>
-</div>
-
-<p>
-<strong>You must now
-<a href="http://www.tigris.org/servlets/Login">log in</a>
-to a <a href="http://www.tigris.org">tigris.org</a> account
-before submitting a feature request!</strong>
-</p>
-
-<p>
-Feature requests should be submitted to the
-<a href="http://scons.tigris.org/issues/enter_bug.cgi?component=scons&subcomponent=scons&issue_type=FEATURE">"Enter Issue" page</a>.
-A more detailed set of <a href="feature-request.html#steps">submission steps</a>
-can be found below.
-</p>
-
-<p>
-The "Enter Issue" links on this page,
-by default, create a <tt>FEATURE</tt> request,
-a request for completely new SCons functionality.
-If your request is for modified behavior
-of an already-existing SCons feature,
-you may wish to change the Issue type
-to an <tt>ENHANCEMENT</tt> request.
-If you're not sure, leave the issue as a <tt>FEATURE</tt> request;
-it can be reclassified in the future, if necessary.
-</div>
-
-<div class="h2 app" style="border-left: 0px" id="customcontent">
-
-<h2 id="steps">Steps for Submitting a Feature Request</h2>
-
-<p>
-The following guides you step-by-step through the
-process of submitting a feature request.
-</p>
-
-<ul>
-<li>
-<strong><a href="http://www.tigris.org/servlets/Login">Log in</a> at tigris.org</strong>
-<p>
-If you do not already have a tigris.org account,
-register for one at
-<a href="http://www.tigris.org/servlets/Join">http://www.tigris.org/servlets/Join</a>.
-</p>
-<p>
-We no longer accept anonymous feature requests,
-due to spambot abuse of the open-door policy.
-</p>
-</li>
-<li>
-<strong>Go to the
-<a href="http://scons.tigris.org/issues/enter_bug.cgi?component=scons&subcomponent=scons&issue_type=FEATURE">"Enter issue" page</a>
-</strong>
-<p>
-By default, the "scons" subcomponent is selected;
-if this bug is for a different subcomponent, select that instead.
-</p>
-</li>
-<li>
-<strong>Fill in a good Summary line describing the feature you're requesting</strong>
-<p>
-This line is what shows up in summary reports,
-so it should be descriptive but not too long.
-</p>
-</li>
-<li>
-<strong>Fill in the Description field</strong>
-<p>
-This is where you should go into detail
-about what you'd like to see SCons do differently.
-When in doubt, include more information rather than less.
-</p>
-</li>
-<li>
-<strong>Press the "Submit issue" to submit your request</strong>
-<p>
-You will now receive a <tt>Posting issue</tt> page
-that gives you the number of the issue you submitted.
-If you want to attach a file to your feature request,
-you can do so by clicking the
-<tt>Attach a file to this issue</tt>
-link and using that page to upload a file.
-</p>
-</li>
-</ul>
-
-</div>
-
-</body>
-</html>
diff --git a/www/gen_sched_table.py b/www/gen_sched_table.py
deleted file mode 100755
index 85b1b81..0000000
--- a/www/gen_sched_table.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function
-
-import sys
-import datetime
-
-months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
-print('<table width="100%">')
-def row(*cells, **kw):
- td = kw.get('tr','td')
- print(' <tr>')
- for cell in cells:
- print(' <%s>%s</%s>' % (td,cell,td))
- print(' </tr>')
-row('Estimated&nbsp;date', 'Type', 'Comments', tr = 'th')
-
-if len(sys.argv) > 1:
- f = open(sys.argv[1])
-else: f = open('schedule')
-now = None
-current = 'UNKNOWN'
-for line in f:
- if line[0] == '#': continue # comment
- if line[0] == '=':
- date,current = line[1:].strip().split(None, 1)
- now = datetime.date(*tuple([int(i) for i in date.split('-')]))
- continue
- if line[0] == '+':
- incr,type,desc = line[1:].strip().split(None,2)
- now = now + datetime.timedelta(int(incr))
- else:
- print('dunna understand code', line[0])
- sys.exit(1)
- #name = current + '.d' + str(now).replace('-','')
- date = '%s-%s-%s' % (now.day,months[now.month-1],now.year)
- if type == 'ck':
- category = 'Ckpt'
- elif type == 'rc':
- category = 'RC'
- else:
- category = current = type
- row(date, category, desc)
-print('</table>')
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/www/index.html b/www/index.html
deleted file mode 100644
index 203435d..0000000
--- a/www/index.html
+++ /dev/null
@@ -1,288 +0,0 @@
-<html>
-<head>
-</head>
-<body>
-
-<div class="h2 app" style="border-left: 0px" id="customcontent">
-
-<h2>What is SCons?</h2>
-
-<p>SCons is a next-generation,
-cross-platform, build tool.
-Think of SCons as an improved
-substitute for the classic
-<tt>Make</tt> utility
-with integrated functionality
-similar to <tt>autoconf</tt>/<tt>automake</tt>
-and compiler caches such as <tt>ccache</tt>.
-</p>
-
-<p>
-Unlike build tools that invent their own mini-language
-or wedge a scripting language onto some other
-configuration file syntax,
-SCons configuration files
-are actually Python scripts.
-The ability to script your build
-gives you a tremendous amount of flexibility
-to solve complicated build problems
-in surprisingly small amounts of maintainable code.
-</p>
-
-<p>
-In short, SCons is an easier, more reliable
-and more flexible way to build software.
-</p>
-
-<!--
-
-<h2><b>Goal</b></h2>
-
-<p>The primary goal of The SCons Project
-is to become the premiere enterprise-quality tool for
-building cross-platform, multi-language software projects
-by offering unparalleled <b>reliability</b> and <b>flexibility</b>
-to software buildmasters and developers.
-</p>
-
-<p>
-Yeah, yeah, every project has similar lofty mom-and-apple-pie goals,
-blah, blah, blah...
-So why is SCons any different?
-Fair question.
-If you go to our public home page at
-<a href="http://www.scons.org/">http://www.scons.org</a>
-you'll get the usual lists of
-supported features and platforms, testimonials, etc.
-But you're presumably at <emphasis>this</emphasis>
-project page because you're interested in digging a little deeper.
-So here are the <emphasis>philosophical viewpoints</emphasis>
-that we think contribute to SCons being
-a really distinctive software build tool:
-</p>
-
-<ul>
-
-<li>
-<strong>Software builds are getting more complicated, not less</strong>
-<p>
-The proliferation of programming languages and technologies
-have led to increasingly difficult demands being
-placed on traditional software build tools Make.
-EVen if you stick to one language--a well-worn
-and mature one like C, for example--the
-differences between the various C tool chains
-and how they behave on various platforms
-make it a real challenge
-to keep your software builds simple and reliable.
-</p>
-<p>
-Consequently, SCons is a build tool
-</p>
-</li>
-
-<li>
-<strong>Effective software building is not a language design issue</strong>
-<p>
-There are a lot of build tools out there,
-and it seems like a new one pops up every week
-as someone gets the urge to fix some particularly
-bad build problem that they're facing.
-Most build tools have, historically,
-invented some special configuration file format
-to express dependencies and actions.
-The problem is that by the time you take care of all
-of the different ways people
-you really want to have the flexibility
-that a scripting language gives:
-loops, conditionals, real data structures, etc.
-(It's interesting to note that the Ant community is
-working hard on adding more scriptability to their
-XML-based Ant files,
-and James Duncan Davidson, Ant's creator,
-is on record as saying that he'd use a scripting
-language if he were doing it over again.)
-</p>
-<p>
-</p>
-<p>
-Note that SCons is not completely pure in this regard.
-</p>
-</li>
-
-<li>
-<strong>You want to encapsulate software build complexity
-so most developers don't even have to think about it</strong>
-<pp>
-XXX
-</pp>
-</li>
-
-<li>
-<strong>Overall, a reliable build that takes a little longer is
-cheaper than a fast build that you can't rely on</strong>
-<p>
-This one is sometimes tough to swallow,
-because we all want the build to be as quick as possible
-when we're in that tight edit-build-debug development cycle.
-The problem is that if you take shortcuts in how your
-build tool manages the dependencies,
-you waste time chasing phantom problems
-that simply go away because you finally give up
-and do a <tt>make clean; make</tt>.
-</p>
-</li>
-
-<li>
-<strong>Building software in multiple side-by-side variants is crucial
-in a multi-platform world</strong>
-<pp>
-XXX
-</pp>
-</li>
-
-</ul>
-
--->
-
-<h2><b>SCons Features</b></h2>
-
-<ul>
-
-<li>
-<strong>Configuration files are Python scripts</strong>
-<p>
-This provides much more flexibility for solving
-difficult build problems
-than traditional build tools.
-</p>
-</li>
-
-<li>
-<strong>Reliable, automatic dependency analysis</strong>
-<p>
-C, C++ and Fortran are scanned for dependencies,
-eliminating the need for a separate <tt>make depend</tt> step
-or a <tt>make clean</tt> to get all of the dependencies.
-Avoids the time waste from debugging phantom problems
-that mysteriously disappear after you
-<tt>make clean; make</tt>.
-Easily extended to scan for other languages or file types.
-</p>
-</li>
-
-<li>
-<strong>Built-in support for multiple languages</strong>
-<p>
-C, C++, D, Java, Fortran, Yacc, Lex, Qt and SWIG.
-Can also build TeX and LaTeX documents.
-Easily extended for other languages or file types.
-</p>
-</li>
-
-<li>
-<strong>Cross-platform</strong>
-<p>
-Known to work on Linux,
-other POSIX systems (AIX, *BSD, HP/UX, IRIX, Solaris),
-Windows (NT, 2000, XP),
-Mac OS X,
-and OS/2.
-</p>
-</li>
-
-<li>
-<strong>Fetch files from SCM systems or central directory trees</strong>
-<p>
-Built-in support for SCCS, RCS, CVS, BitKeeper and Perforce.
-On-disk directory trees can be searched for source files
-or pre-built target files.
-</p>
-</li>
-
-<li>
-<strong>Support for Microsoft Visual Studio .NET and 2005</strong>
-<p>
-Generates <tt>.dsp</tt> and <tt>.dsw</tt> files,
-or <tt>.sln</tt> and <tt>.vcproj</tt> files,
-from the same build configuration used to build on all platforms.
-Allows Windows developers to do all the productive
-point-and-click debugging they're used to
-without having to maintain a separate build configuration
-just for Windows.
-</p>
-</li>
-
-<li>
-<strong>Reliable detection of file changes using MD5 signatures</strong>
-<p>
-Use of traditional file timestamps instead of MD5 can be configured.
-</p>
-</li>
-
-<li>
-<strong>Parallel builds</strong>
-<p>
-Keeps up to N jobs running simultaneously regardless
-of directory hierarchy.
-</p>
-</li>
-
-<li>
-<strong>Global view of dependencies</strong>
-<p>
-Simplifies builds by eliminating multiple passes
-or reording targets to build everything correctly.
-</p>
-</li>
-
-<li>
-<strong>Multi-platform configuration (like <tt>Autoconf</tt>)</strong>
-<p>
-Support for finding <tt>#include</tt> files,
-libraries, functions and <tt>typedef</tt> declarations.
-</p>
-</li>
-
-<li>
-<strong>Shared built-file cache</strong>
-<p>
-Speeds up multiple builds by allowing developers
-to share pre-built targets
-(like <tt>ccache</tt>, but for any type of target file,
-not just C/C++ compilation).
-</p>
-</li>
-
-</ul>
-
-<!--
-
-<h2></h2>
-
-<p>What are the high-level assumptions or ground rules for the project?
-</p>
-
-<p>For example:
-</p>
-
-<ul>
-<li> we will use programming language X on operating system Y for now.
-
-<li>We will, or will not, consider certain functional areas like
-internationalization, high security, concurrency, etc. The list of
-functional areas will depend on what you are trying to do.
-
-<li>Try to keep this part short.
-</ul>
-
--->
-
-<h2>Future</h2>
-
-See the <a href="roadmap.html">Roadmap</a> page.
-
-</div>
-
-</body>
-</html>
diff --git a/www/patch-submission.html b/www/patch-submission.html
deleted file mode 100644
index a2d9b95..0000000
--- a/www/patch-submission.html
+++ /dev/null
@@ -1,355 +0,0 @@
-<html>
-<head>
-<title>Patch Submission</title>
-</head>
-<body>
-
-<div id="apphead">
-<h1><small>scons</small><br />Patch Submission</h1>
-</div>
-
-<p>
-<strong>You must now
-<a href="http://www.tigris.org/servlets/Login">log in</a>
-to a <a href="http://www.tigris.org">tigris.org</a> account
-before submitting a patch!</strong>
-</p>
-
-<p>
-Patches should be submitted to the
-<a href="http://scons.tigris.org/issues/enter_bug.cgi?component=scons&subcomponent=scons&issue_type=PATCH">"Enter Issue" page</a>.
-Please follow the <a href="patch-submission.html#guidelines">submission guidelines</a> below
-to make sure your patch contains the necessary information.
-A more detailed set of <a href="patch-submission.html#steps">submission steps</a>
-can be found below.
-</p>
-
-</div>
-
-<div class="h2 app" style="border-left: 0px" id="customcontent">
-
-<h2 id="guidelines">Guidelines for Patch Submission</h2>
-
-<p>
-To try to maintain and improve the quality of SCons releases,
-we have some pretty high standards for the quality of patches
-that make it into the SCons code base.
-This list of guidelines describes how to make it as
-easy as possible for your patch to be accepted for integration.
-We're still interested in your code
-even if you don't follow all of these guidelines,
-but then your patch will more than likely sit in the queue
-until someone else has time to supply all of the
-necessary missing items.
-</p>
-
-<ul>
-
-<li>
-<strong>
-Please
-<a href="http://www.tigris.org/servlets/Login">log in</a>
-to your tigris.org account before submitting any patch
-</strong>
-<p>
-If you do not already have a tigris.org account,
-register for one at
-<a href="http://www.tigris.org/servlets/Join">http://www.tigris.org/servlets/Join</a>.
-</p>
-<p>
-We no longer accept anonymous patches,
-due to spambot abuse of the open-door policy.
-</p>
-</li>
-
-<li>
-<strong>If your patch is extensive, discuss it first on the
-<a href="mailto:scons-dev@scons.org">scons-dev@scons.org</a>
-mailing list
-</strong>
-<p>
-In fact, for extensive changes, it's a good idea to have this discusssion
-<em>before</em> you invest too much time in coding.
-It's possible that your idea overlaps with something else
-already in the works,
-or that your idea is unlikely to be accepted
-because it would conflict with planned directions for SCons.
-It's much better to find that out,
-or get advice on acceptable design choices.
-before you've spent a lot of time polishing code
-that will be rejected because it doesn't fit
-plans for the architecture.
-</p>
-</li>
-
-<li>
-<strong>It's better to submit multiple patches with separate bits of functionality than a big patch containing lots of changes</strong>
-<p>
-Big, intertwined sets of changes
-increase the chances of unintended side effects
-that could cause the entire patch to be rejected.
-If you submit separate functional changes in separate patches,
-those change that meet all the criteria can
-still be integrated even
-though other pieces might be held up for one reason or another.
-</p>
-</li>
-
-<li>
-<strong>Submit your patch in <tt>diff -u</tt> or <tt>diff -c</tt> format</strong>
-<p>
-In particular, do <em>not</em> submit whole source files,
-or <tt>diff</tt> output without any kind of context information.
-It's much more difficult to integrate whole source files
-or plain <tt>diff</tt> output with other changes to
-the SCons code base,
-especially other changes that might be integrated
-after you've submitted your patch.
-</p>
-</li>
-
-<li>
-<strong>Your patch must include test case(s) before it can be integrated!</strong>
-<p>
-THIS IS THE SINGLE MOST COMMON REASON FOR DELAYS IN INTEGRATING PATCHES
-AND THE SINGLE MOST IMPORTANT THING YOU CAN DO TO INCREASE THE
-CHANCES OF YOUR PATCH BEING INTEGRATED QUICKLY.
-</p>
-<p>
-The SCons development methodology requires
-that each change be accompanied by one or more
-new or modified test cases
-that get added to our extensive regression test suite.
-This is to make sure that the behavior added by your patch
-doesn't get inadvertently broken by other changes in the future.
-Patches that fix bugs should contain at least one test case
-that demonstrates the behavior being fixed by the patch.
-For example, if you're fixing a configuration that causes
-SCons to exit with an error and a stack trace,
-the test case should trigger that stack trace
-when run against the current code.
-Patches that add new features or enhancements
-should contain test cases that use
-the new behavior being added to SCons.
-</p>
-<p>
-You can do any of the following to supply
-test cases with your patch:
-</p>
-<ul>
-<li>
-<strong>Include actual new or modified SCons test scripts in your patch</strong>
-<p>
-This is the best option because it's the easiest to integrate,
-and therefore maximizes the chances of your patch being accepted quickly.
-(Note that, yes, there's a curve to learning how to
-write test scripts in the SCons testing harness.
-We're working on documentation to deal with that.)
-</p>
-</li>
-<li>
-<strong>Include a .tar.gz or .zip file containing test configurations</strong>
-<p>
-If you can't quite figure out how to deal with the SCons test scripts,
-the next best option is to include with your patch an archive file
-containing one or more actual test configurations
-(<tt>SConscript</tt> files, input files, etc.).
-It will be relatively straightforward for someone integrating your patch,
-and who's presumably familiar with the SCons testing harness,
-to turn this into an appropriate test script.
-Be sure to include a description of how to run your recommended test scenario,
-or a script for doing so.
-</p>
-</li>
-<li>
-<strong>Describe how to go about testing the patch</strong>
-<p>
-If you really can't cook up a test configuration to include with the patch,
-the lowest-common-denominator approach is to just describe
-how to go about testing the patch.
-Be as specific as possible,
-even if you think it should be obvious
-how to test the patch.
-It might be clear to you while you're writing the code,
-but it will still take someone else time
-to make sure they understand your intent
-and work out the details of how to set up an appropriate case.
-The point is you're trying to use your existing knowledge
-of the bug being fixed or new feature being added
-to make the process of integrating your patch as
-simple and quick as possible,
-thereby increasing the chance of your patch making it
-into the SCons code base.
-</p>
-</li>
-</ul>
-<p>
-If you don't supply <em>any</em> sort of testing
-information with your patch,
-well, you're still welcome to submit the code.
-Just be aware that the patch will likely stay
-in the queue until someone has time to reverse-engineer
-a test case.
-</p>
-</li>
-
-<li>
-<strong>Your patch should not break any existing tests</strong>
-<p>
-This almost sounds like it should go without saying,
-but the reason we put so much emphasis on test cases
-is so that we can make sure functionality doesn't break.
-Your patch will almost certainly be run through the
-the complete set of checked-in test scripts,
-and if any of them break,
-your patch will either be rejected outright
-or delayed while someone else figures out how to fix it
-(or the tests) so that everything works correctly.
-You should, of course, avoid this by running your patch
-against the regression tests and fixing any problems
-<em>before</em> submitting your patch.
-If you run your patch against against the regression tests
-but can't figure out how to fix all the cases,
-the best bet would be to ask the
-<a href="mailto:scons-dev@scons.org">scons-dev@scons.org</a>
-mailing list.
-</p>
-</li>
-
-<li>
-<strong>Your patch should include documentation changes</strong>
-<p>
-We also insist that changes to the SCons code base
-be accompanied by appropriate changes to the documentation.
-In practice, right now we make sure the man page is up to date,
-and updates to the User's Guide often lag.
-</p>
-<p>
-Similar to the guidelines above for testing,
-if you don't submit changes to the actual man page with your patch,
-it's helpful if you at least provide
-some suggested text describing your change.
-Even if the actual words get rewritten
-(usually to make the style consistent with the rest of the man page),
-taking the time to provide this
-makes the integration easier because
-the person integrating the patch doesn't have
-to reverse-engineer the <em>intent</em>
-of your change to figure out how to describe it.
-</p>
-</li>
-
-</ul>
-
-<h2 id="steps">Steps for Submitting a Patch</h2>
-
-<p>
-The following guides you step-by-step through the
-process of submitting a patch to SCons.
-</p>
-
-<p>
-NOTE: Attaching a file or files
-(such as a .tar.gz or .zip file containing your patch)
-is a two-step process in the tigris.org Issue Tracker.
-You must first create the patch issue in the Tracker,
-and then attach the file(s) in a separate step,
-as described below.
-</p>
-
-<ul>
-
-<li>
-<strong><a href="http://www.tigris.org/servlets/Login">Log in</a> at tigris.org</strong>
-<p>
-If you do not already have a tigris.org account,
-register for one at
-<a href="http://www.tigris.org/servlets/Join">http://www.tigris.org/servlets/Join</a>.
-</p>
-<p>
-We no longer accept anonymous bug reports,
-due to spambot abuse of the open-door policy.
-</p>
-</li>
-
-<li>
-<strong>Go to the
-<a href="http://scons.tigris.org/issues/enter_bug.cgi?component=scons&subcomponent=scons&issue_type=PATCH">"Enter issue" page</a>
-</strong>
-<p>
-By default, the "scons" subcomponent is selected;
-if this bug is for a different subcomponent, select that instead.
-</p>
-</li>
-
-<li>
-<strong>Specify the version of SCons that you used as a baseline</strong>
-<p>
-You can leave this <tt>-unspecified-</tt>,
-in which case the assumption will be that you started with
-the code checked in to our Subversion repository
-at the time you opened the issue.
-</p>
-</li>
-
-<li>
-<strong>Fill in a good Summary line describing the patch</strong>
-<p>
-This line is what shows up in summary reports,
-so it should be descriptive but not too long.
-Avoid overly-general things like "SCons error," etc.
-</p>
-</li>
-
-<li>
-<strong>Fill in the Description field</strong>
-<p>
-This is where you should describe
-the nature of your patch:
-the exact error it fixes,
-the feature that it adds,
-how to go about testing it,
-etc.
-When in doubt, include more information rather than less.
-</p>
-</li>
-
-<li>
-<strong>Press the "Submit issue" to submit your report</strong>
-<p>
-You will now receive a <tt>Posting issue</tt> page
-that gives you the number of the issue you submitted.
-</p>
-</li>
-
-<li>
-<strong>Click the "Attach a file to this issue" link</strong>
-<p>
-</p>
-</li>
-
-<li>
-<strong>Fill in the "File" field with the path to the patch file you want to upload</strong>
-<p>
-(You can also do this through the <tt>Browse...</tt> button.)
-</p>
-</li>
-
-<li>
-<strong>Fill in the Description field</strong>
-<p>
-</p>
-</li>
-
-<li>
-<strong>Click the "Submit" button to attach your patch file</strong>
-<p>
-</p>
-</li>
-
-</ul>
-
-</div>
-
-</body>
-</html>
diff --git a/www/project_highlights.html b/www/project_highlights.html
deleted file mode 100644
index 98f00bc..0000000
--- a/www/project_highlights.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<html>
-<head>
-</head>
-<body>
-
-
-<p>
-<strong>09 Sep 2011:</strong>
-Release 2.1.0 is now available at the
-<a href="http://sourceforge.net/project/showfiles.php?group_id=30337">download page</a>.
-</p>
-
-
-<p>
-<strong>15 Aug 2010:</strong>
-Release 2.0.1 is now available at the
-<a href="http://sourceforge.net/projects/scons/files/">download page</a>.
-</p>
-
-
-
-
-</body>
-</html>
diff --git a/www/project_issues.html b/www/project_issues.html
deleted file mode 100644
index dc28ca8..0000000
--- a/www/project_issues.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<div id="apphead">
-<h1><small>scons</small><br /> Issue Tracker
- </h1>
-</div>
-
-
-<div id="projectissues" class="application">
-
-
-<table class="axial">
-
- <tr>
- <th><a href="http://scons.tigris.org/issues/query.cgi">Query database</a></th>
- <td>
- Search for issues and defects here or find a specific issue. Always search first before reporting an issue to avoid duplication.
- <form id="ProjectIssuesForm" method="get" action="http://scons.tigris.org/issues/show_bug.cgi">
- <p>
- <input type="submit" value="Find" /> Issue # <input name="id" size="6" />
-
- </p>
- </form>
- <p>
- Common queries:
- </p>
- <table>
- <tr>
- <td COLSPAN="4"> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&component=scons&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&issue_status=UNCONFIRMED">All Open Issues</a> </td>
- </tr>
- <tr>
- <td> <ul> <li> Bug Reports: </li> </ul> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=DEFECT&component=scons">All</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=DEFECT&component=scons&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&issue_status=UNCONFIRMED">Open</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=DEFECT&component=scons&issue_status=RESOLVED&issue_status=VERIFIED&issue_status=CLOSED">Non-Open</a> </td>
- </tr>
- <tr>
- <td> <ul> <li>Enhancement: </li> </ul> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=ENHANCEMENT&component=scons">All</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=ENHANCEMENT&component=scons&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&issue_status=UNCONFIRMED">Open</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=ENHANCEMENT&component=scons&issue_status=RESOLVED&issue_status=VERIFIED&issue_status=CLOSED">Non-Open</a> </td>
- </tr>
- <tr>
- <td> <ul> <li>Feature Requests: </li> </ul> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=FEATURE&component=scons">All</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=FEATURE&component=scons&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&issue_status=UNCONFIRMED">Open</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=FEATURE&component=scons&issue_status=RESOLVED&issue_status=VERIFIED&issue_status=CLOSED">Non-Open</a> </td>
- </tr>
- <tr>
- <td> <ul> <li> Patches: </li> </ul> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=PATCH&component=scons">All</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=PATCH&component=scons&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&issue_status=UNCONFIRMED">Open</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=PATCH&component=scons&issue_status=RESOLVED&issue_status=VERIFIED&issue_status=CLOSED">Non-Open</a> </td>
- </tr>
- <tr>
- <td> <ul> <li> Tasks: </li> </ul> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=TASK&component=scons">All</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=TASK&component=scons&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&issue_status=UNCONFIRMED">Open</a> </td>
- <td> <a href="http://scons.tigris.org/issues/buglist.cgi?Submit+query=Submit+query&issue_type=TASK&component=scons&issue_status=RESOLVED&issue_status=VERIFIED&issue_status=CLOSED">Non-Open</a> </td>
- </tr>
- </table>
- </td>
-</tr>
-
-
- <tr>
- <th>Enter an issue</th>
- <td>
-
- To enter an issue, you must first be a project member and know the component you want to report on.
-
-
-
-<p>
-
-Enter:
-</p>
- <ul>
- <li><a href="http://scons.tigris.org/issues/enter_bug.cgi?issue_type=DEFECT">Defect</a></li>
- <li><a href="http://scons.tigris.org/issues/enter_bug.cgi?issue_type=PATCH">Patch</a></li>
- <li><a href="http://scons.tigris.org/issues/enter_bug.cgi?issue_type=TASK">Task</a></li>
- <li><a href="http://scons.tigris.org/issues/enter_bug.cgi?issue_type=FEATURE">Feature</a></li>
- <li><a href="http://scons.tigris.org/issues/enter_bug.cgi?issue_type=ENHANCEMENT">Enhancement</a></li>
-
-</ul>
- </td>
-</tr>
-
-
-
- <tr>
- <th><a href="http://scons.tigris.org/issues/buglist.cgi?cmdtype=runuserdefault">My issues</a></th>
- <td>
- View both active issues assigned to you and those that you have entered.
- </td>
-</tr>
- <tr>
- <th><a href="http://scons.tigris.org/issues/userprefs.cgi">My preferences</a></th>
-
- <td>
- View and edit your Issue Tracker user settings.
- </td>
-</tr>
-
- <tr>
- <th><a href="http://scons.tigris.org/issues/reports.cgi">Reports</a></th>
- <td>
- Generate and view issue tracking reports.
- </td>
-</tr>
-
-
-
- <tr>
- <th><a href="http://scons.tigris.org/issues/admin.cgi">Configuration options </a>
- </th>
- <td>
- Add, view and edit Issue Tracker configuration parameters, including project member permissions, issue tracking groups, project components and subcomponents, etc.
- </td>
-</tr>
-
-
-
-</table>
-</div>
diff --git a/www/project_tools.html b/www/project_tools.html
deleted file mode 100644
index ee731a4..0000000
--- a/www/project_tools.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
-This is a customization of the tigris.org nav bar to try to make
-things a little more navigable. This isn't really approved by
-tigris.org (I copped the basic idea from the Subversion project pages),
-but it works for our purposes.
-
-The main changes are:
-
-* Added links to the scons.org home page and scons.org wiki.
-* Our custom issue tracker page, which contains common queries.
-* Subheadings for reporting a bug / submitting a patch / request a feature.
-* Link to our Roadmap page.
--->
-<li><a href="http://scons.org/">SCons Home Page</a></li>
-<li><a href="http://scons.org/wiki/">SCons Wiki</a></li>
-</dd>
-
-<dd>
-<li><a href="/servlets/ProjectMemberList">Project Membership</a></li>
-<li><a href="/servlets/ProjectNewsList">Announcements</a></li>
-<li><a href="http://scons.org/lists.php">Discussion lists/fora</a></li>
-<!-- <li><a href="/ds/viewForums.do">Discussion lists/fora</a></li> -->
-<li><a href="/servlets/ProjectDocumentList">Documents &amp; files</a></li>
-<li><a href="/source/browse/scons/">Browse source code</a></li>
-<li><a href="/servlets/ReportingHome?scope=Project">Project metrics</a></li>
-</dd>
-
-<dd>
-<li>
-<!-- <a href="/servlets/ProjectIssues">Issue Tracker</a> -->
-<a href="/project_issues.html">Issue Tracker</a>
-<ul>
-<li><a href="/bug-submission.html">Report a Bug</a></li>
-<li><a href="/patch-submission.html">Submit a Patch</a></li>
-<li><a href="/feature-request.html">Request a Feature</a></li>
-</ul>
-</li>
-</dd>
-
-<dd>
-<li><a href="/roadmap.html">Roadmap</a></li>
diff --git a/www/roadmap.html b/www/roadmap.html
deleted file mode 100644
index 333d0fd..0000000
--- a/www/roadmap.html
+++ /dev/null
@@ -1,173 +0,0 @@
-<html>
-<head>
-<title>scons: Release Roadmap</title>
-</head>
-<body>
-
-<div id="apphead">
-<h1><small>Release Roadmap</small></h1>
-</div>
-
-<div class="h2 app" style="border-left: 0px" id="customcontent">
-
-<h2>Current Releases</h2>
-
-<p>
-The current stable release is 2.1.0, released 09 Sep 2011.
-The latest 2.1.x release is 2.1.0, released 09 Sep 2011.
-</p>
-
-<p>
-The latest 1.3.x release is 1.3.1, released 25 July 2010.
-</p>
-
-<h2>Upcoming Releases</h2>
-
-<p>
-Our goal is to meet the dates
-for release candidates and the releases themselves;
-the beta checkpoint dates are our best guess as this was published,
-but they may be adjusted without notice.
-</p>
-
-<!--
-
-DO NOT EDIT THE FOLLOWING TABLE DIRECTLY.
-
-Edit the "schedule" file and replace it with the output from
-running "gen_sched_table.py".
-
--->
-
-<table width="100%">
- <tr>
- <th>Estimated&nbsp;date</th>
- <th>Type</th>
- <th>Comments</th>
- </tr>
- <tr>
- <td>May 2010</td>
- <td>Ckpt</td>
- <td>Beta for 2.0; breaks backward compatibility</td>
- </tr>
- <tr>
- <td>June 2010</td>
- <td>RC</td>
- <td>Release candidate for 2.0.</td>
- </tr>
- <tr>
- <td>June 2010</td>
- <td>2.0</td>
- <td>Public release that breaks backward compatibility and drops deprecated features</td>
- </tr>
- <tr>
- <td>July 2010</td>
- <td>Ckpt</td>
- <td>Beta for testing new features.</td>
- </tr>
- <tr>
- <td>Aug 2010</td>
- <td>Ckpt</td>
- <td>Beta for testing new features.</td>
- </tr>
- <tr>
- <td>Sept 2010</td>
- <td>RC</td>
- <td>Release candidate for 2.1.</td>
- </tr>
- <tr>
- <td>Oct 2010</td>
- <td>2.1</td>
- <td>First minor release of v2</td>
- </tr>
-</table>
-
-<!--
-
-<h2>Upcoming Features</h2>
-
--->
-
-<h2>Release Planning</h2>
-
-<h3>Release numbering</h3>
-
-<p>
-Our release numbers are of the form <i>major</i>.<i>minor</i>.<i>revision</i>.
-</p>
-
-<ul>
-<li>
-<strong>Major release (1.0, 2.0, 3.0, etc.)</strong>
-<p>
-The major number increments when one of two things happens:
-</p>
- <ul>
- <li>The release knowingly breaks backwards compatibility in some way.
- <li>The release knowingly causes a rebuild when you upgrade.
- </ul>
-<p>
-Our goal is that as a user of SCons,
-you should always be able to upgrade to a later
-release of the same major version
-with complete confidence that your build will not break.
-We expect that our major releases will be long-lived platforms
-with many minor releases to add functionality and fix bugs.
-</p>
-</li>
-<li>
-<strong>Minor release (1.1, 1.2, 1.3, etc.)</strong>
-<p>
-Minor numbers increment for releases
-that add new functionality and/or bug fixes
-to an existing major release.
-Any new functionality will never knowingly break backwards compatibility
-with any previous minor releases from the same major release.
-</p>
-</li>
-<li>
-<strong>Bug-fix revisions (1.0.1, 1.1.1, 1.2.1, etc.)</strong>
-<p>
-Revision numbers are appended and/or incremented
-whenever a critical bug fix is necessary
-for a major or minor release.
-Because most new functionality and bug fixes
-will be delivered in minor releases,
-we expect that there will be few of these&mdash;at most
-one per minor release.
-</p>
-</li>
-<li>
-<strong>Release candidates (x.y.z.dyyyymmdd)</strong>
-<p>
-A release candidates is a special form of checkpoint
-(see below)
-that is expected to be the next major or minor release.
-If blocking issues show up in the candidate,
-another candidate will normally be issued
-(potentially delaying the release date),
-otherwise the candidate will be repackaged as the major or minor release.
-</p>
-</li>
-<li>
-<strong>Checkpoints (x.y.z.dyyyymmdd)</strong>
-<p>
-A checkpoint has a 'd<i>yyymmdd</i>' suffix
-and is made every couple of weeks between major or minor releases.
-It is intended for beta testing new features
-and for ensuring that bug fixes work as intended.
-Although existing features from the previous release will not change,
-compatibility of features under test is not guaranteed between checkpoints
-(<i>i.e.</i>, the implementation of the feature may change).
-Checkpoints are intended not only to allow for wider testing,
-but also to make new features available to users
-(who may urgently need one of them)
-in advance of them being published in the next major or minor release.
-</p>
-</li>
-</ul>
-
-</div>
-
-</body>
-</html>
diff --git a/www/schedule b/www/schedule
deleted file mode 100644
index 4b1e9eb..0000000
--- a/www/schedule
+++ /dev/null
@@ -1,19 +0,0 @@
-#=2008-09-13 1.0.1
-#=2008-10-01 Release candidate for 1.1.
-#=2008-10-10 1.1.0
-=2008-12-01 1.1.0
-+4 rc Release candidate for 1.2. (released 7-Dec)
-+7 1.2 Second minor release of 1.0. (released 21-Dec)
-+17 ck Beta for testing new features.
-+14 ck Beta for testing new features.
-+7 rc Release candidate for 1.3.
-+7 1.3 Third minor release of 1.0.
-+7 ck Beta for 2.0; breaks backward compatibility
-#+7 ck Beta for 2.0.
-+7 rc Release candidate for 2.0.
-+7 rc Release candidate for 2.0, if needed.
-+7 2.0 Public release that breaks backward compatibility and drops deprecated features
-+21 ck Beta for testing new features.
-+21 ck Beta for testing new features.
-+21 rc Release candidate for 2.1.
-+7 2.1 First minor release of 2.0