#!/usr/bin/env python

## Copyright (C) 2006, 2011 Free Software Foundation
## Written by Gary Benson <gbenson@redhat.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.

import sys
sys.path.insert(0, "@python_mod_dir_expanded@")
import aotcompile
import getopt
import os

usage = """\
Usage: %s [OPTION...] SRCDIR DSTDIR
AOT-compile all Java bytecode in SRCDIR into DSTDIR.

Options:
  -M, --make=PATH        make executable to use (%s)
  -C, --gcj=PATH         gcj executable to use (%s)
  -D, --dbtool=PATH      gcj-dbtool executable to use (%s)
  -m, --makeflags=FLAGS  flags to pass to make during build
  -c, --gcjflags=FLAGS   flags to pass to gcj during compilation
                           in addition to %s
  -l, --ldflags=FLAGS    flags to pass to gcj during linking
                           in addition to %s
  -e, --exclude=PATH     do not compile PATH

Extra flags may also be passed using the AOT_MAKEFLAGS, AOT_GCJFLAGS
and AOT_LDFLAGS environment variables.""" % (
    os.path.basename(sys.argv[0]),
    aotcompile.PATHS["make"],
    aotcompile.PATHS["gcj"],
    aotcompile.PATHS["dbtool"],
    repr(" ".join(aotcompile.GCJFLAGS)),
    repr(" ".join(aotcompile.LDFLAGS)))

try:
    if os.environ.has_key("RPM_PACKAGE_NAME"):
        raise aotcompile.Error, "not for use within rpm specfiles"

    try:
        opts, args = getopt.getopt(
            sys.argv[1:],
            "M:C:D:m:c:l:e:",
            ["make=", "gcj=", "dbtool=",
             "makeflags=", "gcjflags=", "ldflags=",
             "exclude="])
        srcdir, dstdir = args
    except:
        print >>sys.stderr, usage
        sys.exit(1)

    compiler = aotcompile.Compiler(srcdir, dstdir)
    for o, a in opts:
        if o in ("-M", "--make"):
            aotcompile.PATHS["make"] = a
        if o in ("-C", "--gcj"):
            aotcompile.PATHS["gcj"] = a
        if o in ("-D", "--dbtool"):
            aotcompile.PATHS["dbtool"] = a
        if o in ("-m", "--makeflags"):
            compiler.makeflags[0:0] = a.split()
        if o in ("-c", "--gcjflags"):
            compiler.gcjflags[0:0] = a.split()
        if o in ("-l", "--ldflags"):
            compiler.ldflags[0:0] = a.split()
        if o in ("-e", "--exclude"):
            compiler.exclusions.append(a)
    
    compiler.makeflags[0:0] = os.environ.get("AOT_MAKEFLAGS", "").split() 
    compiler.gcjflags[0:0] = os.environ.get("AOT_GCJFLAGS", "").split() 
    compiler.ldflags[0:0] = os.environ.get("AOT_LDFLAGS", "").split() 

    compiler.compile()

except aotcompile.Error, e:
    print >>sys.stderr, "%s: error: %s" % (
        os.path.basename(sys.argv[0]), e)
    sys.exit(1)
