third_party: Update waf to version 2.0.17
[samba.git] / third_party / waf / waflib / Tools / javaw.py
index f6fd20cc689c85996be5015ea441620cd9afc9d0..fd1cf469abf6ccec15e2b1b45d0d2c8b218078bb 100644 (file)
@@ -24,12 +24,95 @@ You would have to run::
    java -jar /path/to/jython.jar waf configure
 
 [1] http://www.jython.org/
+
+Usage
+=====
+
+Load the "java" tool.
+
+def configure(conf):
+       conf.load('java')
+
+Java tools will be autodetected and eventually, if present, the quite
+standard JAVA_HOME environment variable will be used. The also standard
+CLASSPATH variable is used for library searching.
+
+In configuration phase checks can be done on the system environment, for
+example to check if a class is known in the classpath::
+
+       conf.check_java_class('java.io.FileOutputStream')
+
+or if the system supports JNI applications building::
+
+       conf.check_jni_headers()
+
+
+The java tool supports compiling java code, creating jar files and
+creating javadoc documentation. This can be either done separately or
+together in a single definition. For example to manage them separately::
+
+       bld(features  = 'javac',
+               srcdir    = 'src',
+               compat    = '1.7',
+               use       = 'animals',
+               name      = 'cats-src',
+       )
+
+       bld(features  = 'jar',
+               basedir   = '.',
+               destfile  = '../cats.jar',
+               name      = 'cats',
+               use       = 'cats-src'
+       )
+
+
+Or together by defining all the needed attributes::
+
+       bld(features   = 'javac jar javadoc',
+               srcdir     = 'src/',  # folder containing the sources to compile
+               outdir     = 'src',   # folder where to output the classes (in the build directory)
+               compat     = '1.6',   # java compatibility version number
+               classpath  = ['.', '..'],
+
+               # jar
+               basedir    = 'src', # folder containing the classes and other files to package (must match outdir)
+               destfile   = 'foo.jar', # do not put the destfile in the folder of the java classes!
+               use        = 'NNN',
+               jaropts    = ['-C', 'default/src/', '.'], # can be used to give files
+               manifest   = 'src/Manifest.mf', # Manifest file to include
+
+               # javadoc
+               javadoc_package = ['com.meow' , 'com.meow.truc.bar', 'com.meow.truc.foo'],
+               javadoc_output  = 'javadoc',
+       )
+
+External jar dependencies can be mapped to a standard waf "use" dependency by
+setting an environment variable with a CLASSPATH prefix in the configuration,
+for example::
+
+       conf.env.CLASSPATH_NNN = ['aaaa.jar', 'bbbb.jar']
+
+and then NNN can be freely used in rules as::
+
+       use        = 'NNN',
+
+In the java tool the dependencies via use are not transitive by default, as
+this necessity depends on the code. To enable recursive dependency scanning
+use on a specific rule:
+
+               recurse_use = True
+
+Or build-wise by setting RECURSE_JAVA:
+
+               bld.env.RECURSE_JAVA = True
+
+Unit tests can be integrated in the waf unit test environment using the javatest extra.
 """
 
 import os, shutil
 from waflib import Task, Utils, Errors, Node
 from waflib.Configure import conf
-from waflib.TaskGen import feature, before_method, after_method
+from waflib.TaskGen import feature, before_method, after_method, taskgen_method
 
 from waflib.Tools import ccroot
 ccroot.USELIB_VARS['javac'] = set(['CLASSPATH', 'JAVACFLAGS'])
@@ -107,6 +190,37 @@ def apply_java(self):
        if names:
                tsk.env.append_value('JAVACFLAGS', ['-sourcepath', names])
 
+
+@taskgen_method
+def java_use_rec(self, name, **kw):
+       """
+       Processes recursively the *use* attribute for each referred java compilation
+       """
+       if name in self.tmp_use_seen:
+               return
+
+       self.tmp_use_seen.append(name)
+
+       try:
+               y = self.bld.get_tgen_by_name(name)
+       except Errors.WafError:
+               self.uselib.append(name)
+               return
+       else:
+               y.post()
+               # Add generated JAR name for CLASSPATH. Task ordering (set_run_after)
+               # is already guaranteed by ordering done between the single tasks
+               if hasattr(y, 'jar_task'):
+                       self.use_lst.append(y.jar_task.outputs[0].abspath())
+               else:
+                       if hasattr(y,'outdir'):
+                               self.use_lst.append(y.outdir.abspath())
+                       else:
+                               self.use_lst.append(y.path.get_bld().abspath())
+
+       for x in self.to_list(getattr(y, 'use', [])):
+               self.java_use_rec(x)
+
 @feature('javac')
 @before_method('propagate_uselib_vars')
 @after_method('apply_java')
@@ -114,24 +228,39 @@ def use_javac_files(self):
        """
        Processes the *use* attribute referring to other java compilations
        """
-       lst = []
+       self.use_lst = []
+       self.tmp_use_seen = []
        self.uselib = self.to_list(getattr(self, 'uselib', []))
        names = self.to_list(getattr(self, 'use', []))
        get = self.bld.get_tgen_by_name
        for x in names:
                try:
-                       y = get(x)
+                       tg = get(x)
                except Errors.WafError:
                        self.uselib.append(x)
                else:
-                       y.post()
-                       if hasattr(y, 'jar_task'):
-                               lst.append(y.jar_task.outputs[0].abspath())
-                               self.javac_task.set_run_after(y.jar_task)
+                       tg.post()
+                       if hasattr(tg, 'jar_task'):
+                               self.use_lst.append(tg.jar_task.outputs[0].abspath())
+                               self.javac_task.set_run_after(tg.jar_task)
+                               self.javac_task.dep_nodes.extend(tg.jar_task.outputs)
                        else:
-                               for tsk in y.tasks:
+                               if hasattr(tg, 'outdir'):
+                                       base_node = tg.outdir.abspath()
+                               else:
+                                       base_node = tg.path.get_bld()
+
+                               self.use_lst.append(base_node.abspath())
+                               self.javac_task.dep_nodes.extend([x for x in base_node.ant_glob(JAR_RE, remove=False, quiet=True)])
+
+                               for tsk in tg.tasks:
                                        self.javac_task.set_run_after(tsk)
-       self.env.append_value('CLASSPATH', lst)
+
+               # If recurse use scan is enabled recursively add use attribute for each used one
+               if getattr(self, 'recurse_use', False) or self.bld.env.RECURSE_JAVA:
+                       self.java_use_rec(x)
+
+       self.env.append_value('CLASSPATH', self.use_lst)
 
 @feature('javac')
 @after_method('apply_java', 'propagate_uselib_vars', 'use_javac_files')
@@ -245,7 +374,7 @@ class jar_create(JTask):
                                return Task.ASK_LATER
                if not self.inputs:
                        try:
-                               self.inputs = [x for x in self.basedir.ant_glob(JAR_RE, remove=False) if id(x) != id(self.outputs[0])]
+                               self.inputs = [x for x in self.basedir.ant_glob(JAR_RE, remove=False, quiet=True) if id(x) != id(self.outputs[0])]
                        except Exception:
                                raise Errors.WafError('Could not find the basedir %r for %r' % (self.basedir, self))
                return super(jar_create, self).runnable_status()
@@ -279,14 +408,14 @@ class javac(JTask):
                        self.inputs  = []
                        for x in self.srcdir:
                                if x.exists():
-                                       self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False))
+                                       self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False, quiet=True))
                return super(javac, self).runnable_status()
 
        def post_run(self):
                """
                List class files created
                """
-               for node in self.generator.outdir.ant_glob('**/*.class'):
+               for node in self.generator.outdir.ant_glob('**/*.class', quiet=True):
                        self.generator.bld.node_sigs[node] = self.uid()
                self.generator.bld.task_sigs[self.uid()] = self.cache_sig
 
@@ -338,7 +467,7 @@ class javadoc(Task.Task):
                self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0)
 
        def post_run(self):
-               nodes = self.generator.javadoc_output.ant_glob('**')
+               nodes = self.generator.javadoc_output.ant_glob('**', quiet=True)
                for node in nodes:
                        self.generator.bld.node_sigs[node] = self.uid()
                self.generator.bld.task_sigs[self.uid()] = self.cache_sig
@@ -356,7 +485,7 @@ def configure(self):
                self.env.JAVA_HOME = [self.environ['JAVA_HOME']]
 
        for x in 'javac java jar javadoc'.split():
-               self.find_program(x, var=x.upper(), path_list=java_path)
+               self.find_program(x, var=x.upper(), path_list=java_path, mandatory=(x not in ('javadoc')))
 
        if 'CLASSPATH' in self.environ:
                v.CLASSPATH = self.environ['CLASSPATH']