summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Moody <dmoody256@gmail.com>2017-10-25 22:10:20 -0400
committerDaniel Moody <dmoody256@gmail.com>2017-10-25 22:10:20 -0400
commitb54f4166d0053ae7168af1d16223fff574344f17 (patch)
tree540209939b10707541732eefd2f0e9aadb236b31
parenta583f043aec89e58bf4ab0ab20cc039299eff1df (diff)
downloadscons-git-b54f4166d0053ae7168af1d16223fff574344f17.tar.gz
added a method to the jar tool to handle directories and file sources. This was taken from the similar Java method in the javac tool. Updated the Jar builder to have an unambiguos name.
-rw-r--r--src/engine/SCons/Tool/__init__.py14
-rw-r--r--src/engine/SCons/Tool/jar.py107
2 files changed, 119 insertions, 2 deletions
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index a4e44a0f1..42f84e118 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -913,15 +913,25 @@ def createCFileBuilders(env):
# Create common Java builders
def CreateJarBuilder(env):
+ """The Jar builder expects a list of class files
+ which it can package into a jar file.
+
+ The jar tool provides an interface for passing other types
+ of java files such as .java, directories or swig interfaces
+ and will build them to class files in which it can package
+ into the jar.
+ """
try:
- java_jar = env['BUILDERS']['Jar']
+ java_jar = env['BUILDERS']['JarFile']
except KeyError:
fs = SCons.Node.FS.get_default_fs()
jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR')
java_jar = SCons.Builder.Builder(action = jar_com,
suffix = '$JARSUFFIX',
+ src_suffix = '$JAVACLASSSUFFIX',
+ src_builder = 'JavaClassFile',
source_factory = fs.Entry)
- env['BUILDERS']['Jar'] = java_jar
+ env['BUILDERS']['JarFile'] = java_jar
return java_jar
def CreateJavaHBuilder(env):
diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py
index 830892702..62cd86a26 100644
--- a/src/engine/SCons/Tool/jar.py
+++ b/src/engine/SCons/Tool/jar.py
@@ -35,6 +35,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Subst
import SCons.Util
+from SCons.Node.FS import _my_normcase
+import os
def jarSources(target, source, env, for_signature):
"""Only include sources that are not a manifest file."""
@@ -87,10 +89,115 @@ def jarFlags(target, source, env, for_signature):
break
return jarflags
+def Jar(env, target = None, source = [], *args, **kw):
+ """
+ A pseudo-Builder wrapper around the separate Jar sources{File,Dir}
+ Builders.
+ """
+
+ # jar target should not be a list so assume they passed
+ # no target and want implicit target to be made and the arg
+ # was actaully the list of sources
+ if SCons.Util.is_List(target):
+ source = target
+ target = None
+
+ # they passed no target so make a target implicitly
+ if target == None:
+ try:
+ # make target from the first source file
+ target = os.path.splitext(str(source[0]))[0] + env.subst('$JARSUFFIX')
+ except:
+ # something strange is happening but attempt anyways
+ SCons.Warning.Warning("Could not make implicit target from sources, using directory")
+ target = os.path.basename(str(env.Dir('.'))) + env.subst('$JARSUFFIX')
+
+ # make lists out of our target and sources
+ if not SCons.Util.is_List(target):
+ target = [target]
+ if not SCons.Util.is_List(source):
+ source = [source]
+
+ # Pad the target list with repetitions of the last element in the
+ # list so we have a target for every source element.
+ target = target + ([target[-1]] * (len(source) - len(target)))
+
+ # setup for checking through all the sources and handle accordingly
+ java_class_suffix = env.subst('$JAVACLASSSUFFIX')
+ java_suffix = env.subst('$JAVASUFFIX')
+ target_classes = []
+
+ # function for determining what to do with a file and not a directory
+ # if its already a class file then it can be used as a
+ # source for jar, otherwise turn it into a class file then
+ # return the source
+ def file_to_class(s):
+ if(str(_my_normcase(s)).endswith(java_suffix)):
+ return env.JavaClassFile(source = s, *args, **kw)
+ else:
+ return [env.fs.File(s)]
+
+ # In the case that we are passed just string to a node which is directory
+ # but does not exist, we need to check all the current targets to see if
+ # that directory is going to exist so we can add it as a source to Jar builder
+ def get_all_targets(env, node='.'):
+ def get_all_targets_iter(env, node):
+ if node.has_builder():
+ yield node
+ for kid in node.all_children():
+ for kid in get_all_targets(env, kid):
+ yield kid
+ node = env.arg2nodes(node, env.fs.Entry)[0]
+ return list(get_all_targets_iter(env, node))
+
+ # loop through the sources and handle each accordingly
+ # the goal here is to get all the source files into a class
+ # file or a directory that contains class files
+ for s in source:
+ s = env.subst(s)
+ if isinstance(s, SCons.Node.FS.Base):
+ if isinstance(s, SCons.Node.FS.File):
+ # found a file so make sure its a class file
+ target_classes.extend(file_to_class(s))
+ else:
+ # found a dir so make sure its a dir of class files
+ target_classes.extend(env.JavaClassDir(source = env.fs.Dir(s), *args, **kw))
+ else:
+ if os.path.isfile(s):
+ # found a file that exists on the FS, make sure its a class file
+ target_classes.extend(file_to_class(s))
+ elif os.path.isdir(s):
+ # found a dir on the FS, add it as a dir of class files
+ target_classes.append(env.fs.Dir(s))
+ elif s[-len(java_suffix):] == java_suffix or s[-len(java_class_suffix):] == java_class_suffix:
+ # found a file that may not exists and is only a string
+ # so add it after converting it to a class file
+ target_classes.extend(file_to_class(s))
+ else:
+ # found a swig file so add it after converting it to class files
+ if(os.path.splitext(str(s))[1] == ".i"):
+ target_classes.extend(env.JavaClassFile(source = s, *args, **kw))
+ else:
+ # found a directory that does not yet exist, but can exist as a node
+ # check the target nodes to make sure it will be built, then add
+ # it as a source
+ for node in get_all_targets(env):
+ if(s in str(node) and os.path.splitext(str(node))[1] == ""):
+ target_classes.append(node)
+ # at this point all our sources have been converted to classes or directories of class
+ # so pass it to the Jar builder
+ return env.JarFile(target = target, source = target_classes, *args, **kw)
+
def generate(env):
"""Add Builders and construction variables for jar to an Environment."""
SCons.Tool.CreateJarBuilder(env)
+ SCons.Tool.CreateJavaFileBuilder(env)
+ SCons.Tool.CreateJavaClassFileBuilder(env)
+ SCons.Tool.CreateJavaClassDirBuilder(env)
+
+ env.AddMethod(Jar)
+
env['JAR'] = 'jar'
env['JARFLAGS'] = SCons.Util.CLVar('cf')
env['_JARFLAGS'] = jarFlags