diff options
Diffstat (limited to 'src/engine/SCons/Tool/jar.py')
| -rw-r--r-- | src/engine/SCons/Tool/jar.py | 137 | 
1 files changed, 131 insertions, 6 deletions
diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py index a56dd70..98be08f 100644 --- a/src/engine/SCons/Tool/jar.py +++ b/src/engine/SCons/Tool/jar.py @@ -9,7 +9,7 @@ selection method.  """  # -# Copyright (c) 2001 - 2017 The SCons Foundation +# Copyright (c) 2001 - 2019 The SCons Foundation  #  # Permission is hereby granted, free of charge, to any person obtaining  # a copy of this software and associated documentation files (the @@ -31,10 +31,14 @@ selection method.  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  # -__revision__ = "src/engine/SCons/Tool/jar.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" +__revision__ = "src/engine/SCons/Tool/jar.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan" +import os  import SCons.Subst  import SCons.Util +from SCons.Node.FS import _my_normcase +from SCons.Tool.JavaCommon import get_java_install_dirs +  def jarSources(target, source, env, for_signature):      """Only include sources that are not a manifest file.""" @@ -50,7 +54,7 @@ def jarSources(target, source, env, for_signature):      result = []      for src in source:          contents = src.get_text_contents() -        if contents[:16] != "Manifest-Version": +        if not contents.startswith("Manifest-Version"):              if jarchdir_set:                  _chdir = jarchdir              else: @@ -71,7 +75,7 @@ def jarManifest(target, source, env, for_signature):      """Look in sources for a manifest file, if any."""      for src in source:          contents = src.get_text_contents() -        if contents[:16] == "Manifest-Version": +        if contents.startswith("Manifest-Version"):              return src      return '' @@ -81,16 +85,137 @@ def jarFlags(target, source, env, for_signature):      jarflags = env.subst('$JARFLAGS', target=target, source=source)      for src in source:          contents = src.get_text_contents() -        if contents[:16] == "Manifest-Version": -            if not 'm' in jarflags: +        if contents.startswith("Manifest-Version"): +            if 'm' not in jarflags:                  return jarflags + 'm'              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) and source == []: +        SCons.Warnings.Warning("Making implicit target jar file, " + +                              "and treating the list as sources") +        source = target +        target = None + +    # mutiple targets pass so build each target the same from the +    # same source +    #TODO Maybe this should only be done once, and the result copied +    #     for each target since it should result in the same? +    if SCons.Util.is_List(target) and SCons.Util.is_List(source): +        jars = [] +        for single_target in target: +            jars += env.Jar( target = single_target, source = source, *args, **kw) +        return jars + +    # they passed no target so make a target implicitly +    if target is 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.Warnings.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] + +    # setup for checking through all the sources and handle accordingly +    java_class_suffix = env.subst('$JAVACLASSSUFFIX') +    java_suffix = env.subst('$JAVASUFFIX') +    target_nodes = [] + +    # 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 _my_normcase(str(s)).endswith(java_suffix): +            return env.JavaClassFile(source = s, *args, **kw) +        else: +            return [env.fs.File(s)] + +    # function for calling the JavaClassDir builder if a directory is +    # passed as a source to Jar builder. The JavaClassDir builder will +    # return an empty list if there were not target classes built from +    # the directory, in this case assume the user wanted the directory +    # copied into the jar as is (it contains other files such as +    # resources or class files compiled from proir commands) +    # TODO: investigate the expexcted behavior for directories that +    #       have mixed content, such as Java files along side other files +    #       files. +    def dir_to_class(s): +        dir_targets = env.JavaClassDir(source = s, *args, **kw) +        if(dir_targets == []): +            # no classes files could be built from the source dir +            # so pass the dir as is. +            return [env.fs.Dir(s)] +        else: +            return dir_targets + +    # 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 SCons.Util.flatten(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_nodes.extend(file_to_class(s)) +            else: +                # found a dir so get the class files out of it +                target_nodes.extend(dir_to_class(s)) +        else: +            try: +                # source is string try to convert it to file +                target_nodes.extend(file_to_class(env.fs.File(s))) +                continue +            except: +                pass + +            try: +                # source is string try to covnert it to dir +                target_nodes.extend(dir_to_class(env.fs.Dir(s))) +                continue +            except: +                pass + +            SCons.Warnings.Warning("File: " + str(s) + " could not be identified as File or Directory, skipping.") + +    # 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_nodes, *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) + +    if env['PLATFORM'] == 'win32': +        # Ensure that we have a proper path for jar +        paths = get_java_install_dirs('win32') +        jar = SCons.Tool.find_program_path(env, 'jar', default_paths=paths) +        if jar: +            jar_bin_dir = os.path.dirname(jar) +            env.AppendENVPath('PATH', jar_bin_dir) +      env['JAR']        = 'jar'      env['JARFLAGS']   = SCons.Util.CLVar('cf')      env['_JARFLAGS']  = jarFlags  | 
