./SCons/Tool/icc.py
./SCons/Tool/ifl.py
./SCons/Tool/ilink.py
+./SCons/Tool/jar.py
+./SCons/Tool/javac.py
+./SCons/Tool/javah.py
./SCons/Tool/latex.py
./SCons/Tool/lex.py
./SCons/Tool/link.py
env.Java(target = 'classes', source = 'src')
.EE
+.IP JavaH
+Builds C header and source files for
+implementing Java native methods.
+The target can be either a directory
+in which the header files will be written,
+or a header file name which
+will contain all of the definitions.
+The source can be either the names of .class files,
+or the objects returned from the
+.B Java
+builder.
+
+If the construction variable
+.B JAVACLASSDIR
+is set, either in the environment
+or in the call to the
+.B JavaH
+builder itself,
+then the value of the variable
+will be stripped from the
+beginning of any .class file names.
+
+Examples:
+
+.ES
+# builds java_native.h
+classes = env.Java(target = 'classdir', source = 'src')
+env.JavaH(target = 'java_native.h', source = classes)
+
+# builds include/package_foo.h and include/package_bar.h
+env.JavaH(target = 'include',
+ source = ['package/foo.class', 'package/bar.class'])
+
+# builds export/foo.h and export/bar.h
+env.JavaH(target = 'export',
+ source = ['classes/foo.class', 'classes/bar.class'],
+ JAVACLASSDIR = 'classes')
+.EE
+
.IP TypeLibrary
Builds a Windows type library (.tlb) file from and input IDL file
(.idl). In addition, it will build the associated inteface stub and
.IP JAVACFLAGS
General options that are passed to the Java compiler.
+.IP JAVACLASSDIR
+The directory in which Java class files may be found.
+This is stripped from the beginning of any Java .class
+file names supplied to the
+.B JavaH
+builder.
+
.IP JAVACLASSSUFFIX
The suffix for Java class files;
.B .class
by default.
+.IP JAVAH
+The Java generator for C header and stub files.
+
+.IP JAVAHCOM
+The command line used to generate C header and stub files
+from Java classes.
+Any options specified in the $JAVAHFLAGS construction variable
+are included on this command line.
+
+.IP JAVAHFLAGS
+General options passed to the C header and stub file generator
+for Java classes.
+
.IP JAVASUFFIX
The suffix for Java files;
.B .java
- Parse the source .java files for class names (including inner class
names) to figure out the target .class files that will be created.
- - Fix Java support with Repositories and SConscriptChdir(0).
+ - Make Java support work with Repositories and SConscriptChdir(0).
- Pass Nodes, not strings, to Builder emitter functions.
From Steven Knight:
- - Add support for Java (javac and jar).
+ - Add Java support (javac, javah and jar).
- Propagate the external SYSTEMROOT environment variable into ENV on
Win32 systems, so external commands that use sockets will work.
SCons/Tool/gs.py
SCons/Tool/hpcc.py
SCons/Tool/hplink.py
-SCons/Tool/javac.py
SCons/Tool/jar.py
+SCons/Tool/javac.py
+SCons/Tool/javah.py
SCons/Tool/icc.py
SCons/Tool/ifl.py
SCons/Tool/ilink.py
other_tools = FindAllTools(['BitKeeper', 'CVS',
'dvipdf', 'dvips', 'gs',
- 'jar', 'javac',
+ 'jar', 'javac', 'javah',
'latex', 'lex', 'midl',
'pdflatex', 'pdftex', 'Perforce',
'RCS', 'SCCS',
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import os
import os.path
import re
import string
"""
return os.path.split(file)
-def emit_java_files(target, source, env):
+def classname(path):
+ """Turn a string (path name) into a Java class name."""
+ return string.replace(os.path.normpath(path), os.sep, '.')
+
+def emit_java_classes(target, source, env):
"""Create and return lists of source java files
and their corresponding target class files.
"""
- env['_JAVACLASSDIR'] = target[0]
- env['_JAVASRCDIR'] = source[0].rdir()
java_suffix = env.get('JAVASUFFIX', '.java')
class_suffix = env.get('JAVACLASSSUFFIX', '.class')
-
+
slist = []
js = _my_normcase(java_suffix)
def visit(arg, dirname, names, js=js, dirnode=source[0].rdir()):
java_files = filter(lambda n, js=js:
- _my_normcase(n[-len(js):]) == js,
+ _my_normcase(n[-len(js):]) == js,
names)
mydir = dirnode.Dir(dirname)
java_paths = map(lambda f, d=mydir: d.File(f), java_files)
arg.extend(java_paths)
os.path.walk(source[0].rdir().get_abspath(), visit, slist)
-
+
tlist = []
for file in slist:
pkg_dir, classes = parse_java(file.get_abspath())
if pkg_dir:
for c in classes:
- tlist.append(target[0].Dir(pkg_dir).File(c+class_suffix))
+ t = target[0].Dir(pkg_dir).File(c+class_suffix)
+ t.attributes.java_classdir = target[0]
+ t.attributes.java_classname = classname(pkg_dir + os.sep + c)
+ tlist.append(t)
elif classes:
for c in classes:
- tlist.append(target[0].File(c+class_suffix))
+ t = target[0].File(c+class_suffix)
+ t.attributes.java_classdir = target[0]
+ t.attributes.java_classname = classname(c)
+ tlist.append(t)
else:
# This is an odd end case: no package and no classes.
# Just do our best based on the source file name.
- tlist.append(target[0].File(str(file)[:-len(java_suffix)] + class_suffix))
-
+ base = str(file)[:-len(java_suffix)]
+ t = target[0].File(base + class_suffix)
+ t.attributes.java_classdir = target[0]
+ t.attributes.java_classname = classname(base)
+ tlist.append(t)
+
return tlist, slist
JavaBuilder = SCons.Builder.Builder(action = '$JAVACCOM',
- emitter = emit_java_files,
- target_factory = SCons.Node.FS.default_fs.Dir,
- source_factory = SCons.Node.FS.default_fs.Dir)
+ emitter = emit_java_classes,
+ target_factory = SCons.Node.FS.default_fs.Dir,
+ source_factory = SCons.Node.FS.default_fs.Dir)
def generate(env):
"""Add Builders and construction variables for javac to an Environment."""
-
env['BUILDERS']['Java'] = JavaBuilder
env['JAVAC'] = 'javac'
env['JAVACFLAGS'] = ''
- env['JAVACCOM'] = '$JAVAC $JAVACFLAGS -d $_JAVACLASSDIR -sourcepath $_JAVASRCDIR $SOURCES'
+ env['JAVACCOM'] = '$JAVAC $JAVACFLAGS -d ${TARGET.attributes.java_classdir} -sourcepath ${SOURCE.dir.rdir()} $SOURCES'
env['JAVACLASSSUFFIX'] = '.class'
env['JAVASUFFIX'] = '.java'
--- /dev/null
+"""SCons.Tool.javah
+
+Tool-specific initialization for javah.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# __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__"
+
+import os.path
+import re
+import string
+
+import SCons.Builder
+import SCons.Node.FS
+
+def emit_java_headers(target, source, env):
+ """Create and return lists of Java stub header files that will
+ be created from a set of class files.
+ """
+ class_suffix = env.get('JAVACLASSSUFFIX', '.class')
+ classdir = env.get('JAVACLASSDIR')
+
+ if not classdir:
+ try:
+ s = source[0]
+ except IndexError:
+ classdir = '.'
+ else:
+ try:
+ classdir = s.attributes.java_classdir
+ except:
+ pass
+ classdir = SCons.Node.FS.default_fs.Dir(classdir).rdir()
+ if str(classdir) == '.':
+ c_ = None
+ else:
+ c_ = str(classdir) + os.sep
+
+ slist = []
+ for src in source:
+ try:
+ classname = src.attributes.java_classname
+ except AttributeError:
+ classname = str(src)
+ if c_ and classname[:len(c_)] == c_:
+ classname = classname[len(c_):]
+ if class_suffix and classname[:-len(class_suffix)] == class_suffix:
+ classname = classname[-len(class_suffix):]
+ s = src.rfile()
+ s.attributes.java_classdir = classdir
+ s.attributes.java_classname = classname
+ slist.append(s)
+
+ if target[0].__class__ is SCons.Node.FS.File:
+ tlist = target
+ else:
+ if not isinstance(target[0], SCons.Node.FS.Dir):
+ target[0].__class__ = SCons.Node.FS.Dir
+ target[0]._morph()
+ File = SCons.Node.FS.default_fs.File
+ tlist = []
+ for s in source:
+ fname = string.replace(s.attributes.java_classname, '.', '_') + '.h'
+ t = target[0].File(fname)
+ t.attributes.java_lookupdir = target[0]
+ tlist.append(t)
+
+ return tlist, source
+
+def JavaHOutFlagGenerator(target, source, env, for_signature):
+ try:
+ t = target[0]
+ except AttributeError, TypeError:
+ t = target
+ try:
+ return '-d ' + str(t.attributes.java_lookupdir)
+ except AttributeError:
+ return '-o ' + str(t)
+
+JavaHBuilder = SCons.Builder.Builder(action = '$JAVAHCOM',
+ emitter = emit_java_headers,
+ src_suffix = '$JAVACLASSSUFFIX',
+ target_factory = SCons.Node.FS.default_fs.Entry,
+ source_factory = SCons.Node.FS.default_fs.File)
+
+def generate(env):
+ """Add Builders and construction variables for javah to an Environment."""
+ env['BUILDERS']['JavaH'] = JavaHBuilder
+
+ env['_JAVAHOUTFLAG'] = JavaHOutFlagGenerator
+ env['JAVAH'] = 'javah'
+ env['JAVAHFLAGS'] = ''
+ env['JAVAHCOM'] = '$JAVAH $JAVAHFLAGS $_JAVAHOUTFLAG -classpath ${SOURCE.attributes.java_classdir} ${SOURCES.attributes.java_classname}'
+ env['JAVACLASSSUFFIX'] = '.class'
+
+def exists(env):
+ return env.Detect('javah')
JAVAC = '/usr/local/j2sdk1.3.1/bin/javac')
javac = foo.Dictionary('JAVAC')
bar = foo.Copy(JAVAC = r'%s wrapper.py ' + javac)
-foo.Java(target = 'classes', source = 'com/sub/foo')
-bar.Java(target = 'classes', source = 'com/sub/bar')
-foo.Java(target = 'classes', source = 'src')
+foo.Java(target = 'class1', source = 'com/sub/foo')
+bar.Java(target = 'class2', source = 'com/sub/bar')
+foo.Java(target = 'class3', source = 'src')
""" % python)
test.subdir('com',
test.run(arguments = '.')
-test.fail_test(test.read('wrapper.out') != "wrapper.py /usr/local/j2sdk1.3.1/bin/javac -d classes -sourcepath com/sub/bar com/sub/bar/Example4.java com/sub/bar/Example5.java com/sub/bar/Example6.java\n")
-
-test.fail_test(not os.path.exists(test.workpath('classes', 'com', 'sub', 'foo', 'Example1.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'com', 'other', 'Example2.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'com', 'sub', 'foo', 'Example3.class')))
-
-test.fail_test(not os.path.exists(test.workpath('classes', 'com', 'sub', 'bar', 'Example4.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'com', 'other', 'Example5.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'com', 'sub', 'bar', 'Example6.class')))
-
-test.fail_test(not os.path.exists(test.workpath('classes', 'Empty.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Listener.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Private.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Private$1.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Test.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Test$1.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Test$2.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Test$3.class')))
-test.fail_test(not os.path.exists(test.workpath('classes', 'Test$Inner.class')))
+test.fail_test(test.read('wrapper.out') != "wrapper.py /usr/local/j2sdk1.3.1/bin/javac -d class2 -sourcepath com/sub/bar com/sub/bar/Example4.java com/sub/bar/Example5.java com/sub/bar/Example6.java\n")
+
+test.fail_test(not os.path.exists(test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class')))
+test.fail_test(not os.path.exists(test.workpath('class1', 'com', 'other', 'Example2.class')))
+test.fail_test(not os.path.exists(test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class')))
+
+test.fail_test(not os.path.exists(test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class')))
+test.fail_test(not os.path.exists(test.workpath('class2', 'com', 'other', 'Example5.class')))
+test.fail_test(not os.path.exists(test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class')))
+
+test.fail_test(not os.path.exists(test.workpath('class3', 'Empty.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Listener.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Private.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Private$1.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Test.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Test$1.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Test$2.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Test$3.class')))
+test.fail_test(not os.path.exists(test.workpath('class3', 'Test$Inner.class')))
test.up_to_date(arguments = '.')
--- /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__"
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+test.write('myjavah.py', r"""
+import sys
+args = sys.argv[1:]
+while args:
+ a = args[0]
+ if a == '-d':
+ args = args[1:]
+ elif a == '-sourcepath':
+ args = args[1:]
+ else:
+ break
+ args = args[1:]
+for file in args:
+ infile = open(file, 'rb')
+ outfile = open(file[:-5] + '.class', 'wb')
+ for l in infile.readlines():
+ if l[:9] != '/*javah*/':
+ outfile.write(l)
+sys.exit(0)
+""")
+
+test.write('SConstruct', """
+env = Environment(tools = ['javah'],
+ JAVAH = r'%s myjavah.py')
+env.JavaH(target = 'test1.class', source = 'test1.java')
+""" % (python))
+
+test.write('test1.java', """\
+test1.java
+/*javah*/
+line 3
+""")
+
+#test.run(arguments = '.', stderr = None)
+
+#test.fail_test(test.read('test1.class') != "test1.java\nline 3\n")
+
+if os.path.normcase('.java') == os.path.normcase('.JAVA'):
+
+ test.write('SConstruct', """\
+env = Environment(tools = ['javah'],
+ JAVAH = r'%s myjavah.py')
+env.Java(target = 'test2.class', source = 'test2.JAVA')
+""" % python)
+
+ test.write('test2.JAVA', """\
+test2.JAVA
+/*javah*/
+line 3
+""")
+
+ test.run(arguments = '.', stderr = None)
+
+ test.fail_test(test.read('test2.class') != "test2.JAVA\nline 3\n")
+
+
+if not os.path.exists('/usr/local/j2sdk1.3.1/bin/javah'):
+ print "Could not find Java, skipping test(s)."
+ test.pass_test(1)
+
+
+
+test.write("wrapper.py", """\
+import os
+import string
+import sys
+open('%s', 'ab').write("wrapper.py %%s\\n" %% string.join(sys.argv[1:]))
+os.system(string.join(sys.argv[1:], " "))
+""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+
+test.write('SConstruct', """
+foo = Environment(tools = ['javac', 'javah'],
+ JAVAC = '/usr/local/j2sdk1.3.1/bin/javac',
+ JAVAH = '/usr/local/j2sdk1.3.1/bin/javah')
+javah = foo.Dictionary('JAVAH')
+bar = foo.Copy(JAVAH = r'%s wrapper.py ' + javah)
+fff = foo.Java(target = 'class1', source = 'com/sub/foo')
+bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar')
+foo_classes = foo.Java(target = 'class3', source = 'src')
+foo.JavaH(target = 'outdir1',
+ source = ['class1/com/sub/foo/Example1.class',
+ 'class1/com/other/Example2',
+ 'class1/com/sub/foo/Example3'],
+ JAVACLASSDIR = 'class1')
+bar.JavaH(target = 'outdir2', source = bar_classes)
+foo.JavaH(target = File('output.h'), source = foo_classes)
+""" % python)
+
+test.subdir('com',
+ ['com', 'sub'],
+ ['com', 'sub', 'foo'],
+ ['com', 'sub', 'bar'],
+ 'src')
+
+test.write(['com', 'sub', 'foo', 'Example1.java'], """\
+package com.sub.foo;
+
+public class Example1
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example2.java'], """\
+package com.other;
+
+public class Example2
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example3.java'], """\
+package com.sub.foo;
+
+public class Example3
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example4.java'], """\
+package com.sub.bar;
+
+public class Example4
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example5.java'], """\
+package com.other;
+
+public class Example5
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example6.java'], """\
+package com.sub.bar;
+
+public class Example6
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['src', 'Test.java'], """\
+class Empty {
+}
+
+interface Listener {
+ public void execute();
+}
+
+public
+class
+Test {
+ class Inner {
+ void go() {
+ use(new Listener() {
+ public void execute() {
+ System.out.println("In Inner");
+ }
+ });
+ }
+ String s1 = "class A";
+ String s2 = "new Listener() { }";
+ /* class B */
+ /* new Listener() { } */
+ }
+
+ public static void main(String[] args) {
+ new Test().run();
+ }
+
+ void run() {
+ use(new Listener() {
+ public void execute() {
+ use(new Listener( ) {
+ public void execute() {
+ System.out.println("Inside execute()");
+ }
+ });
+ }
+ });
+
+ new Inner().go();
+ }
+
+ void use(Listener l) {
+ l.execute();
+ }
+}
+
+class Private {
+ void run() {
+ new Listener() {
+ public void execute() {
+ }
+ };
+ }
+}
+""")
+
+test.run(arguments = '.')
+
+test.fail_test(test.read('wrapper.out') != "wrapper.py /usr/local/j2sdk1.3.1/bin/javah -d outdir2 -classpath class2 com.sub.bar.Example4 com.other.Example5 com.sub.bar.Example6\n")
+
+test.fail_test(not os.path.exists(test.workpath('outdir1', 'com_sub_foo_Example1.h')))
+test.fail_test(not os.path.exists(test.workpath('outdir1', 'com_other_Example2.h')))
+test.fail_test(not os.path.exists(test.workpath('outdir1', 'com_sub_foo_Example3.h')))
+
+test.fail_test(not os.path.exists(test.workpath('outdir2', 'com_sub_bar_Example4.h')))
+test.fail_test(not os.path.exists(test.workpath('outdir2', 'com_other_Example5.h')))
+test.fail_test(not os.path.exists(test.workpath('outdir2', 'com_sub_bar_Example6.h')))
+
+test.up_to_date(arguments = '.')
+
+test.pass_test()
--- /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__"
+
+"""
+Test building Java applications when using Repositories.
+"""
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+java = '/usr/local/j2sdk1.3.1/bin/java'
+javac = '/usr/local/j2sdk1.3.1/bin/javac'
+javah = '/usr/local/j2sdk1.3.1/bin/javah'
+
+if not os.path.exists(javac):
+ print "Could not find Java (javac), skipping test(s)."
+ test.pass_test(1)
+
+if not os.path.exists(javah):
+ print "Could not find Java (javah), skipping test(s)."
+ test.pass_test(1)
+
+###############################################################################
+
+#
+test.subdir('rep1', ['rep1', 'src'],
+ 'work1',
+ 'work2',
+ 'work3')
+
+#
+rep1_classes = test.workpath('rep1', 'classes')
+work1_classes = test.workpath('work1', 'classes')
+work3_classes = test.workpath('work3', 'classes')
+
+#
+opts = '-Y ' + test.workpath('rep1')
+
+#
+test.write(['rep1', 'SConstruct'], """
+env = Environment(tools = ['javac', 'javah'],
+ JAVAC = r'%s',
+ JAVAH = r'%s')
+classes = env.Java(target = 'classes', source = 'src')
+env.JavaH(target = 'outdir', source = classes)
+""" % (javac, javah))
+
+test.write(['rep1', 'src', 'Foo1.java'], """\
+public class Foo1
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo1.java");
+
+ }
+}
+""")
+
+test.write(['rep1', 'src', 'Foo2.java'], """\
+public class Foo2
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo2.java");
+
+ }
+}
+""")
+
+test.write(['rep1', 'src', 'Foo3.java'], """\
+public class Foo3
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo3.java");
+
+ }
+}
+""")
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % work1_classes,
+ stdout = "rep1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % work1_classes,
+ stdout = "rep1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % work1_classes,
+ stdout = "rep1/src/Foo3.java\n")
+
+test.fail_test(not os.path.exists(test.workpath('work1', 'outdir', 'Foo1.h')))
+test.fail_test(not os.path.exists(test.workpath('work1', 'outdir', 'Foo2.h')))
+test.fail_test(not os.path.exists(test.workpath('work1', 'outdir', 'Foo3.h')))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.subdir(['work1', 'src'])
+
+test.write(['work1', 'src', 'Foo1.java'], """\
+public class Foo1
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo1.java");
+
+ }
+}
+""")
+
+test.write(['work1', 'src', 'Foo2.java'], """\
+public class Foo2
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo2.java");
+
+ }
+}
+""")
+
+test.write(['work1', 'src', 'Foo3.java'], """\
+public class Foo3
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo3.java");
+
+ }
+}
+""")
+
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % work1_classes,
+ stdout = "work1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % work1_classes,
+ stdout = "work1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % work1_classes,
+ stdout = "work1/src/Foo3.java\n")
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.writable('rep1', 1)
+
+test.run(chdir = 'rep1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % rep1_classes,
+ stdout = "rep1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % rep1_classes,
+ stdout = "rep1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % rep1_classes,
+ stdout = "rep1/src/Foo3.java\n")
+
+test.up_to_date(chdir = 'rep1', options = opts, arguments = ".")
+
+#
+test.writable('repository', 0)
+
+#
+test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+#
+test.write(['work3', 'SConstruct'], """
+env = Environment(tools = ['javac', 'javah'],
+ JAVAC = r'%s',
+ JAVAH = r'%s')
+classes = env.Java(target = 'classes', source = 'src')
+hfiles = env.JavaH(target = 'outdir', source = classes)
+Local(hfiles)
+""" % (javac, javah))
+
+test.run(chdir = 'work3', options = opts, arguments = ".")
+
+test.fail_test(os.path.exists(test.workpath('work3', 'classes', 'Foo1.class')))
+test.fail_test(os.path.exists(test.workpath('work3', 'classes', 'Foo2.class')))
+test.fail_test(os.path.exists(test.workpath('work3', 'classes', 'Foo3.class')))
+
+test.fail_test(not os.path.exists(test.workpath('work3', 'outdir', 'Foo1.h')))
+test.fail_test(not os.path.exists(test.workpath('work3', 'outdir', 'Foo2.h')))
+test.fail_test(not os.path.exists(test.workpath('work3', 'outdir', 'Foo3.h')))
+
+#
+# If the Java builder were to interact with Repositories like the
+# other builders, then we'd uncomment the following test(s).
+#
+# This tests that, if the .class files are built in the repository,
+# then a local build says that everything is up-to-date. However,
+# because the destination target is a directory ("classes") not a
+# file, we don't detect that the individual .class files are
+# already there, and think things must be rebuilt.
+#
+#test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+#
+#test.subdir(['work2', 'src'])
+#
+#test.write(['work2', 'src', 'Foo1.java'], """\
+#public class Foo1
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo1.java");
+#
+# }
+#}
+#""")
+#
+#test.write(['work2', 'src', 'Foo2.java'], """\
+#public class Foo2
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo2.java");
+#
+# }
+#}
+#""")
+#
+#test.write(['work2', 'src', 'Foo3.java'], """\
+#public class Foo3
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo3.java");
+#
+# }
+#}
+#""")
+#
+#test.run(chdir = 'work2', options = opts, arguments = ".")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo1" % work2_classes,
+# stdout = "work2/src/Foo1.java\n")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo2" % work2_classes,
+# stdout = "work2/src/Foo2.java\n")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo3" % work2_classes,
+# stdout = "work2/src/Foo3.java\n")
+#
+#test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+test.pass_test()