# Copyright (c) Corporation for National Research Initiatives """Usage: jpythonc [options] [module]* where options include: --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 JPython libraries (implies --deep) --all -a Include all of the JPython 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.jpythonc.compiler in the registry. --compileropts options -J options Options passed directly to the Java compiler. Alternatively, you can set the property python.jpythonc.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 = '' 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, 'p:j:dcab:A:w:s:C:f:J:h', ['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(',') # 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)) def addAll(extraPackages): for name in ('core', '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) print opts.args 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) writeResults(comp, opts)