1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
|
# Copyright (c) Corporation for National Research Initiatives
"""Usage: jythonc [options] [module]*
where options include:
--ignore-warning
-i
silence the jythonc deprecation warning
--package package
-p package
put all compiled code into the named Java package
--jar jarfile
-j jarfile
Compile into jarfile (implies --deep)
--deep
-d
Compile all Python dependencies of the module
--core
-c
Include the core Jython libraries (implies --deep)
--all
-a
Include all of the Jython libraries (implies --deep)
--bean jarfile
-b jarfile
Compile into jarfile, include manifest for bean
--addpackages packages
-A packages
Include Java dependencies from this list of packages. Default is
org.python.modules and org.apache.oro.text.regex
--workdir directory
-w directory
Specify working directory for compiler (default is ./jpywork)
--skip modules
-s modules
Don't include any of these modules in compilation
--compiler path
-C path
Use a different compiler than `standard' javac. If this is set to
`NONE' then compile ends with .java. Alternatively, you can set the
property python.jythonc.compiler in the registry.
--compileropts options
-J options
Options passed directly to the Java compiler. Alternatively, you can
set the property python.jythonc.compileropts in the registry.
--falsenames names
-f names
A comma-separated list of names that are always false. Can be used to
short-circuit if clauses.
--help
-h
Print this message and exit
"""
import sys
import os
import getopt
from types import TupleType
from compile import Compiler
# Standard usage message printing
def usage(errcode, msg=''):
print __doc__ % globals()
if msg:
print msg
sys.exit(errcode)
def getOptions():
class Opts:
jar = None
workdir = 'jpywork'
core = 0
all = 0
deep = 0
bean = None
skip = ''
package = None
addfiles = ''
falsenames = []
compiler = None
jopts = None
addpackages = ''
ignorewarning = 0
options = Opts()
oldopts = ['-jar', '-workdir', '-core', '-all', '-deep',
'-bean', '-skip', '-package', '-addfiles', '-falsenames',
'-compiler', '-addpackages']
# For backwards compatibility, long options used to take only a single
# dash. Convert them to GNU style (e.g. as supported by getopt)
sysargs = []
for arg in sys.argv[1:]:
if arg in oldopts:
newarg = '-'+arg
print 'Warning:', arg, 'is deprecated, use', newarg
sysargs.append(newarg)
else:
sysargs.append(arg)
try:
opts, args = getopt.getopt(
sysargs, 'ip:j:dcab:A:w:s:C:f:J:h',
['ignore-warning', 'package=', 'jar=', 'deep', 'core', 'all', 'bean=',
'addpackages=', 'workdir=', 'skip=', 'compiler=',
'falsenames=', 'compileropts=', 'help'])
except getopt.error, msg:
usage(1, msg)
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt in ('-p', '--package'):
options.package = arg
elif opt in ('-j', '--jar'):
options.jar = arg
options.deep = 1
elif opt in ('-d', '--deep'):
options.deep = 1
elif opt in ('-c', '--core'):
options.core = 1
options.deep = 1
elif opt in ('-a', '--all'):
options.all = 1
options.deep = 1
elif opt in ('-b', '--bean'):
options.bean = arg
elif opt in ('-A', '--addpackages'):
options.addpackages = arg
elif opt in ('-w', '--workdir'):
options.workdir = arg
elif opt in ('-s', '--skip'):
options.skip = arg
elif opt in ('-C', '--compiler'):
options.compiler = arg
elif opt in ('-J', '--compileropts'):
options.jopts = arg.split()
elif opt in ('-f', '--falsenames'):
options.falsenames = arg.split(',')
elif opt in ('-i', '--ignore-warning'):
options.ignorewarning = 1
if not options.ignorewarning:
print '''Warning: jythonc is unmaintained and will not be included in Jython-2.3. See http://jython.org/Project/jythonc.html for alternatives to jythonc. Add '-i' to your invocation of jythonc to turn off this warning'''
# there should be at least one module to compile
if not args:
usage(0, 'nothing to compile')
# post processing
options.args = args
if not os.path.isabs(options.workdir):
options.workdir = os.path.join(os.curdir, options.workdir)
return options
def addCore(extraPackages):
skiplist = [ 'org.python.core.parser',
#'org.python.core.BytecodeLoader',
]
extraPackages.append(('org.python.core', skiplist))
extraPackages.append(('org.python.core.adapter', []))
def addAll(extraPackages):
for name in ('core', 'core.adapter', 'compiler', 'parser'):
extraPackages.append(('org.python.'+name, []))
mainclass = basepath = None
def doCompile(opts):
global mainclass
global basepath
skiplist = opts.skip.split(',')
optpkgs = opts.addpackages.split(',')
addpackages = ['org.python.modules',
'org.apache.oro.text.regex',
] + optpkgs
comp = Compiler(javapackage=opts.package,
deep=opts.deep,
include=addpackages,
skip=skiplist,
options=opts)
for target in opts.args:
if target.endswith('.py'):
classname = os.path.splitext(os.path.basename(target))[0]
filename = target
if basepath is None:
basepath = os.path.split(target)[0]
sys.path.insert(0, basepath)
else:
classname = target
import ImportName
m = ImportName.lookupName(classname)
if not m:
print 'Could not find class:', classname
sys.exit(1)
filename = m.file
if mainclass is None:
mainclass = classname
if opts.package is not None:
mainclass = opts.package+'.'+mainclass
comp.compilefile(filename, classname)
comp.dump(opts.workdir)
return comp
def copyclass(jc, fromdir, todir):
import jar
from java.io import FileInputStream, FileOutputStream
name = apply(os.path.join, jc.split('.'))+'.class'
fromname = os.path.join(fromdir, name)
toname = os.path.join(todir, name)
tohead = os.path.split(toname)[0]
if not os.path.exists(tohead):
os.makedirs(tohead)
istream = FileInputStream(fromname)
ostream = FileOutputStream(toname)
jar.copy(istream, ostream)
istream.close()
ostream.close()
def writeResults(comp, opts):
global mainclass
global basepath
javaclasses = comp.javaclasses
if opts.bean is not None:
jarfile = opts.bean
else:
jarfile = opts.jar
if jarfile is None:
if not opts.deep and opts.package is not None:
for jc in javaclasses:
if isinstance(jc, TupleType):
jc = jc[0]
if basepath is None:
basepath = '.'
copyclass(jc, opts.workdir, basepath)
sys.exit(0)
print 'Building archive:', jarfile
from jar import JavaArchive
extraPackages = []
if opts.all:
addAll(extraPackages)
elif opts.core:
addCore(extraPackages)
ja = JavaArchive(extraPackages)
ja.addToManifest({'Main-Class': mainclass})
for jc in javaclasses:
if isinstance(jc, TupleType):
ja.addClass(opts.workdir, jc[0], jc[1])
else:
ja.addClass(opts.workdir, jc)
for dep in comp.trackJavaDependencies():
ja.addEntry(dep)
if opts.core or opts.all:
import depend
ja.addEntry(depend.getFile('org.python.modules.Setup'))
# ze, jcs = depend.depends('org.python.modules.exceptions')
# ja.addEntry(ze)
# for jc in jcs:
# ja.addEntry(depend.getFile(jc))
ja.dump(jarfile)
def main():
opts = getOptions()
comp = doCompile(opts)
if opts.compiler != "NONE":
writeResults(comp, opts)
|