From 140d836e9cd54fb67b969fd82ef7ed19ba574d40 Mon Sep 17 00:00:00 2001 From: Luca Falavigna Date: Sat, 26 Apr 2014 15:11:58 +0200 Subject: Imported Upstream version 2.3.1 --- doc/user/environments.in | 1752 ---------------------------------------------- 1 file changed, 1752 deletions(-) delete mode 100644 doc/user/environments.in (limited to 'doc/user/environments.in') diff --git a/doc/user/environments.in b/doc/user/environments.in deleted file mode 100644 index eebc486..0000000 --- a/doc/user/environments.in +++ /dev/null @@ -1,1752 +0,0 @@ - - - - - - - An environment - is a collection of values that - can affect how a program executes. - &SCons; distinguishes between three - different types of environments - that can affect the behavior of &SCons; itself - (subject to the configuration in the &SConscript; files), - as well as the compilers and other tools it executes: - - - - - - - External Environment - - - - - The external environment - is the set of variables in the user's environment - at the time the user runs &SCons;. - These variables are available within the &SConscript; files - through the Python os.environ dictionary. - See , below. - - - - - - - &ConsEnv; - - - - - A &consenv; - is a distinct object creating within - a &SConscript; file and - and which contains values that - affect how &SCons; decides - what action to use to build a target, - and even to define which targets - should be built from which sources. - One of the most powerful features of &SCons; - is the ability to create multiple &consenvs;, - including the ability to clone a new, customized - &consenv; from an existing &consenv;. - See , below. - - - - - - - Execution Environment - - - - - An execution environment - is the values that &SCons; sets - when executing an external - command (such as a compiler or linker) - to build one or more targets. - Note that this is not the same as - the external environment - (see above). - See , below. - - - - - - - - - - Unlike &Make;, &SCons; does not automatically - copy or import values between different environments - (with the exception of explicit clones of &consenvs;, - which inherit values from their parent). - This is a deliberate design choice - to make sure that builds are, - by default, repeatable regardless of - the values in the user's external environment. - This avoids a whole class of problems with builds - where a developer's local build works - because a custom variable setting - causes a different compiler or build option to be used, - but the checked-in change breaks the official build - because it uses different environment variable settings. - - - - - - Note that the &SConscript; writer can - easily arrange for variables to be - copied or imported between environments, - and this is often very useful - (or even downright necessary) - to make it easy for developers - to customize the build in appropriate ways. - The point is not - that copying variables between different environments - is evil and must always be avoided. - Instead, it should be up to the - implementer of the build system - to make conscious choices - about how and when to import - a variable from one environment to another, - making informed decisions about - striking the right balance - between making the build - repeatable on the one hand - and convenient to use on the other. - - - -
- Using Values From the External Environment - - - - The external environment - variable settings that - the user has in force - when executing &SCons; - are available through the normal Python - os.environ - dictionary. - This means that you must add an - import os statement - to any &SConscript; file - in which you want to use - values from the user's external environment. - - - - - - import os - - - int main() { } - - - - - - More usefully, you can use the - os.environ - dictionary in your &SConscript; - files to initialize &consenvs; - with values from the user's external environment. - See the next section, - , - for information on how to do this. - - - -
- -
- Construction Environments - - - - It is rare that all of the software in a large, - complicated system needs to be built the same way. - For example, different source files may need different options - enabled on the command line, - or different executable programs need to be linked - with different libraries. - &SCons; accommodates these different build - requirements by allowing you to create and - configure multiple &consenvs; - that control how the software is built. - A &consenv; is an object - that has a number of associated - &consvars;, each with a name and a value. - (A construction environment also has an attached - set of &Builder; methods, - about which we'll learn more later.) - - - -
- Creating a &ConsEnv;: the &Environment; Function - - - - A &consenv; is created by the &Environment; method: - - - - - env = Environment() - - - - - By default, &SCons; initializes every - new construction environment - with a set of &consvars; - based on the tools that it finds on your system, - plus the default set of builder methods - necessary for using those tools. - The construction variables - are initialized with values describing - the C compiler, - the Fortran compiler, - the linker, - etc., - as well as the command lines to invoke them. - - - - - - When you initialize a construction environment - you can set the values of the - environment's &consvars; - to control how a program is built. - For example: - - - - - - env = Environment(CC = 'gcc', - CCFLAGS = '-O2') - - env.Program('foo.c') - - - int main() { } - - - - - - The construction environment in this example - is still initialized with the same default - construction variable values, - except that the user has explicitly specified use of the - GNU C compiler &gcc;, - and further specifies that the -O2 - (optimization level two) - flag should be used when compiling the object file. - In other words, the explicit initializations of - &cv-link-CC; and &cv-link-CCFLAGS; - override the default values in the newly-created - construction environment. - So a run from this example would look like: - - - - - scons -Q - - -
- -
- Fetching Values From a &ConsEnv; - - - - You can fetch individual construction variables - using the normal syntax - for accessing individual named items in a Python dictionary: - - - - - - env = Environment() - print "CC is:", env['CC'] - - - - - - This example &SConstruct; file doesn't build anything, - but because it's actually a Python script, - it will print the value of &cv-link-CC; for us: - - - - - scons -Q - - - - - A construction environment, however, - is actually an object with associated methods, etc. - If you want to have direct access to only the - dictionary of construction variables, - you can fetch this using the &Dictionary; method: - - - - - - env = Environment(FOO = 'foo', BAR = 'bar') - dict = env.Dictionary() - for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']: - print "key = %s, value = %s" % (key, dict[key]) - - - - - - This &SConstruct; file - will print the specified dictionary items for us on POSIX - systems as follows: - - - - - scons -Q - - - - - And on Windows: - - - - - scons -Q - - - - - If you want to loop and print the values of - all of the construction variables in a construction environment, - the Python code to do that in sorted order might look something like: - - - - - env = Environment() - for item in sorted(env.Dictionary().items()): - print "construction variable = '%s', value = '%s'" % item - - -
- -
- Expanding Values From a &ConsEnv;: the &subst; Method - - - - Another way to get information from - a construction environment - is to use the &subst; method - on a string containing $ expansions - of construction variable names. - As a simple example, - the example from the previous - section that used - env['CC'] - to fetch the value of &cv-link-CC; - could also be written as: - - - - - env = Environment() - print "CC is:", env.subst('$CC') - - - - - One advantage of using - &subst; to expand strings is - that construction variables - in the result get re-expanded until - there are no expansions left in the string. - So a simple fetch of a value like - &cv-link-CCCOM;: - - - - - env = Environment(CCFLAGS = '-DFOO') - print "CCCOM is:", env['CCCOM'] - - - - - Will print the unexpanded value of &cv-CCCOM;, - showing us the construction - variables that still need to be expanded: - - - - - % scons -Q - CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES - scons: `.' is up to date. - - - - - Calling the &subst; method on $CCOM, - however: - - - - - env = Environment(CCFLAGS = '-DFOO') - print "CCCOM is:", env.subst('$CCCOM') - - - - - Will recursively expand all of - the construction variables prefixed - with $ (dollar signs), - showing us the final output: - - - - - % scons -Q - CCCOM is: gcc -DFOO -c -o - scons: `.' is up to date. - - - - - Note that because we're not expanding this - in the context of building something - there are no target or source files - for &cv-link-TARGET; and &cv-link-SOURCES; to expand. - - - -
- -
- Handling Problems With Value Expansion - - - - If a problem occurs when expanding a construction variable, - by default it is expanded to '' - (a null string), and will not cause scons to fail. - - - - - env = Environment() - print "value is:", env.subst( '->$MISSING<-' ) - - - - - scons -Q - - - - This default behaviour can be changed using the &AllowSubstExceptions; - function. - When a problem occurs with a variable expansion it generates - an exception, and the &AllowSubstExceptions; function controls - which of these exceptions are actually fatal and which are - allowed to occur safely. By default, &NameError; and &IndexError; - are the two exceptions that are allowed to occur: so instead of - causing scons to fail, these are caught, the variable expanded to - '' - and scons execution continues. - To require that all construction variable names exist, and that - indexes out of range are not allowed, call &AllowSubstExceptions; - with no extra arguments. - - - - - AllowSubstExceptions() - env = Environment() - print "value is:", env.subst( '->$MISSING<-' ) - - - - - scons -Q - - - - This can also be used to allow other exceptions that might occur, - most usefully with the ${...} construction - variable syntax. For example, this would allow zero-division to - occur in a variable expansion in addition to the default exceptions - allowed - - - - - AllowSubstExceptions(IndexError, NameError, ZeroDivisionError) - env = Environment() - print "value is:", env.subst( '->${1 / 0}<-' ) - - - - - scons -Q - - - - - - If &AllowSubstExceptions; is called multiple times, each call - completely overwrites the previous list of allowed exceptions. - - -
- -
- Controlling the Default &ConsEnv;: the &DefaultEnvironment; Function - - - - All of the &Builder; functions that we've introduced so far, - like &Program; and &Library;, - actually use a default &consenv; - that contains settings - for the various compilers - and other tools that - &SCons; configures by default, - or otherwise knows about - and has discovered on your system. - The goal of the default construction environment - is to make many configurations to "just work" - to build software using - readily available tools - with a minimum of configuration changes. - - - - - - You can, however, control the settings - in the default construction environment - by using the &DefaultEnvironment; function - to initialize various settings: - - - - - - DefaultEnvironment(CC = '/usr/local/bin/gcc') - - - - - - When configured as above, - all calls to the &Program; - or &Object; Builder - will build object files with the - /usr/local/bin/gcc - compiler. - - - - - - Note that the &DefaultEnvironment; function - returns the initialized - default construction environment object, - which can then be manipulated like any - other construction environment. - So the following - would be equivalent to the - previous example, - setting the &cv-CC; - variable to /usr/local/bin/gcc - but as a separate step after - the default construction environment has been initialized: - - - - - - env = DefaultEnvironment() - env['CC'] = '/usr/local/bin/gcc' - - - - - - One very common use of the &DefaultEnvironment; function - is to speed up &SCons; initialization. - As part of trying to make most default - configurations "just work," - &SCons; will actually - search the local system for installed - compilers and other utilities. - This search can take time, - especially on systems with - slow or networked file systems. - If you know which compiler(s) and/or - other utilities you want to configure, - you can control the search - that &SCons; performs - by specifying some specific - tool modules with which to - initialize the default construction environment: - - - - - - env = DefaultEnvironment(tools = ['gcc', 'gnulink'], - CC = '/usr/local/bin/gcc') - - - - - - So the above example would tell &SCons; - to explicitly configure the default environment - to use its normal GNU Compiler and GNU Linker settings - (without having to search for them, - or any other utilities for that matter), - and specifically to use the compiler found at - /usr/local/bin/gcc. - - - -
- -
- Multiple &ConsEnvs; - - - - The real advantage of construction environments - is that you can create as many different construction - environments as you need, - each tailored to a different way to build - some piece of software or other file. - If, for example, we need to build - one program with the -O2 flag - and another with the -g (debug) flag, - we would do this like so: - - - - - - opt = Environment(CCFLAGS = '-O2') - dbg = Environment(CCFLAGS = '-g') - - opt.Program('foo', 'foo.c') - - dbg.Program('bar', 'bar.c') - - - int main() { } - - - int main() { } - - - - - scons -Q - - - - - We can even use multiple construction environments to build - multiple versions of a single program. - If you do this by simply trying to use the - &b-link-Program; builder with both environments, though, - like this: - - - - - - opt = Environment(CCFLAGS = '-O2') - dbg = Environment(CCFLAGS = '-g') - - opt.Program('foo', 'foo.c') - - dbg.Program('foo', 'foo.c') - - - int main() { } - - - - - - Then &SCons; generates the following error: - - - - - scons -Q - - - - - This is because the two &b-Program; calls have - each implicitly told &SCons; to generate an object file named - foo.o, - one with a &cv-link-CCFLAGS; value of - -O2 - and one with a &cv-link-CCFLAGS; value of - -g. - &SCons; can't just decide that one of them - should take precedence over the other, - so it generates the error. - To avoid this problem, - we must explicitly specify - that each environment compile - foo.c - to a separately-named object file - using the &b-link-Object; builder, like so: - - - - - - opt = Environment(CCFLAGS = '-O2') - dbg = Environment(CCFLAGS = '-g') - - o = opt.Object('foo-opt', 'foo.c') - opt.Program(o) - - d = dbg.Object('foo-dbg', 'foo.c') - dbg.Program(d) - - - int main() { } - - - - - - Notice that each call to the &b-Object; builder - returns a value, - an internal &SCons; object that - represents the object file that will be built. - We then use that object - as input to the &b-Program; builder. - This avoids having to specify explicitly - the object file name in multiple places, - and makes for a compact, readable - &SConstruct; file. - Our &SCons; output then looks like: - - - - - scons -Q - - -
- -
- Making Copies of &ConsEnvs;: the &Clone; Method - - - - Sometimes you want more than one construction environment - to share the same values for one or more variables. - Rather than always having to repeat all of the common - variables when you create each construction environment, - you can use the &Clone; method - to create a copy of a construction environment. - - - - - - Like the &Environment; call that creates a construction environment, - the &Clone; method takes &consvar; assignments, - which will override the values in the copied construction environment. - For example, suppose we want to use &gcc; - to create three versions of a program, - one optimized, one debug, and one with neither. - We could do this by creating a "base" construction environment - that sets &cv-link-CC; to &gcc;, - and then creating two copies, - one which sets &cv-link-CCFLAGS; for optimization - and the other which sets &cv-CCFLAGS; for debugging: - - - - - - env = Environment(CC = 'gcc') - opt = env.Clone(CCFLAGS = '-O2') - dbg = env.Clone(CCFLAGS = '-g') - - env.Program('foo', 'foo.c') - - o = opt.Object('foo-opt', 'foo.c') - opt.Program(o) - - d = dbg.Object('foo-dbg', 'foo.c') - dbg.Program(d) - - - int main() { } - - - - - - Then our output would look like: - - - - - scons -Q - - -
- -
- Replacing Values: the &Replace; Method - - - - You can replace existing construction variable values - using the &Replace; method: - - - - - - env = Environment(CCFLAGS = '-DDEFINE1') - env.Replace(CCFLAGS = '-DDEFINE2') - env.Program('foo.c') - - - int main() { } - - - - - - The replacing value - (-DDEFINE2 in the above example) - completely replaces the value in the - construction environment: - - - - - scons -Q - - - - - You can safely call &Replace; - for construction variables that - don't exist in the construction environment: - - - - - - env = Environment() - env.Replace(NEW_VARIABLE = 'xyzzy') - print "NEW_VARIABLE =", env['NEW_VARIABLE'] - - - - - - In this case, - the construction variable simply - gets added to the construction environment: - - - - - scons -Q - - - - - Because the variables - aren't expanded until the construction environment - is actually used to build the targets, - and because &SCons; function and method calls - are order-independent, - the last replacement "wins" - and is used to build all targets, - regardless of the order in which - the calls to Replace() are - interspersed with calls to - builder methods: - - - - - - env = Environment(CCFLAGS = '-DDEFINE1') - print "CCFLAGS =", env['CCFLAGS'] - env.Program('foo.c') - - env.Replace(CCFLAGS = '-DDEFINE2') - print "CCFLAGS =", env['CCFLAGS'] - env.Program('bar.c') - - - int main() { } - - - int main() { } - - - - - - The timing of when the replacement - actually occurs relative - to when the targets get built - becomes apparent - if we run &scons; without the -Q - option: - - - - - scons - - - - - Because the replacement occurs while - the &SConscript; files are being read, - the &cv-link-CCFLAGS; - variable has already been set to - -DDEFINE2 - by the time the &foo_o; target is built, - even though the call to the &Replace; - method does not occur until later in - the &SConscript; file. - - - -
- -
- Setting Values Only If They're Not Already Defined: the &SetDefault; Method - - - - Sometimes it's useful to be able to specify - that a construction variable should be - set to a value only if the construction environment - does not already have that variable defined - You can do this with the &SetDefault; method, - which behaves similarly to the set_default - method of Python dictionary objects: - - - - - env.SetDefault(SPECIAL_FLAG = '-extra-option') - - - - - This is especially useful - when writing your own Tool modules - to apply variables to construction environments. - - - - -
- -
- Appending to the End of Values: the &Append; Method - - - - You can append a value to - an existing construction variable - using the &Append; method: - - - - - - env = Environment(CCFLAGS = ['-DMY_VALUE']) - env.Append(CCFLAGS = ['-DLAST']) - env.Program('foo.c') - - - int main() { } - - - - - - &SCons; then supplies both the -DMY_VALUE and - -DLAST flags when compiling the object file: - - - - - scons -Q - - - - - If the construction variable doesn't already exist, - the &Append; method will create it: - - - - - - env = Environment() - env.Append(NEW_VARIABLE = 'added') - print "NEW_VARIABLE =", env['NEW_VARIABLE'] - - - - - - Which yields: - - - - - scons -Q - - - - - Note that the &Append; function tries to be "smart" - about how the new value is appended to the old value. - If both are strings, the previous and new strings - are simply concatenated. - Similarly, if both are lists, - the lists are concatenated. - If, however, one is a string and the other is a list, - the string is added as a new element to the list. - - - -
- -
- Appending Unique Values: the &AppendUnique; Method - - - - Some times it's useful to add a new value - only if the existing construction variable - doesn't already contain the value. - This can be done using the &AppendUnique; method: - - - - - env.AppendUnique(CCFLAGS=['-g']) - - - - - In the above example, - the -g would be added - only if the &cv-CCFLAGS; variable - does not already contain a -g value. - - - -
- -
- Appending to the Beginning of Values: the &Prepend; Method - - - - You can append a value to the beginning of - an existing construction variable - using the &Prepend; method: - - - - - - env = Environment(CCFLAGS = ['-DMY_VALUE']) - env.Prepend(CCFLAGS = ['-DFIRST']) - env.Program('foo.c') - - - int main() { } - - - - - - &SCons; then supplies both the -DFIRST and - -DMY_VALUE flags when compiling the object file: - - - - - scons -Q - - - - - If the construction variable doesn't already exist, - the &Prepend; method will create it: - - - - - - env = Environment() - env.Prepend(NEW_VARIABLE = 'added') - print "NEW_VARIABLE =", env['NEW_VARIABLE'] - - - - - - Which yields: - - - - - scons -Q - - - - - Like the &Append; function, - the &Prepend; function tries to be "smart" - about how the new value is appended to the old value. - If both are strings, the previous and new strings - are simply concatenated. - Similarly, if both are lists, - the lists are concatenated. - If, however, one is a string and the other is a list, - the string is added as a new element to the list. - - - -
- -
- Prepending Unique Values: the &PrependUnique; Method - - - - Some times it's useful to add a new value - to the beginning of a construction variable - only if the existing value - doesn't already contain the to-be-added value. - This can be done using the &PrependUnique; method: - - - - - env.PrependUnique(CCFLAGS=['-g']) - - - - - In the above example, - the -g would be added - only if the &cv-CCFLAGS; variable - does not already contain a -g value. - - - -
- -
- -
- Controlling the Execution Environment for Issued Commands - - - - When &SCons; builds a target file, - it does not execute the commands with - the same external environment - that you used to execute &SCons;. - Instead, it uses the dictionary - stored in the &cv-link-ENV; construction variable - as the external environment - for executing commands. - - - - - - The most important ramification of this behavior - is that the &PATH; environment variable, - which controls where the operating system - will look for commands and utilities, - is not the same as in the external environment - from which you called &SCons;. - This means that &SCons; will not, by default, - necessarily find all of the tools - that you can execute from the command line. - - - - - - The default value of the &PATH; environment variable - on a POSIX system - is /usr/local/bin:/bin:/usr/bin. - The default value of the &PATH; environment variable - on a Windows system comes from the Windows registry - value for the command interpreter. - If you want to execute any commands--compilers, linkers, etc.--that - are not in these default locations, - you need to set the &PATH; value - in the &cv-ENV; dictionary - in your construction environment. - - - - - - The simplest way to do this is to initialize explicitly - the value when you create the construction environment; - this is one way to do that: - - - - - path = ['/usr/local/bin', '/bin', '/usr/bin'] - env = Environment(ENV = {'PATH' : path}) - - - - - Assign a dictionary to the &cv-ENV; - construction variable in this way - completely resets the external environment - so that the only variable that will be - set when external commands are executed - will be the &PATH; value. - If you want to use the rest of - the values in &cv-ENV; and only - set the value of &PATH;, - the most straightforward way is probably: - - - - - env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin'] - - - - - Note that &SCons; does allow you to define - the directories in the &PATH; in a string, - separated by the pathname-separator character - for your system (':' on POSIX systems, ';' on Windows): - - - - - 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). - - - - - -
- Propagating &PATH; From the External Environment - - - - You may want to propagate the external &PATH; - to the execution environment for commands. - You do this by initializing the &PATH; - variable with the &PATH; value from - the os.environ - dictionary, - which is Python's way of letting you - get at the external environment: - - - - - import os - env = Environment(ENV = {'PATH' : os.environ['PATH']}) - - - - - Alternatively, you may find it easier - to just propagate the entire external - environment to the execution environment - for commands. - This is simpler to code than explicity - selecting the &PATH; value: - - - - - import os - env = Environment(ENV = os.environ) - - - - - Either of these will guarantee that - &SCons; will be able to execute - any command that you can execute from the command line. - The drawback is that the build can behave - differently if it's run by people with - different &PATH; values in their environment--for example, - if both the /bin and - /usr/local/bin directories - have different &cc; commands, - then which one will be used to compile programs - will depend on which directory is listed - first in the user's &PATH; variable. - - - -
- -
- Adding to <varname>PATH</varname> Values in the Execution Environment - - - - One of the most common requirements - for manipulating a variable in the execution environment - is to add one or more custom directories to a search - like the $PATH variable on Linux or POSIX systems, - or the %PATH% variable on Windows, - so that a locally-installed compiler or other utility - can be found when &SCons; tries to execute it to update a target. - &SCons; provides &PrependENVPath; and &AppendENVPath; functions - to make adding things to execution variables convenient. - You call these functions by specifying the variable - to which you want the value added, - and then value itself. - So to add some /usr/local directories - to the $PATH and $LIB variables, - you might: - - - - - env = Environment(ENV = os.environ) - env.PrependENVPath('PATH', '/usr/local/bin') - env.AppendENVPath('LIB', '/usr/local/lib') - - - - - Note that the added values are strings, - and if you want to add multiple directories to - a variable like $PATH, - you must include the path separate character - (: on Linux or POSIX, - ; on Windows) - in the string. - - - -
- -
-- cgit v1.2.3