OLD | NEW |
(Empty) | |
| 1 """SCons.Tool.javac |
| 2 |
| 3 Tool-specific initialization for javac. |
| 4 |
| 5 There normally shouldn't be any need to import this module directly. |
| 6 It will usually be imported through the generic SCons.Tool.Tool() |
| 7 selection method. |
| 8 |
| 9 """ |
| 10 |
| 11 # |
| 12 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The S
Cons Foundation |
| 13 # |
| 14 # Permission is hereby granted, free of charge, to any person obtaining |
| 15 # a copy of this software and associated documentation files (the |
| 16 # "Software"), to deal in the Software without restriction, including |
| 17 # without limitation the rights to use, copy, modify, merge, publish, |
| 18 # distribute, sublicense, and/or sell copies of the Software, and to |
| 19 # permit persons to whom the Software is furnished to do so, subject to |
| 20 # the following conditions: |
| 21 # |
| 22 # The above copyright notice and this permission notice shall be included |
| 23 # in all copies or substantial portions of the Software. |
| 24 # |
| 25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY |
| 26 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
| 27 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 28 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
| 29 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
| 30 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| 31 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 32 |
| 33 __revision__ = "src/engine/SCons/Tool/javac.py 5134 2010/08/16 23:02:40 bdeegan" |
| 34 |
| 35 import os |
| 36 import os.path |
| 37 |
| 38 import SCons.Action |
| 39 import SCons.Builder |
| 40 from SCons.Node.FS import _my_normcase |
| 41 from SCons.Tool.JavaCommon import parse_java_file |
| 42 import SCons.Util |
| 43 |
| 44 def classname(path): |
| 45 """Turn a string (path name) into a Java class name.""" |
| 46 return os.path.normpath(path).replace(os.sep, '.') |
| 47 |
| 48 def emit_java_classes(target, source, env): |
| 49 """Create and return lists of source java files |
| 50 and their corresponding target class files. |
| 51 """ |
| 52 java_suffix = env.get('JAVASUFFIX', '.java') |
| 53 class_suffix = env.get('JAVACLASSSUFFIX', '.class') |
| 54 |
| 55 target[0].must_be_same(SCons.Node.FS.Dir) |
| 56 classdir = target[0] |
| 57 |
| 58 s = source[0].rentry().disambiguate() |
| 59 if isinstance(s, SCons.Node.FS.File): |
| 60 sourcedir = s.dir.rdir() |
| 61 elif isinstance(s, SCons.Node.FS.Dir): |
| 62 sourcedir = s.rdir() |
| 63 else: |
| 64 raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'"
% s.__class__) |
| 65 |
| 66 slist = [] |
| 67 js = _my_normcase(java_suffix) |
| 68 for entry in source: |
| 69 entry = entry.rentry().disambiguate() |
| 70 if isinstance(entry, SCons.Node.FS.File): |
| 71 slist.append(entry) |
| 72 elif isinstance(entry, SCons.Node.FS.Dir): |
| 73 result = SCons.Util.OrderedDict() |
| 74 dirnode = entry.rdir() |
| 75 def find_java_files(arg, dirpath, filenames): |
| 76 java_files = sorted([n for n in filenames |
| 77 if _my_normcase(n).endswith(js)]) |
| 78 mydir = dirnode.Dir(dirpath) |
| 79 java_paths = [mydir.File(f) for f in java_files] |
| 80 for jp in java_paths: |
| 81 arg[jp] = True |
| 82 for dirpath, dirnames, filenames in os.walk(dirnode.get_abspath()): |
| 83 find_java_files(result, dirpath, filenames) |
| 84 entry.walk(find_java_files, result) |
| 85 |
| 86 slist.extend(list(result.keys())) |
| 87 else: |
| 88 raise SCons.Errors.UserError("Java source must be File or Dir, not '
%s'" % entry.__class__) |
| 89 |
| 90 version = env.get('JAVAVERSION', '1.4') |
| 91 full_tlist = [] |
| 92 for f in slist: |
| 93 tlist = [] |
| 94 source_file_based = True |
| 95 pkg_dir = None |
| 96 if not f.is_derived(): |
| 97 pkg_dir, classes = parse_java_file(f.rfile().get_abspath(), version) |
| 98 if classes: |
| 99 source_file_based = False |
| 100 if pkg_dir: |
| 101 d = target[0].Dir(pkg_dir) |
| 102 p = pkg_dir + os.sep |
| 103 else: |
| 104 d = target[0] |
| 105 p = '' |
| 106 for c in classes: |
| 107 t = d.File(c + class_suffix) |
| 108 t.attributes.java_classdir = classdir |
| 109 t.attributes.java_sourcedir = sourcedir |
| 110 t.attributes.java_classname = classname(p + c) |
| 111 tlist.append(t) |
| 112 |
| 113 if source_file_based: |
| 114 base = f.name[:-len(java_suffix)] |
| 115 if pkg_dir: |
| 116 t = target[0].Dir(pkg_dir).File(base + class_suffix) |
| 117 else: |
| 118 t = target[0].File(base + class_suffix) |
| 119 t.attributes.java_classdir = classdir |
| 120 t.attributes.java_sourcedir = f.dir |
| 121 t.attributes.java_classname = classname(base) |
| 122 tlist.append(t) |
| 123 |
| 124 for t in tlist: |
| 125 t.set_specific_source([f]) |
| 126 |
| 127 full_tlist.extend(tlist) |
| 128 |
| 129 return full_tlist, slist |
| 130 |
| 131 JavaAction = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') |
| 132 |
| 133 JavaBuilder = SCons.Builder.Builder(action = JavaAction, |
| 134 emitter = emit_java_classes, |
| 135 target_factory = SCons.Node.FS.Entry, |
| 136 source_factory = SCons.Node.FS.Entry) |
| 137 |
| 138 class pathopt(object): |
| 139 """ |
| 140 Callable object for generating javac-style path options from |
| 141 a construction variable (e.g. -classpath, -sourcepath). |
| 142 """ |
| 143 def __init__(self, opt, var, default=None): |
| 144 self.opt = opt |
| 145 self.var = var |
| 146 self.default = default |
| 147 |
| 148 def __call__(self, target, source, env, for_signature): |
| 149 path = env[self.var] |
| 150 if path and not SCons.Util.is_List(path): |
| 151 path = [path] |
| 152 if self.default: |
| 153 path = path + [ env[self.default] ] |
| 154 if path: |
| 155 return [self.opt, os.pathsep.join(path)] |
| 156 #return self.opt + " " + os.pathsep.join(path) |
| 157 else: |
| 158 return [] |
| 159 #return "" |
| 160 |
| 161 def Java(env, target, source, *args, **kw): |
| 162 """ |
| 163 A pseudo-Builder wrapper around the separate JavaClass{File,Dir} |
| 164 Builders. |
| 165 """ |
| 166 if not SCons.Util.is_List(target): |
| 167 target = [target] |
| 168 if not SCons.Util.is_List(source): |
| 169 source = [source] |
| 170 |
| 171 # Pad the target list with repetitions of the last element in the |
| 172 # list so we have a target for every source element. |
| 173 target = target + ([target[-1]] * (len(source) - len(target))) |
| 174 |
| 175 java_suffix = env.subst('$JAVASUFFIX') |
| 176 result = [] |
| 177 |
| 178 for t, s in zip(target, source): |
| 179 if isinstance(s, SCons.Node.FS.Base): |
| 180 if isinstance(s, SCons.Node.FS.File): |
| 181 b = env.JavaClassFile |
| 182 else: |
| 183 b = env.JavaClassDir |
| 184 else: |
| 185 if os.path.isfile(s): |
| 186 b = env.JavaClassFile |
| 187 elif os.path.isdir(s): |
| 188 b = env.JavaClassDir |
| 189 elif s[-len(java_suffix):] == java_suffix: |
| 190 b = env.JavaClassFile |
| 191 else: |
| 192 b = env.JavaClassDir |
| 193 result.extend(b(t, s, *args, **kw)) |
| 194 |
| 195 return result |
| 196 |
| 197 def generate(env): |
| 198 """Add Builders and construction variables for javac to an Environment.""" |
| 199 java_file = SCons.Tool.CreateJavaFileBuilder(env) |
| 200 java_class = SCons.Tool.CreateJavaClassFileBuilder(env) |
| 201 java_class_dir = SCons.Tool.CreateJavaClassDirBuilder(env) |
| 202 java_class.add_emitter(None, emit_java_classes) |
| 203 java_class.add_emitter(env.subst('$JAVASUFFIX'), emit_java_classes) |
| 204 java_class_dir.emitter = emit_java_classes |
| 205 |
| 206 env.AddMethod(Java) |
| 207 |
| 208 env['JAVAC'] = 'javac' |
| 209 env['JAVACFLAGS'] = SCons.Util.CLVar('') |
| 210 env['JAVABOOTCLASSPATH'] = [] |
| 211 env['JAVACLASSPATH'] = [] |
| 212 env['JAVASOURCEPATH'] = [] |
| 213 env['_javapathopt'] = pathopt |
| 214 env['_JAVABOOTCLASSPATH'] = '${_javapathopt("-bootclasspath", "JAVABOO
TCLASSPATH")} ' |
| 215 env['_JAVACLASSPATH'] = '${_javapathopt("-classpath", "JAVACLASSPA
TH")} ' |
| 216 env['_JAVASOURCEPATH'] = '${_javapathopt("-sourcepath", "JAVASOURCE
PATH", "_JAVASOURCEPATHDEFAULT")} ' |
| 217 env['_JAVASOURCEPATHDEFAULT'] = '${TARGET.attributes.java_sourcedir}' |
| 218 env['_JAVACCOM'] = '$JAVAC $JAVACFLAGS $_JAVABOOTCLASSPATH $_
JAVACLASSPATH -d ${TARGET.attributes.java_classdir} $_JAVASOURCEPATH $SOURCES' |
| 219 env['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM')}" |
| 220 env['JAVACLASSSUFFIX'] = '.class' |
| 221 env['JAVASUFFIX'] = '.java' |
| 222 |
| 223 def exists(env): |
| 224 return 1 |
| 225 |
| 226 # Local Variables: |
| 227 # tab-width:4 |
| 228 # indent-tabs-mode:nil |
| 229 # End: |
| 230 # vim: set expandtab tabstop=4 shiftwidth=4: |
OLD | NEW |