From ec8c484f8ed251275337d054854159a1e65f992c Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Mon, 14 Oct 2002 05:24:03 +0000 Subject: Allow new Reading --- doc/man/scons.1 | 91 +++++++++++++++++++++++++++---------- src/CHANGES.txt | 2 +- src/engine/SCons/Script/__init__.py | 46 +++++++++++++------ test/option--Q.py | 60 ++++++++++++++++++++++++ test/option-s.py | 6 +-- 5 files changed, 163 insertions(+), 42 deletions(-) create mode 100644 test/option--Q.py diff --git a/doc/man/scons.1 b/doc/man/scons.1 index b090ff6..6b3aabd 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -61,7 +61,8 @@ searches for a file named or .I sconstruct (in that order) in the current directory and reads its -configuration from the first file found. An alternate file name may be +configuration from the first file found. +An alternate file name may be specified via the .B -f option. If the specified file is not @@ -70,13 +71,44 @@ in the local directory, will internally change its working directory (chdir) to the directory containing the file. -The configuration file specifies the files to be built, and -(optionally) the rules to build those files. Reasonable default +The configuration files +(generically referred to as +.I SConscript +files) +specify the target files to be built, and +(optionally) the rules to build those targets. Reasonable default rules exist for building common software components (executable -programs, object files, libraries), so that for simple software +programs, object files, libraries), so that for most software projects, only the target and input files need be specified. .B scons +reads and executes the SConscript files as Python scripts, +so you may use normal Python scripting capabilities +(such as flow control, data manipulation, and imported Python libraries) +to handle complicated build situations. +.BR scons , +however, reads all of the SConscript files +.I before +it begins building any targets. +To make this obvious, +.B scons +prints the following messages about what it is doing: + +.ES +$ scons foo.out +scons: Reading SConscript files ... +scons: done reading SConscript files. +scons: Building targets ... +cp foo.in foo.out +scons: done building targets. +$ +.EE + +These status messages may be suppressed using the +.B -Q +option. + +.B scons can scan known input files automatically for dependency information (for example, #include statements in C or C++ files) and will rebuild dependent files appropriately @@ -111,7 +143,7 @@ scons foo bar Targets may be omitted from the command line, in which case the targets specified -in the configuration file(s) as +in the SConscript file(s) as .B Default targets will be built: @@ -119,7 +151,7 @@ targets will be built: scons .EE -Specifying "cleanup" targets in configuration files is not +Specifying "cleanup" targets in SConscript files is not necessary. The .B -c flag removes all files @@ -172,7 +204,7 @@ scons -j 4 builds four targets in parallel, for example. -Values of variables to be passed to the configuration file(s) +Values of variables to be passed to the SConscript file(s) may be specified on the command line: .ES @@ -181,7 +213,7 @@ scons debug=1 . These variables are available in SConscript files through the ARGUMENTS dictionary, -and can be used in the configuration file(s) to modify +and can be used in the SConscript file(s) to modify the build in any way: .ES @@ -194,7 +226,7 @@ else: .\" .B scons .\" can maintain a cache of target (derived) files that can .\" be shared between multiple builds. When caching is enabled in a -.\" configuration file, any target files built by +.\" SConscript file, any target files built by .\" .B scons .\" will be copied .\" to the cache. If an up-to-date target file is found in the cache, it @@ -250,7 +282,7 @@ command is specified. .\" --cache-disable, --no-cache .\" Disable caching. Will neither retrieve files from cache nor flush .\" files to cache. Has no effect if use of caching is not specified -.\" in a configuration file. +.\" in an SConscript file. .\" .\" .TP .\" --cache-force, --cache-populate @@ -348,14 +380,14 @@ SConscript files, and the total time spent executing SCons itself. .TP -e, --environment-overrides Variables from the execution environment override construction -variables from the configuration files. +variables from the SConscript files. .TP .RI -f " file" ", --file=" file ", --makefile=" file ", --sconstruct=" file Use .I file -as the initial configuration -file. If +as the initial SConscript file. +If .I file is in another directory, .B scons @@ -364,7 +396,7 @@ will change to that directory before building targets. .TP -h, --help Print a local help message for this build, if one is defined in -the configuration file(s), plus a line that describes the +the SConscript file(s), plus a line that describes the .B -H option for command-line option help. If no local help message is defined, prints the standard help message about command-line @@ -496,7 +528,7 @@ any out-of-date target files, but do not execute the commands. .\" -p .\" Print the data base (construction environments, .\" Builder and Scanner objects) that are defined -.\" after reading the configuration files. +.\" after reading the SConscript files. .\" After printing, a normal build is performed .\" as usual, as specified by other command-line options. .\" This also prints version information @@ -522,6 +554,14 @@ pstats module. Do not run any commands, or print anything. Just return an exit status that is zero if the specified targets are already up to date, non-zero otherwise. +.TP +-Q +Quiets SCons status messages about +reading SConscript files, +building targets +and entering directories. +Commands that are executed +to rebuild target files are still printed. .\" .TP .\" -r, -R, --no-builtin-rules, --no-builtin-variables @@ -539,6 +579,7 @@ date, non-zero otherwise. -s, --silent, --quiet Silent. Do not print commands that are executed to rebuild target files. +Also suppresses SCons status messages. .TP -S, --no-keep-going, --stop @@ -645,7 +686,7 @@ repositories are searched in the order specified. .\" .SS Python Basics .\" XXX Adding this in the future would be a help. .SS Construction Environments -A construction environment is the basic means by which the configuration +A construction environment is the basic means by which the SConscript files communicate build information to .BR scons . A new construction environment is created using the @@ -2047,7 +2088,7 @@ locations, or site-specific compiler options may need to be passed to the compiler. .B scons provides a mechanism for overridding construction variables from the -command line or a text based configuration file through an Options +command line or a text-based SConscript file through an Options object. To create an Options object, call the Options() function: .TP @@ -2107,7 +2148,7 @@ of customizable variables. Example: Help(opts.GenerateHelpText(env)) .EE -The text based configuration file is executed as a Python script, and the +The text based SConscript file is executed as a Python script, and the global variables are queried for customizable construction variables. Example: @@ -2120,7 +2161,7 @@ CC = 'my_cc' .B scons also provides various additional functions, not associated with a construction environment, -that configuration files can use: +that SConscript files can use: .TP .RI BuildDir( build_dir ", " src_dir ", [" duplicate ]) @@ -2231,7 +2272,7 @@ EnsureSConsVersion(0,9) This tells .B scons to export a list of variables from the current -configuration file to all other configuration files. The exported variables +SConscript file to all other SConscript files. The exported variables are kept in a global collection, so subsequent exports will over-write previous exports that have the same name. Multiple variable names should be passed to @@ -2265,7 +2306,7 @@ will exit after printing out the help text. .RI Import( vars ) This tells .B scons -to import a list of variables into the current configuration file. This +to import a list of variables into the current SConscript file. This will import variables that were exported with .BR Export () or in the @@ -2300,8 +2341,8 @@ env = Environment(platform = Platform('win32')) .RI Return( vars ) This tells .B scons -what variable(s) to use as the return value(s) of the current configuration -file. These variables will be returned to the "calling" configuration file +what variable(s) to use as the return value(s) of the current SConscript +file. These variables will be returned to the "calling" SConscript file as the return value(s) of .BR SConscript (). Multiple variable names should be passed to @@ -2319,7 +2360,7 @@ This tells .B scons to execute .I script -as a configuration file. The optional +as a SConscript (configuration) file. The optional .I exports argument provides a list of variable names to export to .IR script ". " @@ -2348,7 +2389,7 @@ this instructs .B scons to change its working directory (chdir) to the directory in which each subsidiary -configure (SConscript) file lives. +SConscript file lives. Note that you may enable and disable this ability by calling SConscriptChdir() diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 265b19e..42ce7e8 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -43,7 +43,7 @@ RELEASE 0.09 - - Add explicit messages to tell when we're "Reading SConscript files ...," "done reading SConscript files," "Building targets," and - "done building targets." + "done building targets." Add a -Q option to supress these. - Add separate $SHOBJPREFIX and $SHOBJSUFFIX construction variables (by default, the same as $OBJPREFIX and $OBJSUFFIX). diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 9fd1327..65d900c 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -76,7 +76,7 @@ class BuildTask(SCons.Taskmaster.Task): def execute(self): if self.targets[0].get_state() == SCons.Node.up_to_date: if self.top: - print 'scons: "%s" is up to date.' % str(self.targets[0]) + display('scons: "%s" is up to date.' % str(self.targets[0])) else: try: self.targets[0].prepare() @@ -130,7 +130,7 @@ class CleanTask(SCons.Taskmaster.Task): """An SCons clean task.""" def show(self): if self.targets[0].builder or self.targets[0].side_effect: - print "Removed " + str(self.targets[0]) + display("Removed " + str(self.targets[0])) def remove(self): if self.targets[0].builder or self.targets[0].side_effect: @@ -141,7 +141,7 @@ class CleanTask(SCons.Taskmaster.Task): print "scons: Could not remove '%s':" % str(t), e.strerror else: if removed: - print "Removed " + str(t) + display("Removed " + str(t)) execute = remove @@ -179,6 +179,12 @@ profiling = 0 max_drift = None repositories = [] +# +def print_it(text): + print text + +display = print_it + # Exceptions for this module class PrintHelp(Exception): pass @@ -546,7 +552,7 @@ def options_init(): Option(func = opt_implicit_cache, long = ['implicit-cache'], - help = "Cache implicit dependencies") + help = "Cache implicit (scanned) dependencies.") def opt_implicit_deps_changed(opt, arg): import SCons.Node @@ -555,7 +561,7 @@ def options_init(): Option(func = opt_implicit_deps_changed, long = ['implicit-deps-changed'], - help = "Ignore the cached implicit deps.") + help = "Ignore the cached implicit dependencies.") def opt_implicit_deps_unchanged(opt, arg): import SCons.Node @@ -564,7 +570,7 @@ def options_init(): Option(func = opt_implicit_deps_unchanged, long = ['implicit-deps-unchanged'], - help = "Ignore changes in implicit deps.") + help = "Ignore changes in implicit dependencies.") def opt_j(opt, arg): global num_jobs @@ -650,11 +656,21 @@ def options_init(): long = ['profile'], arg = 'FILE', help = "Profile SCons and put results in FILE.") + def opt_Q(opt, arg): + global display + def dont_print_it(text): + pass + display = dont_print_it + + Option(func = opt_Q, + short = 'Q', + help = "Don't print SCons progress messages.") + def opt_q(opt, arg): global task_class task_class = QuestionTask - Option(func = opt_q, future = 1, + Option(func = opt_q, short = 'q', long = ['question'], help = "Don't build; exit status says if up to date.") @@ -667,6 +683,10 @@ def options_init(): help = "Build dependencies in random order.") def opt_s(opt, arg): + global display + def dont_print_it(text): + pass + display = dont_print_it SCons.Action.print_actions = None Option(func = opt_s, @@ -901,7 +921,7 @@ def _main(): else: script_dir = '' if script_dir: - print "scons: Entering directory %s" % script_dir + display("scons: Entering directory %s" % script_dir) os.chdir(script_dir) else: raise UserError, "No SConstruct file found." @@ -944,7 +964,7 @@ def _main(): for rep in repositories: SCons.Node.FS.default_fs.Repository(rep) - print "scons: Reading SConscript files ..." + display("scons: Reading SConscript files ...") try: start_time = time.time() for script in scripts: @@ -952,12 +972,12 @@ def _main(): global sconscript_time sconscript_time = time.time() - start_time except PrintHelp, text: - print "scons: done reading SConscript files." + display("scons: done reading SConscript files.") print text print "Use scons -H for help about command-line options." sys.exit(0) - print "scons: done reading SConscript files." + display("scons: done reading SConscript files.") SCons.Node.FS.default_fs.chdir(SCons.Node.FS.default_fs.Top) @@ -1025,7 +1045,7 @@ def _main(): calc = SCons.Sig.default_calc - print "scons: Building targets ..." + display("scons: Building targets ...") taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, calc) jobs = SCons.Job.Jobs(num_jobs, taskmaster) @@ -1033,7 +1053,7 @@ def _main(): try: jobs.run() finally: - print "scons: done building targets." + display("scons: done building targets.") SCons.Sig.write() def main(): diff --git a/test/option--Q.py b/test/option--Q.py new file mode 100644 index 0000000..b89b042 --- /dev/null +++ b/test/option--Q.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path +import string +import sys +import TestSCons + +python = sys.executable + +test = TestSCons.TestSCons() + +test.write('build.py', r""" +import sys +file = open(sys.argv[1], 'wb') +file.write("build.py: %s\n" % sys.argv[1]) +file.close() +""") + +test.write('SConstruct', """ +MyBuild = Builder(action = r'%s build.py $TARGET') +env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) +env.MyBuild(target = 'f1.out', source = 'f1.in') +env.MyBuild(target = 'f2.out', source = 'f2.in') +""" % python) + +test.write('f1.in', "f1.in\n") +test.write('f2.in', "f2.in\n") + +test.run(arguments = '-Q f1.out f2.out', stdout = """\ +%s build.py f1.out +%s build.py f2.out +""" % (python, python)) +test.fail_test(not os.path.exists(test.workpath('f1.out'))) +test.fail_test(not os.path.exists(test.workpath('f2.out'))) + +test.pass_test() diff --git a/test/option-s.py b/test/option-s.py index 67155d4..450e994 100644 --- a/test/option-s.py +++ b/test/option-s.py @@ -50,21 +50,21 @@ env.MyBuild(target = 'f2.out', source = 'f2.in') test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") -test.run(arguments = '-s f1.out f2.out', stdout = test.wrap_stdout("")) +test.run(arguments = '-s f1.out f2.out', stdout = "") test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.fail_test(not os.path.exists(test.workpath('f2.out'))) test.unlink('f1.out') test.unlink('f2.out') -test.run(arguments = '--silent f1.out f2.out', stdout = test.wrap_stdout("")) +test.run(arguments = '--silent f1.out f2.out', stdout = "") test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.fail_test(not os.path.exists(test.workpath('f2.out'))) test.unlink('f1.out') test.unlink('f2.out') -test.run(arguments = '--quiet f1.out f2.out', stdout = test.wrap_stdout("")) +test.run(arguments = '--quiet f1.out f2.out', stdout = "") test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.fail_test(not os.path.exists(test.workpath('f2.out'))) -- cgit v0.12