env['_CPPINCFLAGS'] = '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs)} $)',
.EE
+.IP CPPDEFINES
+A platform independent specification of C preprocessor definitions.
+The definitions will be added to command lines
+through the automatically-generated
+$_CPPDEFFLAGS construction variable (see below),
+which is constructed according to
+the type of value of $CPPDEFINES:
+
+.IP
+If $CPPDEFINES is a string,
+the values of the
+$CPPDEFPREFIX and $CPPDEFSUFFIX
+construction variables
+will be added to the beginning and end.
+
+.ES
+# Will add -Dxyz to POSIX compiler command lines,
+# and /Dxyz to Microsoft Visual C++ command lines.
+env = Environment(CPPDEFINES='xyz')
+.EE
+
+.IP
+If $CPPDEFINES is a list,
+the values of the
+$CPPDEFPREFIX and $CPPDEFSUFFIX
+construction variables
+will be appended to the beginning and end
+of each element in the list.
+If any element is a list or tuple,
+then the first item is the name being
+defined and the second item is its value:
+
+.ES
+# Will add -DB=2 -DA to POSIX compiler command lines,
+# and /DB=2 /DA to Microsoft Visual C++ command lines.
+env = Environment(CPPDEFINES=[('B', 2), 'A'])
+.EE
+
+.IP
+If $CPPDEFINES is a dictionary,
+the values of the
+$CPPDEFPREFIX and $CPPDEFSUFFIX
+construction variables
+will be appended to the beginning and end
+of each item from the dictionary.
+The key of each dictionary item
+is a name being defined
+to the dictionary item's corresponding value;
+if the value is
+.BR None ,
+then the name is defined without an explicit value.
+Note that the resulting flags are sorted by keyword
+to ensure that the order of the options on the
+command line is consistent each time
+.B scons
+ is run.
+
+.ES
+# Will add -DA -DB=2 to POSIX compiler command lines,
+# and /DA /DB=2 to Microsoft Visual C++ command lines.
+env = Environment(CPPDEFINES={'B':2, 'A':None})
+.EE
+
+.IP _CPPDEFFLAGS
+An automatically-generated construction variable
+containing the C preprocessor command-line options
+to define values.
+The value of $_CPPDEFFLAGS is created
+by appending $CPPDEFPREFIX and $CPPDEFSUFFIX
+to the beginning and end
+of each directory in $CPPDEFINES.
+
+.IP CPPDEFPREFIX
+The prefix used to specify preprocessor definitions
+on the C compiler command line.
+This will be appended to the beginning of each definition
+in the $CPPDEFINES construction variable
+when the $_CPPDEFFLAGS variable is automatically generated.
+
+.IP CPPDEFSUFFIX
+The suffix used to specify preprocessor definitions
+on the C compiler command line.
+This will be appended to the end of each definition
+in the $CPPDEFINES construction variable
+when the $_CPPDEFFLAGS variable is automatically generated.
+
.IP CPPFLAGS
User-specified C preprocessor options.
These will be included in any command that uses the C preprocessor,
including not just compilation of C and C++ source files
via the $CCCOM, $SHCCCOM, $CXXCOM and $SHCXXCOM command lines,
-but also the $F77PPCOM command line
+but also the $F77PPCOM and $SHF77PPCOM command lines
used to compile a Fortran source file,
and the $ASPPCOM command line
used to assemble an assembly language source file,
- When the -debug=pdb option is specified, use pdb.Pdb().runcall() to
call pdb directly, don't call Python recursively.
+ From Ben Scott:
+
+ - Add support for a platform-independent CPPDEFINES variable.
+
From Christoph Wiedemann:
- Have the g++ Tool actually use g++ in preference to c++.
import shutil
import stat
import string
+import types
import SCons.Action
import SCons.Builder
return ret
return c(prefix, list, suffix, env, f)
+def _defines(prefix, defs, suffix, env, c=_concat):
+ """A wrapper around _concat that turns a list or string
+ into a list of C preprocessor command-line definitions.
+ """
+ if SCons.Util.is_List(defs):
+ l = []
+ for d in defs:
+ if SCons.Util.is_List(d) or type(d) is types.TupleType:
+ l.append(str(d[0]) + '=' + str(d[1]))
+ else:
+ l.append(str(d))
+ elif SCons.Util.is_Dict(defs):
+ # The items in a dictionary are stored in random order, but
+ # if the order of the command-line options changes from
+ # invocation to invocation, then the signature of the command
+ # line will change and we'll get random unnecessary rebuilds.
+ # Consequently, we have to sort the keys to ensure a
+ # consistent order...
+ l = []
+ keys = defs.keys()
+ keys.sort()
+ for k in keys:
+ v = defs[k]
+ if v is None:
+ l.append(str(k))
+ else:
+ l.append(str(k) + '=' + str(v))
+ else:
+ l = [str(defs)]
+ return c(prefix, l, suffix, env)
+
class NullCmdGenerator:
"""This is a callable class that can be used in place of other
command generators if you don't want them to do anything.
'ENV' : {},
'INSTALL' : copyFunc,
'_concat' : _concat,
+ '_defines' : _defines,
'_stripixes' : _stripixes,
'_LIBFLAGS' : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
'_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs)} $)',
'_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs)} $)',
'_F77INCFLAGS' : '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs)} $)',
+ '_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
'TEMPFILE' : NullCmdGenerator
}
env['AS'] = '386asm'
env['ASFLAGS'] = ''
env['ASCOM'] = '$AS $ASFLAGS $SOURCES -o $TARGET'
- env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $SOURCES -o $TARGET'
+ env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES -o $TARGET'
addPharLapPaths(env)
env['AS'] = env.Detect(assemblers) or 'as'
env['ASFLAGS'] = ''
env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES'
- env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
def exists(env):
return env.Detect(assemblers)
env['CC'] = 'cc'
env['CCFLAGS'] = ''
- env['CCCOM'] = '$CC $CCFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['CCCOM'] = '$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
env['SHCC'] = '$CC'
env['SHCCFLAGS'] = '$CCFLAGS'
- env['SHCCCOM'] = '$SHCC $SHCCFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['SHCCCOM'] = '$SHCC $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
env['CXX'] = 'c++'
env['CXXFLAGS'] = '$CCFLAGS'
- env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
env['SHCXX'] = '$CXX'
env['SHCXXFLAGS'] = '$CXXFLAGS'
- env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['CPPDEFPREFIX'] = '-D'
+ env['CPPDEFSUFFIX'] = ''
env['INCPREFIX'] = '-I'
env['INCSUFFIX'] = ''
env['SHOBJSUFFIX'] = '.os'
env['F77'] = env.Detect(compilers) or 'f77'
env['F77FLAGS'] = ''
env['F77COM'] = '$F77 $F77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
- env['F77PPCOM'] = '$F77 $F77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
+ env['F77PPCOM'] = '$F77 $F77FLAGS $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
env['SHF77'] = '$F77'
env['SHF77FLAGS'] = '$F77FLAGS'
env['SHF77COM'] = '$SHF77 $SHF77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
- env['SHF77PPCOM'] = '$SHF77 $SHF77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
+ env['SHF77PPCOM'] = '$SHF77 $SHF77FLAGS $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
def exists(env):
return env.Detect(compilers)
env['CXX'] = env.Detect(compilers) or 'g++'
env['CXXFLAGS'] = '$CCFLAGS'
- env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
env['SHCXX'] = '$CXX'
if env['PLATFORM'] == 'cygwin':
env['SHCXXFLAGS'] = '$CXXFLAGS'
else:
env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC'
- env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
+ env['CPPDEFPREFIX'] = '-D'
+ env['CPPDEFSUFFIX'] = ''
env['INCPREFIX'] = '-I'
env['INCSUFFIX'] = ''
cc.generate(env)
env['CC'] = 'icc'
- env['CCCOM'] = '$CC $CCFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET'
- env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET'
+ env['CCCOM'] = '$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET'
+ env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET'
+ env['CPPDEFPREFIX'] = '/D'
+ env['CPPDEFSUFFIX'] = ''
env['INCPREFIX'] = '/I'
+ env['INCSUFFIX'] = ''
env['CFILESUFFIX'] = '.c'
env['CXXFILESUFFIX'] = '.cc'
env['F77'] = 'ifl'
env['F77FLAGS'] = ''
env['F77COM'] = '$F77 $F77FLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET'
- env['F77PPCOM'] = '$F77 $F77FLAGS $CPPFLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET'
+ env['F77PPCOM'] = '$F77 $F77FLAGS $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET'
env['SHF77'] = '$F77'
env['SHF77FLAGS'] = '$F77FLAGS'
env['SHF77COM'] = '$SHF77 $SHF77FLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET'
- env['SHF77PPCOM'] = '$SHF77 $SHF77FLAGS $CPPFLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET'
+ env['SHF77PPCOM'] = '$SHF77 $SHF77FLAGS $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET'
def exists(env):
return env.Detect('ifl')
env['AS'] = 'ml'
env['ASFLAGS'] = '/nologo'
env['ASCOM'] = '$AS $ASFLAGS /c /Fo$TARGET $SOURCES'
- env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS /c /Fo$TARGET $SOURCES'
+ env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c /Fo$TARGET $SOURCES'
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
def exists(env):
env['CCPDBFLAGS'] = '${(PDB and "/Zi /Fd%s"%File(PDB)) or ""}'
env['CCPCHFLAGS'] = '${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'
- env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS'
+ env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS'
env['CC'] = 'cl'
env['CCFLAGS'] = '/nologo'
env['CCCOM'] = '$CC $CCFLAGS $CCCOMFLAGS'
env['SHCXX'] = '$CXX'
env['SHCXXFLAGS'] = '$CXXFLAGS'
env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS'
+ env['CPPDEFPREFIX'] = '/D'
+ env['CPPDEFSUFFIX'] = ''
env['INCPREFIX'] = '/I'
env['INCSUFFIX'] = ''
env['OBJEMITTER'] = object_emitter
env['RC'] = 'rc'
env['RCFLAGS'] = ''
- env['RCCOM'] = '$RC $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
+ env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
CScan = env.get_scanner('.c')
if CScan:
CScan.add_skey('.rc')
env['CFILESUFFIX'] = '.c'
env['CXXFILESUFFIX'] = '.cc'
- env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS'
+ env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS'
env['BUILDERS']['PCH'] = pch_builder
def exists(env):
env['AS'] = 'nasm'
env['ASFLAGS'] = ''
env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES'
- env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS -c -o $TARGET $SOURCES'
+ env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
def exists(env):
return env.Detect('nasm')
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+XXX Put a description of the test here.
+"""
+
+import string
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+# Make sure $_CPPDEFFLAGS doesn't barf when CPPDEFINES isn't defined.
+test.write('SConstruct', """\
+env = Environment()
+print env.subst('$_CPPDEFFLAGS')
+""")
+
+expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n",
+ read_str = "\n")
+
+test.run(arguments = '.', stdout=expect)
+
+# Test CPPDEFINES as a string and a list.
+test.write('SConstruct', """\
+test_list = [
+ 'xyz',
+ ['x', 'y', 'z'],
+ ['x', ['y', 123], 'z'],
+ { 'c' : 3, 'b': None, 'a' : 1 },
+]
+env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='')
+for i in test_list:
+ print env.Copy(CPPDEFINES=i).subst('$_CPPDEFFLAGS')
+env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|')
+for i in test_list:
+ print env.Copy(CPPDEFINES=i).subst('$_CPPDEFFLAGS')
+""")
+
+expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n",
+ read_str = """\
+-Dxyz
+-Dx -Dy -Dz
+-Dx -Dy=123 -Dz
+-Da=1 -Db -Dc=3
+|xyz|
+|x| |y| |z|
+|x| |y=123| |z|
+|a=1| |b| |c=3|
+""")
+
+test.run(arguments = '.', stdout=expect)
+
+test.write('SConstruct', """\
+foo = Environment(CPPDEFINES = ['FOO', ('VAL', 7)])
+bar = Environment(CPPDEFINES = {'BAR':None, 'VAL':8})
+f = foo.Object(target = 'foo', source = 'prog.c')
+b = bar.Object(target = 'bar', source = 'prog.c')
+foo.Program(target = 'foo', source = f)
+bar.Program(target = 'bar', source = b)
+""")
+
+test.write('prog.c', r"""
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+#ifdef FOO
+ printf("prog.c: FOO %d\n", VAL);
+#endif
+#ifdef BAR
+ printf("prog.c: BAR %d\n", VAL);
+#endif
+ exit (0);
+}
+""")
+
+
+test.run(arguments = '.')
+
+test.run(program = test.workpath('foo'), stdout = "prog.c: FOO 7\n")
+test.run(program = test.workpath('bar'), stdout = "prog.c: BAR 8\n")
+
+test.pass_test()