From b2587b0facd446ceb35b440493835a9ee1d426fe Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 8 Jan 2022 12:51:01 -0700 Subject: Update manpage "Extending SCons" section. [skip appveyor] Now organized into four sections: Builder Objects, Action Objects, Scanner Objects, Tool Modules, with the latter (new) section getting a lot of the material that was in the Tools section (which users dodn't need just to select an existing tool). Adds a bit of commentary to the beginning of the section, and to Builder and Scanner. Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 408 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 232 insertions(+), 176 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 517ce41..fc2e24d 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -1202,11 +1202,11 @@ database with name .sconsign_sha256.dblite. If this option is not specified, a the first supported hash format found is selected. Typically this is MD5, however, if you are on a FIPS-compliant system and using a version of Python less than 3.9, SHA1 or SHA256 will be chosen as the default. -Python 3.9 and onwards clients will always default to MD5, even in FIPS mode, unless +Python 3.9 and onwards clients will always default to MD5, even in FIPS mode, unless otherwise specified with the option. -For MD5 databases (either explicitly specified with or -defaulted), the SConsign database is.sconsign.dblite. The newer SHA1 and +For MD5 databases (either explicitly specified with or +defaulted), the SConsign database is.sconsign.dblite. The newer SHA1 and SHA256 selections meanwhile store their databases to .sconsign_algorithmname.dblite Available since &scons; 4.2. @@ -2519,11 +2519,11 @@ See for details. Tools -&SCons; has a large number of predefined tools -(more properly, tool specifications) +&SCons; has a large number of predefined tool modules +(more properly, tool specification modules) which are used to help initialize the &consenv;. An &SCons; tool is only responsible for setup. -For example, if the &SConscript; file declares +For example, if an SConscript file declares the need to construct an object file from a C-language source file by calling the &b-link-Object; builder, then a tool representing @@ -2531,8 +2531,8 @@ an available C compiler needs to have run first, to set up that builder and all the &consvars; it needs in the associated &consenv;; the tool itself is not called in the process of the build. Normally this -happens invisibly: &scons; has per-platform -lists of default tools, and it runs through those tools, +happens invisibly as &scons; has per-platform +lists of default tools, and it steps through those tools, calling the ones which are actually applicable, skipping those where necessary programs are not installed on the build system, or other preconditions are not met. @@ -2582,152 +2582,10 @@ Changing the PATH variable after the &consenv; is constructed will not cause the tools to be re-detected. - -Additional tools can be added to a project either by -placing them in a site_tools subdirectory -of a site directory, or in a custom location specified to -&scons; by giving the -toolpath keyword argument. -toolpath also takes a list as its value: - - - -env = Environment(tools=['default', 'foo'], toolpath=['tools']) - - - -This looks for a tool specification module foo.py -in directory tools and in the standard locations, -as well as using the ordinary default tools for the platform. - - - -Directories specified via toolpath are prepended -to the existing tool path. The default tool path is any site_tools -directories, so tools in a specified toolpath -take priority, -followed by tools in a site_tools directory, -followed by built-in tools. For example, adding -a tool specification module gcc.py to the toolpath -directory would override the built-in &t-link-gcc; tool. -The tool path is -stored in the environment and will be -used by subsequent calls to the &f-link-Tool; method, -as well as by &f-link-env-Clone;. - - - -base = Environment(toolpath=['custom_path']) -derived = base.Clone(tools=['custom_tool']) -derived.CustomBuilder() - - - -A tool specification module must include two functions: - - - - - generate(env, **kwargs) - -Modifies the environment referenced by env -to set up variables so that the facilities represented by -the tool can be executed. -It may use any keyword arguments -that the user supplies in kwargs -to vary its initialization. - - - - exists(env) - -Return True if the tool can -be called in the context of env. -Usually this means looking up one or more -known programs using the PATH from the -supplied env, but the tool can -make the "exists" decision in any way it chooses. +Additional tools can be added, see the +Extending SCons section +and specifically Tool Modules. - - - - - - -At the moment, user-added tools do not automatically have their -exists function called. -As a result, it is recommended that the generate -function be defensively coded - that is, do not rely on any -necessary existence checks already having been performed. -This is expected to be a temporary limitation, -and the exists function should still be provided. - - - -The elements of the tools list may also -be functions or callable objects, -in which case the &Environment; method -will call those objects -to update the new &consenv; (see &f-link-Tool; for more details): - - -def my_tool(env): - env['XYZZY'] = 'xyzzy' - -env = Environment(tools=[my_tool]) - - -The individual elements of the tools list -may also themselves be lists or tuples of the form -(toolname, kw_dict). -SCons searches for the -toolname -specification file as described above, and -passes -kw_dict, -which must be a dictionary, as keyword arguments to the tool's -generate -function. -The -generate -function can use the arguments to modify the tool's behavior -by setting up the environment in different ways -or otherwise changing its initialization. - - -# in tools/my_tool.py: -def generate(env, **kwargs): - # Sets MY_TOOL to the value of keyword 'arg1' '1' if not supplied - env['MY_TOOL'] = kwargs.get('arg1', '1') - -def exists(env): - return True - -# in SConstruct: -env = Environment(tools=['default', ('my_tool', {'arg1': 'abc'})], - toolpath=['tools']) - - -The tool specification (my_tool in the example) -can use the -PLATFORM variable from -the &consenv; it is passed to customize the tool for different platforms. - -Tools can be "nested" - that is, they -can be located within a subdirectory in the toolpath. -A nested tool name uses a dot to represent a directory separator - - -# namespaced builder -env = Environment(ENV=os.environ.copy(), tools=['SubDir1.SubDir2.SomeTool']) -env.SomeTool(targets, sources) - -# Search Paths -# SCons\Tool\SubDir1\SubDir2\SomeTool.py -# SCons\Tool\SubDir1\SubDir2\SomeTool\__init__.py -# .\site_scons\site_tools\SubDir1\SubDir2\SomeTool.py -# .\site_scons\site_tools\SubDir1\SubDir2\SomeTool\__init__.py - SCons supports the following tool specifications out of the box: @@ -5264,6 +5122,30 @@ css = index.File('app.css') EXTENDING SCONS + +&SCons; is designed to be extensible through provided facilities, +so changing the code of &SCons; itself is only rarely needed +to customize its behavior. +A number of the main operations use callable objects +which can be supplemented by writing your own. +Builders, Scanners and Tools each use a kind of plugin system, +allowing you to seamlessly drop in new ones. +Information about creating +Builder Objects and +Scanner Objects +appear in the following sections. +The instructions &SCons; actually uses to make things are called +Actions, and it is easy to create Action Objects and hand them +to the objects that need to know about those actions +(besides Builders, see &f-link-AddPostAction;, +&f-link-AddPreAction; and &f-link-Alias; for some examples +of other places that take Actions). +Action Objects +are also described below. +Adding new Tool modules is described in +Tool Modules + + Builder Objects @@ -5292,7 +5174,10 @@ factory function. Once created, a builder is added to an environment by entering it in the &cv-link-BUILDERS; dictionary in that environment (some of the examples -in this section illustrate that). +in this section illustrate this). +Doing so automatically triggers &SCons; to add a method +with the name of the builder to the environment. + The @@ -5315,7 +5200,7 @@ any combination of command line strings (if the builder should accept multiple source file extensions), a Python function, an Action object -(see ) +(see Action Objects) or a list of any of the above. An action function must accept three arguments: @@ -5543,7 +5428,7 @@ env.Collect('archive', ['directory_name', 'file_name']) - + emitter A function or list of functions to manipulate the target and source @@ -5640,7 +5525,7 @@ used to call the Builder for the target file.) - + generator A function that returns a list of actions that will be executed to build @@ -5859,9 +5744,11 @@ result of the call). These extra keyword arguments are passed to the following functions: -command generator functions, -function Actions, -and emitter functions. +command generator functions, +function Actions, +and +emitter functions. + @@ -6048,7 +5935,7 @@ with the same interpretation as for a callable -If outputis None, +If outputis None, output is suppressed entirely. @@ -6288,9 +6175,8 @@ a = Action('build $CHANGED_SOURCES', batch_key=batch_key) - - + Miscellaneous Action Functions &SCons; @@ -6519,9 +6405,9 @@ env.Command('marker', 'input_file', action=[MyBuildAction, Touch('$TARGET')]) - + - + Variable Substitution Before executing a command, @@ -6758,7 +6644,7 @@ All text between and $) will be removed from the command line -before it is added to the build (action) signature, +before it is added to the build action signature, and the $( and @@ -6849,9 +6735,9 @@ class foo: # Will expand $BAR to "my argument bar baz" env=Environment(FOO=foo, BAR="${FOO('my argument')} baz") - + - + Python Code Substitution @@ -6971,6 +6857,7 @@ Although &SCons; makes use of it in a somewhat restricted context, you should be aware of this issue when using the ${python-expression-for-subst} form. + @@ -6984,8 +6871,8 @@ that cause other files to be included during processing. &SCons; has a number of pre-built Scanner objects, so it is usually only necessary to set up Scanners for new file types. You do this by calling the &f-link-Scanner; factory function. -&f-Scanner; accepts the following arguments, -only function is required, +&f-Scanner; accepts the following arguments. +Only function is required; the rest are optional: @@ -7200,15 +7087,21 @@ Nodes for additional scanning. -Note that -&scons; -has a global + + +Once created, a Scanner can added to an environment +by setting it in the &cv-link-SCANNERS; list, +which automatically triggers &SCons; to also add it +to the environment as a method. +However, usually a scanner is not truly standalone, but needs to +be plugged in to the existing selection mechanism for +deciding how to scan source files based on filename extensions. +For this, &SCons; has a global SourceFileScanner object that is used by the &b-link-Object;, &b-link-SharedObject; and &b-link-StaticObject; builders to decide -which scanner should be used -for different file extensions. +which scanner should be used. You can use the SourceFileScanner.add_scanner() method to add your own Scanner object @@ -7232,6 +7125,169 @@ env.Program('my_prog', ['file1.c', 'file2.f', 'file3.xyz']) + + +Tool Modules + + +Additional tools can be added to a project either by +placing them in a site_tools subdirectory +of a site directory, or in a custom location specified to +&scons; by giving the +toolpath keyword argument to &f-link-Environment;. +A tool module is a form of Python module, invoked internally +using the Python import mechanism, so a tool can consist either +of a single source file taking the name of the tool +(e.g. mytool.py) or a directory taking +the name of the tool (e.g. mytool/) +which contains at least an __init__.py file. + + + +The toolpath parameter +takes a list as its value: + + + +env = Environment(tools=['default', 'foo'], toolpath=['tools']) + + + +This looks for a tool specification module (mytool.py, +or directory mytool) +in directory tools and in the standard locations, +as well as using the ordinary default tools for the platform. + + + +Directories specified via toolpath are prepended +to the existing tool path. +The default tool path is any site_tools directories, +so tools in a specified toolpath take priority, +followed by tools in a site_tools directory, +followed by built-in tools. For example, adding +a tool specification module gcc.py to the toolpath +directory would override the built-in &t-link-gcc; tool. +The tool path is stored in the environment and will be +used by subsequent calls to the &f-link-Tool; method, +as well as by &f-link-env-Clone;. + + + +base = Environment(toolpath=['custom_path']) +derived = base.Clone(tools=['custom_tool']) +derived.CustomBuilder() + + + +A tool specification module must include two functions: + + + + + generate(env, **kwargs) + +Modifies the &consenv; env +to set up necessary &consvars; so that the facilities represented by +the tool can be executed. +It may use any keyword arguments +that the user supplies in kwargs +to vary its initialization. + + + + exists(env) + +Returns True if the tool can +be called in the context of env. +Usually this means looking up one or more +known programs using the PATH from the +supplied env, but the tool can +make the "exists" decision in any way it chooses. + + + + + + + +At the moment, user-added tools do not automatically have their +exists function called. +As a result, it is recommended that the generate +function be defensively coded - that is, do not rely on any +necessary existence checks already having been performed. +This is expected to be a temporary limitation, +and the exists function should still be provided. + + + +The elements of the tools list may also +be functions or callable objects, +in which case the &Environment; method +will call those objects +to update the new &consenv; (see &f-link-Tool; for more details): + + +def my_tool(env): + env['XYZZY'] = 'xyzzy' + +env = Environment(tools=[my_tool]) + + +The individual elements of the tools list +may also themselves be lists or tuples of the form +(toolname, kw_dict). +SCons searches for the +toolname +specification file as described above, and +passes +kw_dict, +which must be a dictionary, as keyword arguments to the tool's +generate +function. +The +generate +function can use the arguments to modify the tool's behavior +by setting up the environment in different ways +or otherwise changing its initialization. + + +# in tools/my_tool.py: +def generate(env, **kwargs): + # Sets MY_TOOL to the value of keyword 'arg1' '1' if not supplied + env['MY_TOOL'] = kwargs.get('arg1', '1') + +def exists(env): + return True + +# in SConstruct: +env = Environment(tools=['default', ('my_tool', {'arg1': 'abc'})], + toolpath=['tools']) + + +The tool specification (my_tool in the example) +can use the +&cv-link-PLATFORM; variable from +the &consenv; it is passed to customize the tool for different platforms. + + +Tools can be "nested" - that is, they +can be located within a subdirectory in the toolpath. +A nested tool name uses a dot to represent a directory separator + + +# namespaced builder +env = Environment(ENV=os.environ.copy(), tools=['SubDir1.SubDir2.SomeTool']) +env.SomeTool(targets, sources) + +# Search Paths +# SCons\Tool\SubDir1\SubDir2\SomeTool.py +# SCons\Tool\SubDir1\SubDir2\SomeTool\__init__.py +# .\site_scons\site_tools\SubDir1\SubDir2\SomeTool.py +# .\site_scons\site_tools\SubDir1\SubDir2\SomeTool\__init__.py + + + @@ -7332,7 +7388,7 @@ such as the python.org and ActiveState versions, do not have the Cygwin path name semantics. This means that using a native Windows version of Python to build compiled programs using Cygwin tools -(such as &gcc;, &bison; and flex) +(such as &gcc;, &bison; and &flex;) may yield unpredictable results. "Mixing and matching" in this way can be made to work, -- cgit v0.12 From 4bc626d18a0d71d8b0b2436d70f08cabae879bac Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 10 Jan 2022 16:18:36 -0700 Subject: ci fix: "flex" entity not checked in [skip appveyor] Signed-off-by: Mats Wichmann --- doc/scons.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/scons.mod b/doc/scons.mod index e8dc91c..6a2fd6b 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -59,6 +59,7 @@ Cons"> cp"> csh"> +flex"> f77"> f90"> f95"> -- cgit v0.12