diff options
Diffstat (limited to 'doc/user')
-rw-r--r-- | doc/user/MANIFEST | 1 | ||||
-rw-r--r-- | doc/user/build-install.xml | 49 | ||||
-rw-r--r-- | doc/user/builders-commands.xml | 66 | ||||
-rw-r--r-- | doc/user/command-line.xml | 195 | ||||
-rw-r--r-- | doc/user/environments.xml | 30 | ||||
-rw-r--r-- | doc/user/main.xml | 51 | ||||
-rw-r--r-- | doc/user/misc.xml | 3 | ||||
-rw-r--r-- | doc/user/output.xml | 2 | ||||
-rw-r--r-- | doc/user/parse_flags_arg.xml | 2 | ||||
-rw-r--r-- | doc/user/separate.xml | 179 | ||||
-rw-r--r-- | doc/user/sideeffect.xml | 208 | ||||
-rw-r--r-- | doc/user/simple.xml | 2 | ||||
-rw-r--r-- | doc/user/troubleshoot.xml | 4 | ||||
-rw-r--r-- | doc/user/variants.xml | 70 |
14 files changed, 482 insertions, 380 deletions
diff --git a/doc/user/MANIFEST b/doc/user/MANIFEST index d7237df..5be5aff 100644 --- a/doc/user/MANIFEST +++ b/doc/user/MANIFEST @@ -44,6 +44,7 @@ run.xml scanners.xml sconf.xml separate.xml +sideeffect.xml simple.xml tasks.xml tools.xml diff --git a/doc/user/build-install.xml b/doc/user/build-install.xml index 87a86aa..c106dc5 100644 --- a/doc/user/build-install.xml +++ b/doc/user/build-install.xml @@ -110,12 +110,13 @@ Python 3.7.1 </screen> <para> - Note to Windows users: there are many different ways Python - can get installed or invoked on Windows, it is beyond the scope - of this guide to unravel all of them. Try using the - <firstterm>Python launcher</firstterm> (see - <ulink url="https://www.python.org/dev/peps/pep-0397/">PEP 397</ulink>) - by using the name <command>py</command> instead of + Note to Windows users: there are a number of different ways Python + can be installed or invoked on Windows, it is beyond the scope + of this guide to unravel all of them. Many will have an additional + program called the <firstterm>Python launcher</firstterm> (described, + somewhat technically, in + <ulink url="https://www.python.org/dev/peps/pep-0397/">PEP 397</ulink>): + try using the command name <command>py</command> instead of <command>python</command>, if that is not available drop back to trying <command>python</command>. </para> @@ -129,21 +130,23 @@ Python 3.7.1 If Python is not installed on your system, or is not findable in the current search path, you will see an error message - stating something like "command not found" + stating something like <computeroutput>"command not found"</computeroutput> (on UNIX or Linux) - or "'python' is not recognized - as an internal or external command, operable progam or batch file" + or <computeroutput>"'python' is not recognized as an internal + or external command, operable progam or batch file"</computeroutput> (on Windows <command>cmd</command>). - In that case, you need to install Python - (or fix the search path) + In that case, you need to either install Python + or fix the search path before you can install &SCons;. </para> <para> - The canonical location for information - about downloading and installing Python is - <ulink url="http://www.python.org/download/">http://www.python.org/download/</ulink>. - See that page and associated links to get started. + The canonical location for downloading Python + from Python's own website is: + <ulink url="https://www.python.org/download">https://www.python.org/download</ulink>. + There are useful system-specific entries on setup and + usage to be found at: + <ulink url="https://docs.python.org/3/using">https://docs.python.org/3/using</ulink> </para> <para> @@ -153,7 +156,7 @@ Python 3.7.1 by other means, and is easier than installing from source code. Many such systems have separate packages for Python 2 and Python 3 - make sure the Python 3 package is - installed, as &SCons; requires it. + installed, as the latest &SCons; requires it. Building from source may still be a useful option if you need a version that is not offered by the distribution you are using. @@ -195,7 +198,7 @@ Python 3.7.1 For those users using Anaconda or Miniconda, use the <command>conda</command> installer instead, so the &scons; install location will match the version of Python that - system will be using: + system will be using. For example: </para> <screen> @@ -211,14 +214,14 @@ Python 3.7.1 During the still-ongoing Python 2 to 3 transition, some distributions may still have two &SCons; packages available, one which uses Python 2 and one which uses Python 3. Since - latest &scons; only runs on Python 3, to get the current version + the latest &scons; only runs on Python 3, to get the current version you should choose the Python 3 package. </para> <para> If you need a specific version of &SCons; that is different from the package available, - <filename>pip</filename> has a version option or you can follow + <systemitem>pip</systemitem> has a version option or you can follow the instructions in the next section. </para> @@ -229,9 +232,9 @@ Python 3.7.1 <para> If a pre-built &SCons; package is not available for your system, - and installing using <filename>pip</filename> is not suitable, + and installing using <systemitem>pip</systemitem> is not suitable, then you can still easily build and install &SCons; using the native - Python <filename>distutils</filename> package. + Python <systemitem>setuptools</systemitem> package. </para> <para> @@ -265,11 +268,11 @@ Python 3.7.1 install the &scons; script in the python which is used to run the setup.py's scripts directory (<filename>/usr/local/bin</filename> or - <filename>C:\Python27\Scripts</filename>), + <filename>C:\Python37\Scripts</filename>), and will install the &SCons; build engine in the corresponding library directory for the python used (<filename>/usr/local/lib/scons</filename> or - <filename>C:\Python27\scons</filename>). + <filename>C:\Python37\scons</filename>). Because these are system directories, you may need root (on Linux or UNIX) or Administrator (on Windows) privileges to install &SCons; like this. diff --git a/doc/user/builders-commands.xml b/doc/user/builders-commands.xml index 5d378b3..7d47dae 100644 --- a/doc/user/builders-commands.xml +++ b/doc/user/builders-commands.xml @@ -81,7 +81,7 @@ if you only need to execute one specific command to build a single file (or group of files). For these situations, &SCons; supports a - &Command; &Builder; that arranges + &f-link-Command; builder that arranges for a specific action to be executed to build a specific file or files. This looks a lot like the other builders @@ -119,7 +119,7 @@ foo.in This is often more convenient than creating a &Builder; object and adding it to the &cv-link-BUILDERS; variable - of a &consenv; + of a &consenv;. </para> @@ -134,9 +134,11 @@ foo.in <scons_example name="builderscommands_ex2"> <file name="SConstruct" printme="1"> env = Environment() + def build(target, source, env): # Whatever it takes to build return None + env.Command('foo.out', 'foo.in', build) </file> <file name="foo.in"> @@ -157,8 +159,7 @@ foo.in <para> Note that &cv-link-SOURCE; and &cv-link-TARGET; are expanded - in the source and target as well as of SCons 1.1, - so you can write: + in the source and target as well, so you can write: </para> @@ -168,7 +169,6 @@ env.Command('${SOURCE.basename}.out', 'foo.in', build) </file> </scons_example> - <para> which does the same thing as the previous example, but allows you @@ -176,5 +176,61 @@ env.Command('${SOURCE.basename}.out', 'foo.in', build) </para> + <para> + + It may be helpful to use the <parameter>action</parameter> + keyword to specify the action, is this makes things more clear + to the reader: + + </para> + + <scons_example name="builderscommands_ex4"> + <file name="SConstruct" printme="1"> +env.Command('${SOURCE.basename}.out', 'foo.in', action=build) + </file> + </scons_example> + + <para> + + The method described in + <xref linkend="sect-controlling-build-output"/> for controlling + build output works well when used with pre-defined builders which + have pre-defined <literal>*COMSTR</literal> variables for that purpose, + but that is not the case when calling &f-Command;, + where &SCons; has no specific knowledge of the action ahead of time. + If the action argument to &f-Command; is not already an &Action; object, + it will construct one for you with suitable defaults, + which include a message based on the type of action. + However, you can also construct the &Action; object yourself + to pass to &f-Command;, which gives you much more control. + Here's an evolution of the example from above showing this approach: + + </para> + + <scons_example name="builderscommands_ex5"> + <file name="SConstruct" printme="1"> +env = Environment() + +def build(target, source, env): + # Whatever it takes to build + return None + +act = Action(build, cmdstr="Building ${TARGET}") +env.Command('foo.out', 'foo.in', action=act) + </file> + <file name="foo.in"> +foo.in + </file> + </scons_example> + + <para> + + Which executes as follows: + + </para> + + <scons_output example="builderscommands_ex5" suffix="1"> + <scons_output_command>scons -Q</scons_output_command> + </scons_output> </chapter> diff --git a/doc/user/command-line.xml b/doc/user/command-line.xml index 6910290..8db9230 100644 --- a/doc/user/command-line.xml +++ b/doc/user/command-line.xml @@ -174,8 +174,8 @@ def b(target, source, env): pass def s(target, source, env): return " ... [build output] ..." -a = Action(b, strfunction = s) -env = Environment(BUILDERS = {'A' : Builder(action=a)}) +a = Action(b, strfunction=s) +env = Environment(BUILDERS={'A': Builder(action=a)}) env.A('foo.out', 'foo.in') </file> <file name="foo.in"> @@ -330,7 +330,7 @@ if not GetOption('help'): import os num_cpu = int(os.environ.get('NUM_CPU', 2)) SetOption('num_jobs', num_cpu) -print("running with -j %s"%GetOption('num_jobs')) +print("running with -j %s" % GetOption('num_jobs')) </file> <file name="foo.in"> foo.in @@ -347,9 +347,9 @@ foo.in where the string is spelled differently from the from command-line option. The string for fetching or setting the <option>--jobs</option> - value is <literal>num_jobs</literal> + value is <parameter>num_jobs</parameter> for historical reasons.) - The code in this example prints the <literal>num_jobs</literal> + The code in this example prints the <parameter>num_jobs</parameter> value for illustrative purposes. It uses a default value of <literal>2</literal> to provide some minimal parallelism even on @@ -817,7 +817,7 @@ foo.in env = Environment() debug = ARGUMENTS.get('debug', 0) if int(debug): - env.Append(CCFLAGS = '-g') + env.Append(CCFLAGS='-g') env.Program('prog.c') </file> <file name="prog.c"> @@ -847,7 +847,7 @@ prog.c the last values used to build the object files, and as a result correctly rebuilds the object and executable files - only when the value of the <literal>debug</literal> + only when the value of the <parameter>debug</parameter> argument has changed. </para> @@ -1265,9 +1265,7 @@ vars = Variables('custom.py', ARGUMENTS) <scons_example name="commandline_BoolVariable"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(BoolVariable('RELEASE', - help='Set to build for release', - default=0)) +vars.Add(BoolVariable('RELEASE', help='Set to build for release', default=0)) env = Environment(variables=vars, CPPDEFINES={'RELEASE_BUILD': '${RELEASE}'}) env.Program('foo.c') </file> @@ -1348,7 +1346,7 @@ foo.c </section> <section> - <title>Single Value From a List: the &EnumVariable; Build Variable Function</title> + <title>Single Value From a Selection: the &EnumVariable; Build Variable Function</title> <para> @@ -1370,10 +1368,14 @@ foo.c <scons_example name="commandline_EnumVariable"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(EnumVariable('COLOR', - help='Set background color', - default='red', - allowed_values=('red', 'green', 'blue'))) +vars.Add( + EnumVariable( + 'COLOR', + help='Set background color', + default='red', + allowed_values=('red', 'green', 'blue'), + ) +) env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'}) env.Program('foo.c') Help(vars.GenerateHelpText(env)) @@ -1440,11 +1442,15 @@ foo.c <scons_example name="EnumVariable_map"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(EnumVariable('COLOR', - help='Set background color', - default='red', - allowed_values=('red', 'green', 'blue'), - map={'navy':'blue'})) +vars.Add( + EnumVariable( + 'COLOR', + help='Set background color', + default='red', + allowed_values=('red', 'green', 'blue'), + map={'navy': 'blue'}, + ) +) env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'}) env.Program('foo.c') </file> @@ -1496,13 +1502,17 @@ foo.c <scons_example name="commandline_EnumVariable_ic1"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(EnumVariable('COLOR', - help='Set background color', - default='red', - allowed_values=('red', 'green', 'blue'), - map={'navy':'blue'}, - ignorecase=1)) -env = Environment(variables=vars, CPPDEFINES={'COLOR':'"${COLOR}"'}) +vars.Add( + EnumVariable( + 'COLOR', + help='Set background color', + default='red', + allowed_values=('red', 'green', 'blue'), + map={'navy': 'blue'}, + ignorecase=1, + ) +) +env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'}) env.Program('foo.c') </file> <file name="foo.c"> @@ -1537,12 +1547,16 @@ foo.c <scons_example name="commandline_EnumVariable_ic2"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(EnumVariable('COLOR', - help='Set background color', - default='red', - allowed_values=('red', 'green', 'blue'), - map={'navy':'blue'}, - ignorecase=2)) +vars.Add( + EnumVariable( + 'COLOR', + help='Set background color', + default='red', + allowed_values=('red', 'green', 'blue'), + map={'navy': 'blue'}, + ignorecase=2, + ) +) env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'}) env.Program('foo.c') </file> @@ -1587,10 +1601,11 @@ foo.c <scons_example name="commandline_ListVariable"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(ListVariable('COLORS', - help='List of colors', - default=0, - names=['red', 'green', 'blue'])) +vars.Add( + ListVariable( + 'COLORS', help='List of colors', default=0, names=['red', 'green', 'blue'] + ) +) env = Environment(variables=vars, CPPDEFINES={'COLORS': '"${COLORS}"'}) env.Program('foo.c') </file> @@ -1639,6 +1654,29 @@ foo.c <scons_output_command>scons -Q COLORS=magenta foo.o</scons_output_command> </scons_output> + <para> + + You can use this last characteristic as a way to enforce at least + one of your valid options being chosen by specifying the valid + values with the <parameter>names</parameter> parameter and then + giving a value not in that list as the <parameter>default</parameter> + parameter - that way if no value is given on the command line, + the default is chosen, and it will error out with an invalid value. + The example is, in fact, set up that way by using + <literal>0</literal> as the default: + + </para> + + <scons_output example="commandline_ListVariable" suffix="4"> + <scons_output_command>scons -Q foo.o</scons_output_command> + </scons_output> + + <para> + + This technique works for &EnumVariable; as well. + + </para> + </section> <section> @@ -1659,9 +1697,11 @@ foo.c <scons_example name="commandline_PathVariable"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(PathVariable('CONFIG', - help='Path to configuration file', - default='__ROOT__/etc/my_config')) +vars.Add( + PathVariable( + 'CONFIG', help='Path to configuration file', default='__ROOT__/etc/my_config' + ) +) env = Environment(variables=vars, CPPDEFINES={'CONFIG_FILE': '"$CONFIG"'}) env.Program('foo.c') </file> @@ -1678,7 +1718,7 @@ foo.c <para> - This then allows the user to + This allows you to override the &CONFIG; build variable on the command line as necessary: @@ -1714,10 +1754,14 @@ foo.c <scons_example name="commandline_PathIsFile"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(PathVariable('CONFIG', - help='Path to configuration file', - default='__ROOT__/etc/my_config', - validator=PathVariable.PathIsFile)) +vars.Add( + PathVariable( + 'CONFIG', + help='Path to configuration file', + default='__ROOT__/etc/my_config', + validator=PathVariable.PathIsFile, + ) +) env = Environment(variables=vars, CPPDEFINES={'CONFIG_FILE': '"$CONFIG"'}) env.Program('foo.c') </file> @@ -1740,10 +1784,14 @@ foo.c <scons_example name="commandline_PathIsDir"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(PathVariable('DBDIR', - help='Path to database directory', - default='__ROOT__/var/my_dbdir', - validator=PathVariable.PathIsDir)) +vars.Add( + PathVariable( + 'DBDIR', + help='Path to database directory', + default='__ROOT__/var/my_dbdir', + validator=PathVariable.PathIsDir, + ) +) env = Environment(variables=vars, CPPDEFINES={'DBDIR': '"$DBDIR"'}) env.Program('foo.c') </file> @@ -1768,10 +1816,14 @@ foo.c <scons_example name="commandline_PathIsDirCreate"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(PathVariable('DBDIR', - help='Path to database directory', - default='__ROOT__/var/my_dbdir', - validator=PathVariable.PathIsDirCreate)) +vars.Add( + PathVariable( + 'DBDIR', + help='Path to database directory', + default='__ROOT__/var/my_dbdir', + validator=PathVariable.PathIsDirCreate, + ) +) env = Environment(variables=vars, CPPDEFINES={'DBDIR': '"$DBDIR"'}) env.Program('foo.c') </file> @@ -1795,10 +1847,14 @@ foo.c <scons_example name="commandline_PathAccept"> <file name="SConstruct" printme="1"> vars = Variables('custom.py') -vars.Add(PathVariable('OUTPUT', - help='Path to output file or directory', - default=None, - validator=PathVariable.PathAccept)) +vars.Add( + PathVariable( + 'OUTPUT', + help='Path to output file or directory', + default=None, + validator=PathVariable.PathAccept, + ) +) env = Environment(variables=vars, CPPDEFINES={'OUTPUT': '"$OUTPUT"'}) env.Program('foo.c') </file> @@ -1829,9 +1885,9 @@ foo.c <scons_example name="commandline_PackageVariable"> <file name="SConstruct" printme="1"> vars = Variables("custom.py") -vars.Add(PackageVariable("PACKAGE", - help="Location package", - default="__ROOT__/opt/location")) +vars.Add( + PackageVariable("PACKAGE", help="Location package", default="__ROOT__/opt/location") +) env = Environment(variables=vars, CPPDEFINES={"PACKAGE": '"$PACKAGE"'}) env.Program("foo.c") </file> @@ -1967,7 +2023,7 @@ vars.Add('RELEASE', help='Set to 1 to build for release', default=0) env = Environment(variables=vars, CPPDEFINES={'RELEASE_BUILD': '${RELEASE}'}) unknown = vars.UnknownVariables() if unknown: - print("Unknown variables: %s"%unknown.keys()) + print("Unknown variables: %s" % " ".join(unknown.keys())) Exit(1) env.Program('foo.c') </file> @@ -1984,12 +2040,12 @@ foo.c that are <emphasis>not</emphasis> among the variables known to the &Variables; object (from having been specified using - the &Variables; object's&Add; method). - In the examble above, + the &Variables; object's &Add; method). + In the example above, we check for whether the dictionary - returned by the &UnknownVariables; is non-empty, + returned by &UnknownVariables; is non-empty, and if so print the Python list - containing the names of the unknwown variables + containing the names of the unknown variables and then call the &Exit; function to terminate &SCons;: @@ -2016,8 +2072,9 @@ foo.c Note that you must delay the call of &UnknownVariables; until after you have applied the &Variables; object to a construction environment - with the <literal>variables=</literal> - keyword argument of an &Environment; call. + with the <parameter>variables=</parameter> + keyword argument of an &Environment; call: the variables + in the object are not fully processed until this has happened. </para> @@ -2259,7 +2316,7 @@ int bar() { printf("prog2/bar.c\n"); } Lastly, if for some reason you don't want any targets built by default, - you can use the Python <literal>None</literal> + you can use the Python <constant>None</constant> variable: </para> @@ -2441,7 +2498,7 @@ else: prog1 = Program('prog1.c') Program('prog2.c') Default(prog1) -print ("BUILD_TARGETS is %s" % [str(t) for t in BUILD_TARGETS]) +print("BUILD_TARGETS is %s" % [str(t) for t in BUILD_TARGETS]) </file> <file name="prog1.c"> prog1.c diff --git a/doc/user/environments.xml b/doc/user/environments.xml index 8c492b3..40bcd31 100644 --- a/doc/user/environments.xml +++ b/doc/user/environments.xml @@ -379,7 +379,7 @@ environment, of directory names, suffixes, etc. </varlistentry> <varlistentry> - <term>&ConsEnv;</term> + <term>Construction Environment</term> <listitem> <para> @@ -479,15 +479,16 @@ environment, of directory names, suffixes, etc. and key-value store) associates keys with values, such that asking the dict about a key gives you back the associated value and assigning to a key creates the association - either a new - setting if the key was unknown, or replacing the previous - previous association if the key was already in the dict. - Accessing can be done by using <literal>[]</literal> - indexing notation, and dictionaries also provide a + setting if the key was unknown, or replacing the + previous association if the key was already in the dictionary. + Values can be retrieved using <firstterm>item access</firstterm> + (the key name in square brackets (<literal>[]</literal>)), + and dictionaries also provide a method named <methodname>get</methodname> which responds - with a default value (<constant>None</constant> or a default - you supply) if the key is not in the dictionary, which - avoids failing in that case. The syntax - for a dictionary itself uses curly braces (<literal>{}</literal>). + with a default value, either <constant>None</constant> or a value + you supply as the second argument, if the key is not in the dictionary, + which avoids failing in that case. The syntax + for initializing a dictionary uses curly braces (<literal>{}</literal>). Here are some simple examples (inspired by those in the official Python tutorial) using syntax that indicates interacting with the &Python; interpreter @@ -498,7 +499,7 @@ environment, of directory names, suffixes, etc. <screen> <prompt>>>></prompt> <userinput>tel = {'jack': 4098, 'sape': 4139}</userinput> -<prompt>>>></prompt> <userinput>tel['guido'] = 4098</userinput> +<prompt>>>></prompt> <userinput>tel['guido'] = 4127</userinput> <prompt>>>></prompt> <userinput>tel['jack']</userinput> 4098 <prompt>>>></prompt> <userinput>del tel['sape']</userinput> @@ -522,7 +523,8 @@ None a &consenv; <emphasis>is</emphasis> a &Python; dictionary. The <varname>os.environ</varname> value that &Python; uses to make available the external environment is also a - dictionary. We will need these concepts in this chapter. + dictionary. We will need these concepts in this chapter + and throughout the rest of this guide. </para> @@ -538,10 +540,10 @@ None the user has in force when executing &SCons; are available in the &Python; - <varname>os.environ</varname> - dictionary. That syntax means the <varname>environ</varname> + <varname>os.environ</varname> dictionary. + That syntax means the <varname>environ</varname> attribute of the <systemitem>os</systemitem> module. - In Python, to access contents of a module you must first + In Python, to access the contents of a module you must first <literal>import</literal> it - so you would include the <literal>import os</literal> statement to any &SConscript; file diff --git a/doc/user/main.xml b/doc/user/main.xml index 6f516f9..fd643b5 100644 --- a/doc/user/main.xml +++ b/doc/user/main.xml @@ -82,7 +82,8 @@ <chapter id="chap-manip-options"> <title>Automatically Putting Command-line Options into their Construction Variables</title> - <!-- TODO: This intro paragraph should describe at a high-level + <!-- TODO: combine this into a chapter document. + This intro paragraph should describe at a high-level what these things do. People are likely to use the intro as a (brief) overview of *what* these functions do to decide if this chapter is where they should read in more detail. --> @@ -104,60 +105,34 @@ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="file-removal.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hierarchy.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="separate.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="variants.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="gettext.xml"/> - - <!-- - - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="builders-built-in.xml"/> - - --> - + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="repositories.xml"/> + <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="builders-built-in.xml"/> --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="builders-writing.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="builders-commands.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="add-method.xml"/> - - <!-- - - XXX Action() - XXX AddPostAction() - XXX AddPreAction() - - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="actions.xml"/> - - --> - + <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="actions.xml"/> --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="scanners.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="repositories.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sconf.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="caching.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="alias.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="java.xml"/> - - <!-- - - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="run.xml"/> - - --> - + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="gettext.xml"/> + <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="run.xml"/> --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="misc.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="external.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="troubleshoot.xml"/> -<!-- Appendix below here --> + <!-- Appendix below here --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="variables.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="builders.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="functions.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tasks.xml"/> - <!-- - - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="python.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="example.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="make.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ant.xml"/> - - --> + <!-- These sections are only sekeletons: --> + <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="python.xml"/> --> + <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="example.xml"/> --> + <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="make.xml"/> --> + <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ant.xml"/> --> </book> diff --git a/doc/user/misc.xml b/doc/user/misc.xml index b093629..1b18d2f 100644 --- a/doc/user/misc.xml +++ b/doc/user/misc.xml @@ -625,6 +625,9 @@ env.Command('directory_build_info', </section> + <!-- Former unpublished chapter now included as a section here: --> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sideeffect.xml"/> + <section> <title>Virtual environments (virtualenvs)</title> diff --git a/doc/user/output.xml b/doc/user/output.xml index bae018a..cf6571c 100644 --- a/doc/user/output.xml +++ b/doc/user/output.xml @@ -197,7 +197,7 @@ if env['PLATFORM'] == 'win32': </section> - <section> + <section id="sect-controlling-build-output"> <title>Controlling How &SCons; Prints Build Commands: the <envar>$*COMSTR</envar> Variables</title> <para> diff --git a/doc/user/parse_flags_arg.xml b/doc/user/parse_flags_arg.xml index 6e9b926..6014145 100644 --- a/doc/user/parse_flags_arg.xml +++ b/doc/user/parse_flags_arg.xml @@ -17,7 +17,7 @@ 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"> -<title>Merging Options into the Environment: the <parameter>merge_flags</parameter> Parameter</title> +<title>Merging Options While Creating Environment: the <parameter>parse_flags</parameter> Parameter</title> <!-- diff --git a/doc/user/separate.xml b/doc/user/separate.xml index 748a124..236556d 100644 --- a/doc/user/separate.xml +++ b/doc/user/separate.xml @@ -2,7 +2,7 @@ <!DOCTYPE sconsdoc [ <!ENTITY % scons SYSTEM "../scons.mod"> %scons; - + <!ENTITY % builders-mod SYSTEM "../generated/builders.mod"> %builders-mod; <!ENTITY % functions-mod SYSTEM "../generated/functions.mod"> @@ -17,7 +17,7 @@ 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"> -<title>Separating Source and Build Directories</title> +<title>Separating Source and Build Trees: Variant Directories</title> <!-- @@ -44,115 +44,49 @@ --> -<!-- + <para> -=head1 Separating source and build trees - -It's often desirable to keep any derived files from the build completely -separate from the source files. This makes it much easier to keep track of -just what is a source file, and also makes it simpler to handle B<variant> -builds, especially if you want the variant builds to co-exist. - -=head2 Separating build and source directories using the Link command - -Cons provides a simple mechanism that handles all of these requirements. The -C<Link> command is invoked as in this example: - - Link 'build' => 'src'; - -The specified directories are ``linked'' to the specified source -directory. Let's suppose that you setup a source directory, F<src>, with the -sub-directories F<world> and F<hello> below it, as in the previous -example. You could then substitute for the original build lines the -following: - - Build qw( - build/world/Conscript - build/hello/Conscript - ); - -Notice that you treat the F<Conscript> file as if it existed in the build -directory. Now if you type the same command as before, you will get the -following results: - - % cons export - Install build/world/world.h as export/include/world.h - cc -Iexport/include -c build/hello/hello.c -o build/hello/hello.o - cc -Iexport/include -c build/world/world.c -o build/world/world.o - ar r build/world/libworld.a build/world/world.o - ar: creating build/world/libworld.a - ranlib build/world/libworld.a - Install build/world/libworld.a as export/lib/libworld.a - cc -o build/hello/hello build/hello/hello.o -Lexport/lib -lworld - Install build/hello/hello as export/bin/hello - -Again, Cons has taken care of the details for you. In particular, you will -notice that all the builds are done using source files and object files from -the build directory. For example, F<build/world/world.o> is compiled from -F<build/world/world.c>, and F<export/include/world.h> is installed from -F<build/world/world.h>. This is accomplished on most systems by the simple -expedient of ``hard'' linking the required files from each source directory -into the appropriate build directory. - -The links are maintained correctly by Cons, no matter what you do to the -source directory. If you modify a source file, your editor may do this ``in -place'' or it may rename it first and create a new file. In the latter case, -any hard link will be lost. Cons will detect this condition the next time -the source file is needed, and will relink it appropriately. - -You'll also notice, by the way, that B<no> changes were required to the -underlying F<Conscript> files. And we can go further, as we shall see in the -next section. - -=head2 Explicit references to the source directory - -When using the C<Link> command on some operating systems or with some -tool chains, it's sometimes useful to have a command actually use -the path name to the source directory, not the build directory. For -example, on systems that must copy, not "hard link," the F<src/> and -F<build/> copies of C<Linked> files, using the F<src/> path of a file -name might make an editor aware that a syntax error must be fixed in the -source directory, not the build directory. - -You can tell Cons that you want to use the "source path" for a file by -preceding the file name with a ``!'' (exclamation point). For example, -if we add a ``!'' to the beginning of a source file: - - Program $env "foo", "!foo.c"; # Notice initial ! on foo.c - -Cons will compile the target as follows: - - cc -c src/foo.c -o build/foo.o - cc -o build/foo build/foo.o - -Notice that Cons has compiled the program from the the F<src/foo.c> -source file. Without the initial ``!'', Cons would have compiled the -program using the F<build/foo.c> path name. + It's often useful to keep any built files completely + separate from the source files. Consider if you have a + project to build software for a variety of different + controller hardware. The boards are able to share a + lot of code, so it makes sense to keep them in the same + source tree, but certain build options in the source code + and header files differ. If you build "Controller A" first, + then "Controller B", on the second build everything would + have to be rebuilt, because &SCons; sees that the build + instructions differ, and thus the targets that depend on those + different instructions are not valid for the current build. + Now when you go back and build for "Controller A", + things have to be rebuilt from scratch again for the same reason. + However, if you can separate the places the output files + go, this problem can be avoided. + You can even set up to do both builds in one invocation of &SCons;. ---> + </para> <para> - It's often useful to keep any built files completely - separate from the source files. - In &SCons;, this is usually done by creating one or more separate - <emphasis>variant directory trees</emphasis> + You can enable this separation by creating one or more + <firstterm>variant directory</firstterm> trees that are used to hold the built objects files, libraries, and executable programs, etc. for a specific flavor, or variant, of build. &SCons; provides two ways to do this, - one through the &SConscript; function that we've already seen, - and the second through a more flexible &VariantDir; function. + one through the &f-link-SConscript; function that we've already seen, + and the second through a more flexible &f-link-VariantDir; function. </para> <para> - One historical note: the &VariantDir; function + Historical note: the &VariantDir; function used to be called &BuildDir;, a name which was removed because the &SCons; functionality - differs from the model of a "build directory" - implemented by other build systems like the GNU Autotools. + differs from a familiar model of a "build directory" + implemented by other build systems like GNU Autotools. + You might still find references to the old name on + the Internet in postings about &SCons;, but it no longer works. </para> @@ -162,11 +96,11 @@ program using the F<build/foo.c> path name. <para> The most straightforward way to establish a variant directory tree - uses the fact that the usual way to + relies the fact that the usual way to set up a build hierarchy is to have an - &SConscript; file in the source subdirectory. - If you then pass a &variant_dir; argument to the - &SConscript; function call: + SConscript file in the source subdirectory. + If you pass a &variant_dir; argument to the + &f-link-SConscript; function call: </para> @@ -193,20 +127,25 @@ int main() { printf("Hello, world!\n"); } <scons_output example="separate_ex1" suffix="1"> <scons_output_command>ls src</scons_output_command> <scons_output_command>scons -Q</scons_output_command> + <scons_output_command>ls src</scons_output_command> <scons_output_command>ls build</scons_output_command> </scons_output> <para> - But wait a minute--what's going on here? - &SCons; created the object file + No files were built in &src;, they went to &build;. + The build output might show a bit of a surprise: + the object file <filename>build/hello.o</filename> - in the &build; subdirectory, + and the executable file + <filename>build/hello</filename> + were built in the &build; subdirectory, as expected. But even though our &hello_c; file lives in the &src; subdirectory, &SCons; has actually compiled a <filename>build/hello.c</filename> file - to create the object file. + to create the object file, + and that file is now seen in &build;. </para> @@ -215,7 +154,7 @@ int main() { printf("Hello, world!\n"); } What's happened is that &SCons; has <emphasis>duplicated</emphasis> the &hello_c; file from the &src; subdirectory to the &build; subdirectory, - and built the program from there. + and built the program from there (it also duplicated &SConscript;). The next section explains why &SCons; does this. </para> @@ -227,13 +166,13 @@ int main() { printf("Hello, world!\n"); } <para> - &SCons; duplicates source files in variant directory trees - because it's the most straightforward way to guarantee a correct build - <emphasis>regardless of include-file directory paths, - relative references between files, - or tool support for putting files in different locations</emphasis>, - and the &SCons; philosophy is to, by default, - guarantee a correct build in all cases. + The important thing to understand is that when you set up a variant directory, + &SCons; performs the build <emphasis>in that directory</emphasis>. + It turns out it's easiest to ensure where build products end up + by just building in place. + Since the build is happening in a place different from where the + sources are, the most straightforward way to guarantee a correct build + is for &SCons; to copy them there. </para> @@ -312,13 +251,13 @@ int main() { printf("Hello, world!\n"); } duplicating the source files and everything will work just fine. You can disable the default &SCons; behavior - by specifying <literal>duplicate=0</literal> + by specifying <literal>duplicate=False</literal> when you call the &SConscript; function: </para> <sconstruct> -SConscript('src/SConscript', variant_dir='build', duplicate=0) +SConscript('src/SConscript', variant_dir='build', duplicate=False) </sconstruct> <para> @@ -395,14 +334,14 @@ int main() { printf("Hello, world!\n"); } <para> - You can specify the same <literal>duplicate=0</literal> argument + You can specify the same <literal>duplicate=False</literal> argument that you can specify for an &SConscript; call: </para> <scons_example name="separate_duplicate0"> <file name="SConstruct" printme="1"> -VariantDir('build', 'src', duplicate=0) +VariantDir('build', 'src', duplicate=False) env = Environment() env.Program('build/hello.c') </file> @@ -432,8 +371,10 @@ int main() { printf("Hello, world!\n"); } <para> Even when using the &VariantDir; function, - it's much more natural to use it with - a subsidiary &SConscript; file. + it's more natural to use it with + a subsidiary &SConscript; file, + because then you don't have to adjust your individual + build instructions to use the variant directory path. For example, if the <filename>src/SConscript</filename> looks like this: @@ -490,7 +431,7 @@ int main() { printf("Hello, world!\n"); } <para> - The &Glob; file name pattern matching function + The &f-link-Glob; file name pattern matching function works just as usual when using &VariantDir;. For example, if the <filename>src/SConscript</filename> @@ -558,4 +499,6 @@ const char * f2(); --> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="variants.xml"/> + </chapter> diff --git a/doc/user/sideeffect.xml b/doc/user/sideeffect.xml index d03fbe2..2733769 100644 --- a/doc/user/sideeffect.xml +++ b/doc/user/sideeffect.xml @@ -2,7 +2,7 @@ <!DOCTYPE sconsdoc [ <!ENTITY % scons SYSTEM "../scons.mod"> %scons; - + <!ENTITY % builders-mod SYSTEM "../generated/builders.mod"> %builders-mod; <!ENTITY % functions-mod SYSTEM "../generated/functions.mod"> @@ -13,11 +13,11 @@ %variables-mod; ]> -<chapter id="chap-sideeffect" +<section id="sect-sideeffect" 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"> -<title>Sideeffect files</title> +<title>Declaring Additional Outputs: the &f-SideEffect; Function </title> <!-- @@ -46,68 +46,142 @@ <para> - If &SCons; is unaware that a build step produces an extra file, - the &SideEffect; method can be used to identify it, - so that the file can be used as a dependency in subsequent build steps. - However, the primary use for the &SideEffect; method - is to prevent two build steps from simultaneously modifying the same file. + Sometimes the way an action is defined causes effects on files + that &SCons; does not recognize as targets. The &f-link-SideEffect; + method can be used to informs &SCons; about such files. + This can be used just to flag a dependency for use in subsequent + build steps, although there is usually a better way to do that. + The primary use for the &SideEffect; method + is to prevent two build steps from simultaneously modifying + or accessing the same file in a way that could impact each other. </para> <para> - TODO: currently doesn't work due to issue #2154: - https://github.com/SCons/scons/issues/2154 + + In this example, the rule to build <filename>file1</filename> + will also put data into <filename>log</filename>, which is used + as a source for the command to generate <filename>file2</filename>, + but <filename>log</filename> is unknown to &SCons; on a clean + build: it neither exists, nor is it a target output by any builder. + The <filename>SConscript</filename> uses + &SideEffect; to inform &SCons; about the additional output file. + </para> - + + <scons_example name="sideeffect_simple"> + <file name="SConstruct" printme="1"> +env = Environment() +f2 = env.Command( + target='file2', + source='log', + action=Copy('$TARGET', '$SOURCE') +) +f1 = env.Command( + target='file1', + source=[], + action='echo >$TARGET data1; echo >log updated file1' +) +env.SideEffect('log', f1) + </file> + </scons_example> + <para> - If more than one build step creates or manipulates the same file, - it can cause unpleasant results if both build steps are run at the same time. - The shared file is declared as a side-effect of building the primary targets - and &SCons; will prevent the two build steps from running in parallel. + Without the &f-SideEffect;, this build would fail with a message + <computeroutput>Source `log' not found, needed by target `file2'</computeroutput>, + but now it can proceed: </para> + <scons_output example="sideeffect_simple" suffix="1"> + <scons_output_command>scons -Q</scons_output_command> + </scons_output> + <para> - In this example, the <filename>SConscript</filename> uses - &SideEffect; to inform &SCons; about the additional output file. + However, it is better to actually identify + <filename>log</filename> as a target, since in this + case that's what it is: </para> - <scons_example name="sideeffect_simple"> + <scons_example name="sideeffect_simple2"> <file name="SConstruct" printme="1"> env = Environment() -f2 = env.Command('file2', 'log', Copy('$TARGET', '$SOURCE')) -f1 = env.Command('file1', [], - 'echo >$TARGET data1; echo >log updated file1') -env.SideEffect('log', env.Command('file1', [], - 'echo >$TARGET data1; echo >log updated file1')) +f2 = env.Command( + target='file2', + source='log', + action=Copy('$TARGET', '$SOURCE') +) +f1 = env.Command( + target=['file1', 'log'], + source=[], + action='echo >$TARGET data1; echo >log updated file1' +) </file> </scons_example> + <scons_output example="sideeffect_simple2" suffix="1"> + <scons_output_command>scons -Q</scons_output_command> + </scons_output> + <para> - Even when run in parallel mode, &SCons; will run the two steps in order: + In general, &SideEffect; is not intended for the case when + a command produces extra target files (that is, files which + will be used as sources to other build steps). For example, the + the Microsoft Visual C/C++ compiler is capable of performing + incremental linking, for which it uses a status file - such that + linking <filename>foo.exe</filename> also produces + a <filename>foo.ilk</filename>, or uses it if it was already present, + if the <option>/INCREMENTAL</option> option was supplied. + Specifying <filename>foo.ilk</filename> as a + side-effect of <filename>foo.exe</filename> + is <emphasis>not</emphasis> a recommended use of &SideEffect; + since <filename>foo.ilk</filename> is used by the link. + &SCons; handles side-effect files + slightly differently in its analysis of the dependency graph. + When a command produces multiple output files, + they should be specified as multiple targets of + the call to the relevant builder function. + The &SideEffect; function itself should really only be used + when it's important to ensure that commands are not executed in parallel, + such as when a "peripheral" file (such as a log file) + may actually be updated by more than one command invocation. </para> - <scons_output example="sideeffect_simple" suffix="1"> - <scons_output_command>scons -Q --jobs=2</scons_output_command> - </scons_output> + <para> + + Unfortunately, the tool which sets up the &b-Program; builder + for the MSVC compiler chain does not come prebuilt + with an understanding of the details of the <filename>.ilk</filename> + example - that the target list would need to change + in the presence of that specific option flag. Unlike the trivial + example above where we could simply tell the &Command; builder + there were two targets of the action, modifying the + chain of events for a builder like &b-Program;, + though not inherently complex, is definitely an + advanced &SCons; topic. It's okay to use &SideEffect; here + to get started, as long as it comes with an understanding + that it's "not quite right". Perhaps leave a comment in + the file as a reminder, if it does turn out to cause problems later. + + </para> <para> - Sometimes a program the you need to call - to build a target file - will also update another file, - such as a log file describing what the program + So if the main use is to prevent parallelism problems, + here is an example to illustrate. + Say a program that you need to call to build a target file + will also update a log file describing what the program does while building the target. - For example, we the folowing configuration + The following configuration would have &SCons; invoke a hypothetical script named <application>build</application> (in the local directory) - with command-line arguments that write + with command-line arguments telling it to write log information to a common <filename>logfile.txt</filename> file: @@ -115,10 +189,16 @@ env.SideEffect('log', env.Command('file1', [], <screen> env = Environment() -env.Command('file1.out', 'file.in', - './build --log logfile.txt $SOURCE $TARGET') -env.Command('file2.out', 'file.in', - './build --log logfile.txt $SOURCE $TARGET') +env.Command( + target='file1.out', + source='file1.in', + action='./build --log logfile.txt $SOURCE $TARGET' +) +env.Command( + target='file2.out', + source='file2.in', + action='./build --log logfile.txt $SOURCE $TARGET' +) </screen> <para> @@ -156,10 +236,16 @@ env.Command('file2.out', 'file.in', <scons_example name="sideeffect_shared"> <file name="SConstruct" printme="1"> env = Environment() -f1 = env.Command('file1.out', 'file1.in', - './build --log logfile.txt $SOURCE $TARGET') -f2 = env.Command('file2.out', 'file2.in', - './build --log logfile.txt $SOURCE $TARGET') +f1 = env.Command( + target='file1.out', + source='file1.in', + action='./build --log logfile.txt $SOURCE $TARGET' +) +f2 = env.Command( + target='file2.out', + source='file2.in', + action='./build --log logfile.txt $SOURCE $TARGET' +) env.SideEffect('logfile.txt', f1 + f2) </file> <file name="file1.in">file1.in</file> @@ -177,7 +263,7 @@ cat This makes sure the the two <application>./build</application> steps are run sequentially, - even withthe <filename>--jobs=2</filename> in the command line: + even with the <filename>--jobs=2</filename> in the command line: </para> @@ -189,20 +275,23 @@ cat The &SideEffect; function can be called multiple times for the same side-effect file. - Additionally, the name used as a &SideEffect; does not - even need to actually exist as a file on disk. + In fact, the name used as a &SideEffect; does not + even need to actually exist as a file on disk - &SCons; will still make sure that the relevant targets - will be executed sequentially, not in parallel: + will be executed sequentially, not in parallel. + The side effect is actually a pseudo-target, and &SCons; + mainly cares whether nodes are listed as depending on it, + not about its contents. </para> <scons_example name="sideeffect_parallel"> <file name="SConstruct" printme="1"> env = Environment() -f1 = env.Command('file1.out', [], 'echo >$TARGET data1') +f1 = env.Command('file1.out', [], action='echo >$TARGET data1') env.SideEffect('not_really_updated', f1) -f2 = env.Command('file2.out', [], 'echo >$TARGET data2') +f2 = env.Command('file2.out', [], action='echo >$TARGET data2') env.SideEffect('not_really_updated', f2) </file> </scons_example> @@ -211,28 +300,5 @@ env.SideEffect('not_really_updated', f2) <scons_output_command>scons -Q --jobs=2</scons_output_command> </scons_output> - <para> - - Note that it might be tempting to - use &SideEffect; for additional target files - that a command produces. - For example, versions the Microsoft Visual C/C++ compiler - produce a <filename>foo.ilk</filename> - alongside compiling <filename>foo.obj</filename> file. - Specifying <filename>foo.ilk</filename> as a - side-effect of <filename>foo.obj</filename> - is <emphasis>not</emphasis> a recommended use of &SideEffect;, - because &SCons; handle side-effect files - slightly differently in its analysis of the dependency graph. - When a command produces multiple output files, - they should be specified as multiple targets of - the call to the relevant builder function, - and the &SideEffect; function itself should really only be used - when it's important to ensure that commands are not executed in parallel, - such as when a "peripheral" file (such as a log file) - may actually updated by more than one command invocation. - - </para> + </section> - </chapter> - diff --git a/doc/user/simple.xml b/doc/user/simple.xml index 138ff54..8582613 100644 --- a/doc/user/simple.xml +++ b/doc/user/simple.xml @@ -459,7 +459,7 @@ int main() { printf("Goodbye, world!\n"); } we see the output from calling the <function>print</function> function in between the messages about reading the &SConscript; files, - indicating that that is when the + indicating that is when the Python statements are being executed: </para> diff --git a/doc/user/troubleshoot.xml b/doc/user/troubleshoot.xml index 7049deb..3906af6 100644 --- a/doc/user/troubleshoot.xml +++ b/doc/user/troubleshoot.xml @@ -69,8 +69,8 @@ odds are pretty good that someone else will run into the same problem, too. If so, please let the SCons development team know - (preferably by filing a bug report - or feature request at our project pages at tigris.org) + using the contact information at + <ulink url="https://scons.org/contact.html"/> so that we can use your feedback to try to come up with a better way to help you, and others, get the necessary insight into &SCons; behavior diff --git a/doc/user/variants.xml b/doc/user/variants.xml index 0c83b04..6cf8c3d 100644 --- a/doc/user/variants.xml +++ b/doc/user/variants.xml @@ -13,11 +13,11 @@ %variables-mod; ]> -<chapter id="chap-variants" +<section id="sect-variants" 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"> -<title>Variant Builds</title> +<title>Variant Build Examples</title> <!-- @@ -44,30 +44,6 @@ --> -<!-- - -=head1 Variant builds - -=head2 Variations on a theme - -Other variations of this model are possible. For example, you might decide -that you want to separate out your include files into platform dependent and -platform independent files. In this case, you'd have to define an -alternative to C<$INCLUDE> for platform-dependent files. Most F<Conscript> -files, generating purely platform-independent include files, would not have -to change. - -You might also want to be able to compile your whole system with debugging -or profiling, for example, enabled. You could do this with appropriate -command line options, such as C<DEBUG=on>. This would then be translated -into the appropriate platform-specific requirements to enable debugging -(this might include turning off optimization, for example). You could -optionally vary the name space for these different types of systems, but, as -we'll see in the next section, it's not B<essential> to do this, since Cons -is pretty smart about rebuilding things when you change options. - ---> - <para> The &variant_dir; keyword argument of @@ -76,9 +52,15 @@ is pretty smart about rebuilding things when you change options. variant builds using &SCons;. Suppose, for example, that we want to build a program for both Windows and Linux platforms, - but that we want to build it in a shared directory + but that we want to build it in directory on a network share with separate side-by-side build directories for the Windows and Linux versions of the program. + We have to do a little bit of work to construct paths, + to make sure unwanted location dependencies don't creep in. + The top-relative path reference can be useful here. + To avoid writing conditional code based on platform, + we can build the <parameter>variant_dir</parameter> + path dynamically: </para> @@ -90,13 +72,15 @@ include = "#export/$PLATFORM/include" lib = "#export/$PLATFORM/lib" bin = "#export/$PLATFORM/bin" -env = Environment(PLATFORM = platform, - BINDIR = bin, - INCDIR = include, - LIBDIR = lib, - CPPPATH = [include], - LIBPATH = [lib], - LIBS = 'world') +env = Environment( + PLATFORM=platform, + BINDIR=bin, + INCDIR=include, + LIBDIR=lib, + CPPPATH=[include], + LIBPATH=[lib], + LIBS='world', +) Export('env') @@ -155,20 +139,32 @@ int world() { printf "world.c\n"; } <scons_output_command>scons -Q OS=windows</scons_output_command> </scons_output> - <!-- + <para> + + In order to build several variants at once when using the + <parameter>variant_dir</parameter> argument to &SConscript;, + you can call the function repeatedely - this example + does so in a loop. Note that the &f-link-SConscript; trick of + passing a list of script files, or a list of source directories, + does not work with <parameter>variant_dir</parameter>, + &SCons; allows only a single &SConscript; to be given if + <parameter>variant_dir</parameter> is used. + + </para> <scons_example name="variants_ex2"> <file name="SConstruct" printme="1"> -env = Environment(OS = ARGUMENTS.get('OS')) +env = Environment(OS=ARGUMENTS.get('OS')) for os in ['newell', 'post']: SConscript('src/SConscript', variant_dir='build/' + os) </file> </scons_example> + <!-- <scons_output example="variants_ex2" suffix="1"> <scons_output_command>scons -Q</scons_output_command> </scons_output> --> -</chapter> +</section> |