to update the new construction environment:
.ES
-def my_tool(env, platform):
+def my_tool(env):
env['XYZZY'] = 'xyzzy'
env = Environment(tools = [my_tool])
.EE
+The tool definition (i.e. my_tool()) can use the PLATFORM variable from
+the environment it receives to customize the tool for different platforms.
+
If no tool list is specified, then SCons will auto-detect the installed
tools using the PATH variable in the ENV construction variable and the
platform name when the Environment is constructed. Changing the PATH
.IP PDFSUFFIX
The suffix used for PDF file names.
+.IP PLATFORM
+The name of the platform used to create the Environment. If no platform is
+specified when the Environment is created,
+.B SCons
+autodetects the platform.
+
+.ES
+env = Environment(tools = [])
+if env['PLATFORM'] == 'cygwin':
+ Tool('mingw')(env)
+else:
+ Tool('msvc')(env)
+.EE
+
.IP PROGPREFIX
The prefix used for executable file names.
- Use .dll (not .so) for shared libraries on Cygwin.
+ - Add a PLATFORM variable to construction environments.
+
+ - Remove the "platform" argument from tool specifications.
+
From Steven Knight:
- Add support for Java (javac and jar).
Please note the following important changes since release 0.13:
- -
+ - Tool specifications no longer take a "platform" argument.
+ XXX
Please note the following important changes since release 0.11:
if SCons.Util.is_String(platform):
platform = SCons.Platform.Platform(platform)
+ self._dict['PLATFORM'] = str(platform)
platform(self)
# Apply the passed-in variables before calling the tools,
for tool in tools:
if SCons.Util.is_String(tool):
tool = SCons.Tool.Tool(tool)
- tool(self, platform)
+ tool(self)
# Reapply the passed in variables after calling the tools,
# since they should overide anything set by the tools:
def test_platform(self):
"""Test specifying a platform callable when instantiating."""
- def p(env):
- env['XYZZY'] = 777
- env = Environment(platform = p)
+ class platform:
+ def __str__(self): return "TestPlatform"
+ def __call__(self, env): env['XYZZY'] = 777
+
+ def tool(env):
+ assert env['PLATFORM'] == "TestPlatform"
+
+ env = Environment(platform = platform(), tools = [tool])
assert env['XYZZY'] == 777, env
+ assert env['PLATFORM'] == "TestPlatform"
def test_tools(self):
"""Test specifying a tool callable when instantiating."""
- def t1(env, platform):
+ def t1(env):
env['TOOL1'] = 111
- def t2(env, platform):
+ def t2(env):
env['TOOL2'] = 222
- def t3(env, platform):
+ def t3(env):
env['AAA'] = env['XYZ']
+ def t4(env):
+ env['TOOL4'] = 444
env = Environment(tools = [t1, t2, t3], XYZ = 'aaa')
assert env['TOOL1'] == 111, env['TOOL1']
assert env['TOOL2'] == 222, env
- assert env['AAA'] == 'aaa', env
+ assert env['AAA'] == 'aaa', env
+ t4(env)
+ assert env['TOOL4'] == 444, env
+
def test_get(self):
"""Test the get() method."""
else:
ASPPSuffixes.extend(['.S'])
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for ar to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
import SCons.Builder
-def generate(env, platform):
+def generate(env):
"""Add a Builder factory function and construction variables for
BitKeeper to an Environment."""
import SCons.Builder
-def generate(env, platform):
+def generate(env):
"""Add a Builder factory function and construction variables for
CVS to an Environment."""
_import_env = [ 'P4PORT', 'P4CLIENT', 'P4USER', 'USER', 'USERNAME', 'P4PASSWD',
'P4CHARSET', 'P4LANGUAGE', 'SYSTEMROOT' ]
-def generate(env, platform):
+def generate(env):
"""Add a Builder factory function and construction variables for
Perforce to an Environment."""
import SCons.Builder
-def generate(env, platform):
+def generate(env):
"""Add a Builder factory function and construction variables for
RCS to an Environment."""
import SCons.Builder
-def generate(env, platform):
+def generate(env):
"""Add a Builder factory function and construction variables for
SCCS to an Environment."""
import SCons.Builder
-def generate(env, platform):
+def generate(env):
"""Add a Builder factory function and construction variables for
Subversion to an Environment."""
env['BUILDERS'] = {}
env['ENV'] = {}
t = SCons.Tool.Tool('g++')
- t(env, 'foo')
+ t(env)
assert (env['CXX'] == 'c++' or env['CXX'] == 'g++'), env['CXX']
assert env['CXXFLAGS'] == '$CCFLAGS', env['CXXFLAGS']
assert env['INCPREFIX'] == '-I', env['INCPREFIX']
def __str__(self):
return self.name
-def Tool(name, platform = None):
+def Tool(name):
"""Select a canned Tool specification.
"""
full_name = 'SCons.Tool.' + name
import SCons.Defaults
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for ar to an Environment."""
bld = SCons.Defaults.StaticLibrary
env['BUILDERS']['Library'] = bld
import SCons.Tool
-def generate(env, platform):
+def generate(env):
"""Add default tools."""
- for t in SCons.Tool.tool_list(platform, env):
- SCons.Tool.Tool(t, platform)(env, platform)
+ for t in SCons.Tool.tool_list(env['PLATFORM'], env):
+ SCons.Tool.Tool(t)(env)
def exists(env):
return 1
import SCons.Defaults
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for dvipdf to an Environment."""
try:
bld = env['BUILDERS']['PDF']
src_suffix = '.dvi',
src_builder = 'DVI')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for dvips to an Environment."""
env['BUILDERS']['PostScript'] = PostScript
if os.path.normcase('.c') != os.path.normcase('.C'):
CXXSuffixes.append('.C')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for g++ to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
else:
F77PPSuffixes.append('.F')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for g77 to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
else:
ASPPSuffixes.extend(['.S'])
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for as to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
if os.path.normcase('.c') == os.path.normcase('.C'):
CSuffixes.append('.C')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for gcc to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
linkers = ['c++', 'cc', 'g++', 'gcc']
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for gnulink to an Environment."""
env['BUILDERS']['SharedLibrary'] = SCons.Defaults.SharedLibrary
env['BUILDERS']['Program'] = SCons.Defaults.Program
CSuffixes = ['.c', '.C']
CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for MSVC++ to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
else:
F77PPSuffixes.append('.F')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for ifl to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
import SCons.Defaults
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for ilink to an Environment."""
env['BUILDERS']['Program'] = SCons.Defaults.Program
import SCons.Builder
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for jar to an Environment."""
try:
bld = env['BUILDERS']['Jar']
f.close()
return pkg_dir, classes
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for javac to an Environment."""
def emit_java_files(target, source, env):
"""Create and return lists of source java files
LaTeXAction = SCons.Action.Action('$LATEXCOM')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for LaTeX to an Environment."""
try:
import SCons.Defaults
import SCons.Tool
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for lex to an Environment."""
c_file, cxx_file = SCons.Tool.createCFileBuilders(env)
else:
return "${TEMPFILE('" + self.cmdline + "')}"
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for ar to an Environment."""
env['BUILDERS']['SharedLibrary'] = SCons.Defaults.SharedLibrary
env['BUILDERS']['Program'] = SCons.Defaults.Program
else:
ASPPSuffixes.extend(['.S'])
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for masm to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
res_builder = SCons.Builder.Builder(action='$RCCOM', suffix='.o')
-def generate(env, platform):
-
+def generate(env):
mingw = find(env)
if mingw:
dir = os.path.dirname(mingw)
# Most of mingw is the same as gcc and friends...
gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas']
for tool in gnu_tools:
- SCons.Tool.Tool(tool, platform)(env,platform)
+ SCons.Tool.Tool(tool)(env)
#... but a few things differ:
env['CC'] = 'gcc'
import SCons.Defaults
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for lib to an Environment."""
env['BUILDERS']['Library'] = SCons.Defaults.StaticLibrary
env['BUILDERS']['StaticLibrary'] = SCons.Defaults.StaticLibrary
return (target,source)
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for ar to an Environment."""
env['BUILDERS']['SharedLibrary'] = SCons.Defaults.SharedLibrary
env['BUILDERS']['Program'] = SCons.Defaults.Program
pch_builder = SCons.Builder.Builder(action='$PCHCOM', suffix='.pch', emitter=pch_emitter)
res_builder = SCons.Builder.Builder(action='$RCCOM', suffix='.res')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for MSVC++ to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
else:
ASPPSuffixes.extend(['.S'])
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for nasm to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
PDFLaTeXAction = SCons.Action.Action('$PDFLATEXCOM')
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for pdflatex to an Environment."""
try:
bld = env['BUILDERS']['PDF']
import SCons.Defaults
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for pdftex to an Environment."""
try:
bld = env['BUILDERS']['PDF']
import SCons.Defaults
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for ar to an Environment."""
bld = SCons.Defaults.StaticLibrary
env['BUILDERS']['Library'] = bld
assemblers = ['as']
ASSuffixes = ['.s', '.asm', '.ASM']
-ASPPSuffixes = ['.spp', '.SPP']
+ASPPSuffixes = ['.S', '.spp', '.SPP']
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for as to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
import SCons.Util
CSuffixes = ['.c']
-CXXSuffixes = ['.C', '.cpp', '.cc', '.cxx']
+CXXSuffixes = ['.C', '.cpp', '.cc', '.cxx', '.c++', '.C++']
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for gcc to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
compilers = ['f77']
-F77Suffixes = ['.f', '.for', '.F', '.FOR']
-F77PPSuffixes = ['.fpp', '.FPP']
+F77Suffixes = ['.f', '.for', '.FOR']
+F77PPSuffixes = ['.F', '.fpp', '.FPP']
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for g77 to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
env['F77COM'] = '$F77 $F77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
env['F77PPCOM'] = '$F77 $F77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
env['SHF77'] = '$F77'
- env['SHF77FLAGS'] = '$F77FLAGS -fPIC'
+ env['SHF77FLAGS'] = '$F77FLAGS'
env['SHF77COM'] = '$SHF77 $SHF77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
env['SHF77PPCOM'] = '$SHF77 $SHF77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
linkers = ['CC', 'cc']
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for MIPSPro to an Environment."""
env['BUILDERS']['SharedLibrary'] = SCons.Defaults.SharedLibrary
env['BUILDERS']['Program'] = SCons.Defaults.Program
multi = 1)
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for tar to an Environment."""
try:
bld = env['BUILDERS']['Tar']
import SCons.Defaults
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for TeX to an Environment."""
try:
bld = env['BUILDERS']['DVI']
import SCons.Tool
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for yacc to an Environment."""
c_file, cxx_file = SCons.Tool.createCFileBuilders(env)
multi = 1)
-def generate(env, platform):
+def generate(env):
"""Add Builders and construction variables for zip to an Environment."""
try:
bld = env['BUILDERS']['Zip']
test.write('SConstruct', """
env = Environment(LINK = r'%s mylink.py',
+ LINKFLAGS = [],
AS = r'%s myas.py',
CC = r'%s myas.py')
env.Program(target = 'test1', source = 'test1.s')
as = test.detect('AS', 'as')
+x86 = (sys.platform == 'win32' or string.find(sys.platform, 'linux') != -1)
-if as:
+if as and x86:
test.write("wrapper.py",
"""import os
ml = test.where_is('ml')
-if ml:
+if ml and sys.platform == 'win32':
test.write("wrapper.py",
"""import os
test.write('SConstruct', """
env = Environment(LINK = r'%s mylink.py',
+ LINKFLAGS = [],
AS = r'%s myas.py', ASFLAGS = '-x',
CC = r'%s myas.py')
env.Program(target = 'test1', source = 'test1.s')
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os.path
+import string
import sys
import time
import TestSCons
env = Environment(CPPPATH='.', F77PATH='.')
SConscript('../build/var5/SConscript', "env")
SConscript('../build/var6/SConscript', "env")
-""")
+""")
+
+if string.find(sys.platform, 'irix') != -1:
+ fortran_runtime = 'ftn'
+else:
+ fortran_runtime = 'g2c'
test.subdir(['test', 'src'])
test.write(['test', 'src', 'SConscript'], """
if f77 and WhereIs(env['F77']):
env.Command(target='b2.f', source='b2.in', action=buildIt)
- env.Copy(LIBS = ['g2c']).Program(target='bar2', source='b2.f')
- env.Copy(LIBS = ['g2c']).Program(target='bar1', source='b1.f')
-""")
+ env.Copy(LIBS = [r'%s']).Program(target='bar2', source='b2.f')
+ env.Copy(LIBS = [r'%s']).Program(target='bar1', source='b1.f')
+""" % (fortran_runtime, fortran_runtime))
test.write('test/src/f1.c', r"""
#include "f1.h"
test.write('SConstruct', """
cc = Environment().Dictionary('CC')
env = Environment(LINK = r'%s mylink.py',
+ LINKFLAGS = [],
CC = r'%s mycc.py',
- CXX = cc)
+ CXX = cc,
+ CXXFLAGS = [])
env.Program(target = 'test1', source = 'test1.c')
""" % (python, python))
if sys.platform == 'win32':
_exe = '.exe'
_obj = '.obj'
+ _shobj = '.obj'
else:
_exe = ''
_obj = '.o'
+ _shobj = '.os'
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(CPPFLAGS = '-x',
LINK = r'%s mylink.py',
+ LINKFLAGS = [],
CC = r'%s mygcc.py cc',
CXX = r'%s mygcc.py c++',
+ CXXFLAGS = [],
F77 = r'%s mygcc.py g77')
env.Program(target = 'foo', source = Split('test1.c test2.cpp test3.F'))
""" % (python, python, python, python))
#link
""")
-test.run(arguments = '.', stderr = None)
+test.run(arguments = '.', stderr=None)
test.fail_test(test.read('test1' + _obj) != "test1.c\n#link\n")
test.write('SConstruct', """
env = Environment(CPPFLAGS = '-x',
SHLINK = r'%s mylink.py',
+ SHLINKFLAGS = [],
CC = r'%s mygcc.py cc',
CXX = r'%s mygcc.py c++',
+ CXXFLAGS = [],
F77 = r'%s mygcc.py g77')
env.SharedLibrary(target = File('foo.bar'),
source = Split('test1.c test2.cpp test3.F'))
""")
test.unlink('mygcc.out')
+test.unlink('test1' + _obj)
+test.unlink('test2' + _obj)
+test.unlink('test3' + _obj)
test.run(arguments = '.', stderr = None)
-test.fail_test(test.read('test1' + _obj) != "test1.c\n#link\n")
+test.fail_test(test.read('test1' + _shobj) != "test1.c\n#link\n")
-test.fail_test(test.read('test2' + _obj) != "test2.cpp\n#link\n")
+test.fail_test(test.read('test2' + _shobj) != "test2.cpp\n#link\n")
-test.fail_test(test.read('test3' + _obj) != "test3.F\n#link\n")
+test.fail_test(test.read('test3' + _shobj) != "test3.F\n#link\n")
test.fail_test(test.read('foo.bar') != "test1.c\ntest2.cpp\ntest3.F\n")
# Check that a null-string CPPPATH doesn't blow up.
test.write('SConstruct', """
env = Environment(CPPPATH = '')
-env.Library('foo', source = '')
+env.Library('foo', source = 'empty.c')
+""")
+
+test.write('empty.c', """
""")
test.run(arguments = '.')
# Test the most straightforward CVS checkouts, using the module name.
test.write(['work1', 'SConstruct'], """
+import os
def cat(env, source, target):
target = str(target[0])
source = map(str, source)
for src in source:
f.write(open(src, "rb").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(ENV = { 'PATH' : os.environ['PATH'] },
+ BUILDERS={'Cat':Builder(action=cat)})
env.Prepend(CVSFLAGS='-Q ')
env.Cat('aaa.out', 'foo/aaa.in')
env.Cat('bbb.out', 'foo/bbb.in')
# Test CVS checkouts when the module name is specified.
test.write(['work2', 'SConstruct'], """
+import os
def cat(env, source, target):
target = str(target[0])
source = map(str, source)
for src in source:
f.write(open(src, "rb").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env = Environment(ENV = { 'PATH' : os.environ['PATH'] },
+ BUILDERS={'Cat':Builder(action=cat)})
env.Prepend(CVSFLAGS='-q ')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
test.write('SConstruct', """
env = Environment(LINK = r'%s mylink.py',
- CXX = r'%s myc++.py')
+ LINKFLAGS = [],
+ CXX = r'%s myc++.py',
+ CXXFLAGS = [])
env.Program(target = 'test1', source = 'test1.cc')
env.Program(target = 'test2', source = 'test2.cpp')
env.Program(target = 'test3', source = 'test3.cxx')
test.write('SConstruct', """
env = Environment(LINK = r'%s mylink.py',
- CXX = r'%s myc++.py')
+ LINKFLAGS = [],
+ CXX = r'%s myc++.py',
+ CXXFLAGS = [])
env.Program(target = 'test6', source = 'test6.C')
""" % (python, python))
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment()
+import os
+foo = Environment(ENV = { 'PATH' : os.environ['PATH'] })
dvipdf = foo.Dictionary('DVIPDF')
-bar = Environment(DVIPDF = r'%s wrapper.py ' + dvipdf)
+bar = Environment(ENV = { 'PATH' : os.environ['PATH'] },
+ DVIPDF = r'%s wrapper.py ' + dvipdf)
foo.PDF(target = 'foo.pdf',
source = foo.DVI(target = 'foo.dvi', source = 'foo.tex'))
bar.PDF(target = 'bar.pdf',
test.fail_test(test.read('test2' + _exe) != "test2.CLASS\nline 3\n")
+if not os.path.exists('/usr/local/j2sdk1.3.1/bin/javac'):
+ print "Could not find Java, skipping test(s)."
+ test.pass_test(1)
test.write("wrapper.py", """\
}
""")
+if not os.path.exists('/usr/local/j2sdk1.3.1/bin/javac'):
+ print "Could not find Java, skipping test(s)."
+ test.pass_test(1)
+
test.run(arguments = '.',
stdout = test.wrap_stdout("""\
/usr/local/j2sdk1.3.1/bin/javac -d classes -sourcepath src src/Example1.java
test.fail_test(test.read('test2.class') != "test2.JAVA\nline3\n")
+if not os.path.exists('/usr/local/j2sdk1.3.1/bin/javac'):
+ print "Could not find Java, skipping test(s)."
+ test.pass_test(1)
test.write("wrapper.py", """\
test = TestSCons.TestSCons()
+if not os.path.exists('/usr/local/j2sdk1.3.1/bin/javac'):
+ print "Could not find Java, skipping test(s)."
+ test.pass_test(1)
+
test.subdir('src')
test.write('SConstruct', """
opts.Add('UNSPECIFIED',
'An option with no value')
-def test_tool(env, platform):
+def test_tool(env):
if env['RELEASE_BUILD']:
env['CCFLAGS'] = env['CCFLAGS'] + ' -O'
if env['DEBUG_BUILD']: