# This script generates the PyKDE configuration and generates the Makefiles.
#
# Copyright (c) 2004
#   Riverbank Computing Limited <info@riverbankcomputing.co.uk>
#   Jim Bublitz <jbublitz@nwinternet.com>
#
# This file is part of PyKDE.
#
# This copy of PyKDE 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, or (at your option) any later
# version.
#
# PyKDE is supplied 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.
#
# You should have received a copy of the GNU General Public License along with
# PyKDE; see the file LICENSE.  If not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.


import sys
import os
import string
import glob
import getopt
import shutil
import py_compile

try:
    from sip4_tqt import sipconfig
except:
    print ("Can't find sipconfig.py (expected in sys.path)")
    print ("Have you built the correct version of sip?")
    sys.exit (-1)

try:
    from python_tqt import pyqtconfig
except:
    sipconfig.error ("Can't find pyqtconfig.py in sys.path - exiting")

topsrcdir = os.path.dirname(os.path.abspath(__file__))
has_objdir = topsrcdir != os.path.abspath(os.path.curdir)
if not has_objdir:
    topsrcdir = None
    
def srcPath(filename):
    if topsrcdir is not None:
        return os.path.join(topsrcdir, filename)
    return filename

topsrcdir = os.path.dirname(os.path.abspath(__file__))
has_objdir = topsrcdir != os.path.abspath(os.path.curdir)
if not has_objdir:
    topsrcdir = None
    
def srcPath(filename):
    if topsrcdir is not None:
        return os.path.join(topsrcdir, filename)
    return filename

# Get the SIP configuration.
sipcfg            = sipconfig.Configuration()
pyqtcfg           = pyqtconfig.Configuration ()

# Initialise the globals.
pytde_version      = 0x031006
pytde_version_str  = "3.16.6"
kde_version        = None
kde_version_str    = None
kde_version_sfx    = None
kde_version_extra  = None
kde_max_version    = 0x030503

sip_min_v4_version = 0x040900
qt_min_version     = 0x030200
pyqt_min_version   = 0x031000

kde_sip_flags = []

# Command line options.
opt_pytdemoddir   = sipcfg.default_mod_dir
opt_pytdesipdir   = sipcfg.default_sip_dir
opt_debug         = 0
opt_concat        = None
opt_split         = 1
opt_releasegil    = 0
opt_tracing       = 0
opt_static        = 0
opt_tdebasedir    = None
opt_kdelibdir     = None
opt_kdeincdir     = None
opt_dep_warnings  = 0
opt_libdir        = "lib"
opt_dist_name     = ""

pytde_modules     = ["dcop", "tdecore", "tdefx", "tdeui", "tdeio", "tderesources", "tdeabc", "tdeutils", "tdefile", "tdeparts",\
                     "tdehtml", "tdespell", "tdeprint", "tdemdi"] #, "tdespell2"]

pytde_imports     = {
                    "dcop":       ["qt"],
                    "tdecore":    ["qt", "dcop"],
#                    "tdesu":      ["qt", "dcop", "tdecore"],
                    "tdefx":      ["qt", "dcop", "tdecore"],
                    "tdeui":      ["qt", "qtxml", "dcop", "tdecore", "tdefx"],
                    "tdeio":        ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui"],
                    "tderesources": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeio"],
                    "tdeabc":       ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeio", "tderesources"],
                    "tdeutils":     ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeio"],
                    "tdefile":      ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeio"],
                    "tdeparts":     ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeio"],
                    "tdehtml":      ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeutils", "tdeio", "tdeparts"],
                    "tdespell":     ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeio", "tdefile"],
                    "tdeprint":   ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui"],
                    "tdemdi":       ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "tdeio", "tdeparts"],
                    "tdespell2":    ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui"]
                    }

kde_includes      = {
                    "dcop":       None,
                    "tdecore":    None,
#                    "tdesu":      ["tdesu"],
                    "tdefx":      None,
                    "tdeui":      None,
                    "tdeio":        ["tdeio"],
                    "tderesources": ["tdeio", "../tdeio", "tderesources"],
                    "tdeabc":       ["tdeio", "../tdeio", "tderesources", "tdeabc"],
                    "tdefile":      ["tdeio", "../tdeio"],
                    "tdeparts":     ["tdeio", "../tdeio", "tdeparts"],
                    "tdehtml":      ["tdeio", "../tdeio", "tdeparts", "dom"],
                    "tdespell":     ["tdeio"],
                    "tdeprint":   ["tdeprint"],
                    "tdemdi":       ["tdemdi", "tdeio", "../tdeio", "tdeparts"],
                    "tdeutils":     ["tdeio", "../tdeio"] #,
#                    "tdespell2":    None
                    }

postProcess       = {
                    "dcop":       None,
                    "tdecore":    [["-p ", "tdecore", "-o", "appQuit",  "tdecore.py"],
                                   #["-p ", "tdecore", "-o", "fixTQVariant",  "tdecore.sbf"],
                                   ["-p ", "tdecore", "-o", "fixSignal",  "tdecorepart0.*"]],
#                    "tdesu":      None,
                    "tdefx":      None,
                    "tdeui":      None, #[["-p ", "tdeui", "-o", "shpix",  "siptdeuiTDESharedPixmap.cpp"]],
                    "tderesources": None,
                    "tdeabc":       None,
                    "tdeio":        None,
                    "tdefile":      None,
                    "tdeparts":     None,
                    "tdehtml":      None,
                    "tdespell":     None,
                    "tdeprint":   None,
                    "tdemdi":       None,
                    "tdeutils":     None #,
#                    "tdespell2":    None
                    }

opt_startModName  = ""
opt_startmod      = 0
opt_endmod        = len (pytde_modules)

def check_gcc ():
    global opt_concat

    os.system ("gcc -dumpversion > gccvers.txt")
    m = open ('gccvers.txt', 'r')
    vers = m.read ().strip ()
    m.close ()
    os.unlink ('gccvers.txt')
    print "gcc version %s" % vers

    if opt_concat == None:
        if vers < "4.0.0" or vers >= "4.0.3":
            opt_concat = 1
        else:
            opt_concat = 0

    if opt_concat == 1:
        print "concatenating files"
    else:
        print "no concatenation"
    print

def init_and_check_sanity ():
    """ Do some initialization and check various versions and
        attributes of sip and PyTQt installations
    """

    check_gcc ()

    # Check SIP is new enough.
    if sipcfg.sip_version_str[:8] != "snapshot":
        minv = None

        if sipcfg.sip_version < sip_min_v4_version:
            minv = sip_min_v4_version

        if minv:
            sipcfg.error("This version of PyKDE requires SIP v%s or later" % sipcfg.version_to_string(minv))

    # Check SIP has TQt support enabled and check version
    if pyqtcfg.qt_version == 0:
        sipconfig.error("SIP has been built with TQt support disabled.")
    if pyqtcfg.qt_version < qt_min_version:
        sipconfig.error("SIP has been built with an unsupported TQt version (%s)"\
            % sipcfg.version_to_string (sipcfg.qt_version))

    # Check PyTQt built with libtqt-mt
    if pyqtcfg.qt_threaded == 0:
        sipconfig.error ("PyKDE requires a threaded TQt version (libtqt-mt)")

    # Check PyTQt version
    if pyqtcfg.pyqt_version < pyqt_min_version:
        sipcfg.error("This version of PyKDE requires PyTQt v%s or later"\
            % pyqtcfg.version_to_string(pyqtcfg.pyqt_version))

    # find the libs, includes, and version info
    check_kde_installation ()

def usage(rcode = 2):
    """Display a usage message and exit.

    rcode is the return code passed back to the calling process.
    """
    print "Usage:"
    print "    python configure.py [-h] [-c] [-d dir] [-g] [-j #] [-k] [-n dir] [-o dir] [-r] [-u] [-v dir] [-z file]"
    print "where:"
    print "    -h      displays this help message"
    print "    -c      concatenates each module's C/C++ source files [default]"
    print "    -d dir  where the PyKDE modules will be installed [default %s]" % opt_pytdemoddir
    print "    -e lib  explicitly specify the python library"
    print "    -g      always release the GIL (SIP v3.x behaviour)"
    print "    -i      no concatenation of each module's C/C++ source files"
    print "    -j #    splits the concatenated C++ source files into # pieces [default 1]"
    print "    -k dir  the KDE base directory"
    print "    -L dir  the library directory name [default lib]"
    print "    -n dir  the directory containing the KDE lib files"
    print "    -o dir  the directory containing the KDE header files"
    print "    -r      generates code with tracing enabled [default disabled]"
    print "    -u      build with debugging symbols"
    print "    -v dir  where the PyKDE .sip files will be installed [default %s]" % opt_pytdesipdir
    print "    -w      turn on KDE deprecated object warnings when compiling [default off]"
    print "    -z file the name of a file containing command line flags"

    sys.exit(rcode)


def inform_user(stage):
    """Tell the user the option values that are going to be used.
    """
    if stage == 0:
        print
        print "     PyKDE version %s" % pytde_version_str
        print "           -------"
        print
        sipconfig.inform ("Python include directory is %s" % sipcfg.py_inc_dir)
        sipconfig.inform ("Python version is %s" % sipconfig.version_to_string (sipcfg.py_version))
        print
        sipconfig.inform ("sip version is %s (%s)" % (sipcfg.sip_version_str,
            sipconfig.version_to_string (sipcfg.sip_version)))
        print
        sipconfig.inform ("TQt directory is %s" % pyqtcfg.qt_dir)
        sipconfig.inform ("TQt version is %s" % sipconfig.version_to_string (pyqtcfg.qt_version))
        print
        sipconfig.inform ("PyTQt directory is %s" % pyqtcfg.pyqt_sip_dir)
        sipconfig.inform ("PyTQt version is %s (%s)" % (pyqtcfg.pyqt_version_str,
            sipconfig.version_to_string (pyqtcfg.pyqt_version)))
        print

    elif stage == 1:
        sipconfig.inform ("KDE base directory is %s" % opt_tdebasedir)
        sipconfig.inform ("KDE include directory is %s" % opt_kdeincdir)
        sipconfig.inform ("KDE lib directory is %s" % opt_kdelibdir)
        sipconfig.inform ("lib directory is %s" % opt_libdir)

    elif stage == 2:
        sipconfig.inform ("KDE version is %s (0x%x)" % (kde_version_str, kde_version))
        print

        sipconfig.inform("PyKDE modules will be installed in %s" % opt_pytdemoddir)
        sipconfig.inform("PyKDE .sip files will be installed in %s" % opt_pytdesipdir)
        print



def create_config(module, template):
    """Create the PyKDE configuration module so that it can be imported by build
    scripts.

    module is the module file name.
    template is the template file name.
    """
    sipconfig.inform("Creating %s..." % module)

    content = {
        "pytde_version":        pytde_version,
        "pytde_version_str":    pytde_version_str,
        "kde_version":          kde_version,
        "kde_version_str":      kde_version_str,
        "kde_version_sfx":      kde_version_sfx,
        "kde_version_extra":    kde_version_extra,
#        "pytde_bin_dir":        opt_pytdebindir,
        "pytde_mod_dir":        opt_pytdemoddir,
        "pytde_sip_dir":        opt_pytdesipdir,
        "pytde_modules":        pytde_modules,
        "pytde_kde_sip_flags":  kde_sip_flags,
        "tdebasedir":           opt_tdebasedir,
        "kdelibdir":            opt_kdelibdir,
        "libdir":               opt_libdir,
        "kdeincdir":            opt_kdeincdir,
        "pytde_modules":        pytde_modules,
        "dist_name":            opt_dist_name
    }

    sipconfig.create_config_module(module, template, content)

def getKDEVersion (versFile):
    if not os.path.isfile (versFile):
        return

    major = None
    minor = None
    micro = None

    global kde_version, kde_version_str, kde_version_sfx, kde_version_extra

    f = open (versFile)
    l = f.readline ()
    ok = 0

    while not ok and l:
        wl = string.split(l)
        if len(wl) == 3 and wl[0] == "#define":
            if wl[1] == "TDE_VERSION_MAJOR":
                major = string.strip (wl[2])

            if wl[1] == "TDE_VERSION_MINOR":
                minor = string.strip (wl[2])

            if wl[1] == "TDE_VERSION_RELEASE":
                micro = string.strip (wl[2])

        if major and minor and micro:
            ok = 1

        l = f.readline()

    f.close()

    if micro >= "90" and minor == "2":
        micro = "0"
        minor = "3"

    kde_version       = (int (major) << 16) + (int (minor) << 8)  + int (micro)

    if kde_version > kde_max_version:
      print
      sipconfig.inform ("*** True KDE version is %s -- building for KDE %s ***" % (hex (kde_version), hex (kde_max_version)))
      print
      kde_version = kde_max_version
      major       = hex ((kde_version & 0xff0000) >> 16) [ 2:]
      minor       = hex ((kde_version & 0x00ff00) >> 8) [ 2:]
      micro       = hex (kde_version & 0x0000ff) [ 2:]

    if ok:
        kde_version_str   = string.join ([major, minor, micro], ".")
        kde_version_sfx   = string.join (["-kde", major, minor, micro, ".diff"], "")
        kde_version_extra = string.join (["kde", major, minor, micro], "")
    else:
        sipconfig.error ("KDE version not found in %s" % versFile)

    global postProcess

def search (target, searchPath):
    if not searchPath:
        return

    path = None
    for searchEntry in searchPath:
        if os.path.isdir (searchEntry)\
            and (not target or os.path.isfile (os.path.join (searchEntry, target))):
            path = searchEntry
            break

    return path

def discoverKDE3 ():
    global opt_kdeincdir, opt_tdebasedir, opt_kdelibdir, opt_libdir

    if not opt_tdebasedir:
        kdeSearchPaths = []
        libSearchPaths = []
        incSearchPaths = []

        try:
            kdeSearchPaths.append (os.environ ["TDEDIR"])
        except:
            pass
        kdeSearchPaths.append (os.path.join ("/opt", "trinity"))
        kdeSearchPaths.append ("/usr")

        opt_tdebasedir = search (None, kdeSearchPaths)

    if not opt_kdelibdir:
        libSearchPaths = [os.path.join (opt_tdebasedir, "lib"), os.path.join (opt_tdebasedir, "lib64"), os.path.join (opt_tdebasedir, opt_libdir)]
#        print opt_libdir
        opt_kdelibdir  = search ("libtdecore.so", libSearchPaths)

    if not opt_kdeincdir:
        incSearchPaths = [os.path.join (opt_tdebasedir, "include")]
        incSearchPaths.append (os.path.join (opt_tdebasedir, "include", "tde")) # Red Hat
        opt_kdeincdir = search ("tdeapplication.h", incSearchPaths)

def check_kde_installation():
    """Check the KDE installation and get the version number

    """
    # Check the KDE header files have been installed.

    discoverKDE3 ()

    if not opt_tdebasedir:
        sipconfig.error ("Couldn't locate KDE3 base directory")

    if not opt_kdeincdir:
        sipconfig.error ("Couldn't locate KDE3 include directory (%s is KDE base)" % opt_tdebasedir)

    if not opt_kdelibdir:
        sipconfig.error ("Couldn't locate KDE3 lib directory (%s is KDE base)" % opt_tdebasedir)

    tdeversion_h = os.path.join(opt_kdeincdir, "tdeversion.h")

    inform_user (1)

    if not os.access(tdeversion_h, os.F_OK):
        sipconfig.error("tdeversion.h could not be found in %s." % opt_kdeincdir)

    # Get the KDE version number.
    getKDEVersion(tdeversion_h)

    inform_user (2)

def create_top_level (mname):
    """ Create the top level sip file <mname>mod.sip from <mname>mod.sip-in
        and add/delete any %Included sip files per the current KDE version
    """
    diff = srcPath(os.path.join ("sip", mname, mname + kde_version_sfx))
    plus  = []
    minus = []
    if os.path.exists (diff):
        d = open (diff)
        line = d.readline()
        while line:
            if string.find (line, "+") == 0:
                plus.append (line [2:])
            elif string.find (line, "-") == 0:
                minus.append (line [2:])

            line = d.readline()

    sipin  = open (srcPath(os.path.join ("sip", mname, mname + "mod.sip.in")))
    sipout = open (srcPath(os.path.join ("sip", mname, mname + "mod.sip")), "w")

    line = sipin.readline()
    while line:
        if string.find (line, "%Include") == 0:
            inclFound = 1
            if minus and line in minus:
                line = sipin.readline()
                continue
            sipout.write (line)
        elif string.find (line, "@mark@") == 0:
            for p in plus:
                sipout.write (p)
        elif mname == "tdeabc" and kde_version < 0x030200 and string.find (line, "tderesourcesmod.sip") >= 0:
            pass
        else:
            sipout.write (line)

        line = sipin.readline()

    sipin.close ()
    sipout.close ()

    if mname == "tdehtml":
        # PyKDE < 3.3.0 doesn't provide tdeutils (and tdehtml doesn't need it)
        sippath = srcPath(os.path.join ("sip", mname))
        if kde_version < 0x030300:
            sipin   = open (os.path.join (sippath, mname + "mod.sip"))
            sipout  = open (os.path.join (sippath, mname + "mod.sip.new"), "w")
            for line in sipin:
                if line.find ("tdeutilsmod.sip") > 0:
                    continue
                sipout.write (line)
            sipin.close ()
            sipout.close ()
            os.unlink (os.path.join (sippath, mname + "mod.sip"))
            os.rename (os.path.join (sippath, mname + "mod.sip.new"), os.path.join (sippath, mname + "mod.sip"))

            os.system ("cp %s %s" % (os.path.join (sippath, "tdehtml_part.sip.323"), os.path.join (sippath, "tdehtml_part.sip")))

        else:
            os.system ("cp %s %s" % (os.path.join (sippath, "tdehtml_part.sip.330"), os.path.join (sippath, "tdehtml_part.sip")))


def check_distribution ():
    dist = glob.glob ("/etc/*-release")

    kde_sip_flags.append ("-t")
    kde_sip_flags.append ("ALL")
    
    for file in dist:
        if file.find ("andrake") > 0:
            kde_sip_flags.pop()
            kde_sip_flags.append ("D_MANDRAKE")

def set_sip_flags():
    """Set the SIP platform, version and feature flags.
    """
    global kde_sip_flags

    check_distribution ()

    kde_sip_flags.append (pyqtcfg.pyqt_qt_sip_flags)

    kdetags = {
        0x030001: "KDE_3_0_0",
        0x030003: "KDE_3_0_1",
        0x030100: "KDE_3_0_3",
        0x030101: "KDE_3_1_0",
        0x030102: "KDE_3_1_1",
        0x030103: "KDE_3_1_2",
        0x030104: "KDE_3_1_3",
        0x030105: "KDE_3_1_4",
        0x030200: "KDE_3_1_5",
        0x030201: "KDE_3_2_0",
        0x030202: "KDE_3_2_1",
        0x030203: "KDE_3_2_2",
        0x030300: "KDE_3_2_3",
        0x030301: "KDE_3_3_0",
        0x030302: "KDE_3_3_1",
        0x030400: "KDE_3_3_2",
        0x030401: "KDE_3_4_0",
        0x030402: "KDE_3_4_1",
        0x030403: "KDE_3_4_2",
        0x030500: "KDE_3_4_3",
        0x030501: "KDE_3_5_0",
        0x030502: "KDE_3_5_1",
        0x030503: "KDE_3_5_2",
        0x040000: "KDE_3_5_3"

    }

    kde_sip_flags.append("-t")
    kde_sip_flags.append(sipconfig.version_to_sip_tag(kde_version, kdetags, "KDE"))


def generate_code(mname, imports=None, extra_cflags=None, extra_cxxflags=None, extra_define=None, extra_include_dir=None, extra_lflags=None, extra_lib_dir=None, extra_lib=None, extra_libs=None, opengl=0, sip_flags=None):
    """Generate the code for a module.

    mname is the name of the module.
    imports is the list of PyTQt/PyKDE modules that this one %Imports.
    extra_cflags is a string containing additional C compiler flags.
    extra_cxxflags is a string containing additional C++ compiler flags.
    extra_define is a name to add to the list of preprocessor defines.
    extra_include_dir is the name of a directory to add to the list of include
    directories.
    extra_lflags is a string containing additional linker flags.
    extra_lib_dir is the name of a directory to add to the list of library
    directories.
    extra_lib is the name of an extra library to add to the list of libraries.
    opengl is set if the module needs OpenGL support.
    sip_flags is the list of sip flags to use instead of the defaults.
    """
    sipconfig.inform("Generating the C++ source for the %s module..." % mname)

    create_top_level (mname)
    try:
        #create_top_level (mname)
        pass
    except:
        sipconfig.error ("Couldn't create top level sip file for %s" % mname)

    try:
        shutil.rmtree(mname)
    except:
        pass

    try:
        os.mkdir(mname)
    except:
        sipconfig.error("Unable to create the %s directory." % mname)

    # Build the SIP command line.
    argv = [sipcfg.sip_bin]
    argv.extend(kde_sip_flags)

    if opt_concat:
        argv.append("-j")
        if mname == "tdeui" and opt_split == 1:
            splits = 2
        else:
            splits = opt_split
        argv.append(str(splits))

    if opt_tracing:
        argv.append("-r")

    if opt_releasegil:
        argv.append("-g")

    argv.append("-c")
    argv.append(mname)

    buildfile = os.path.join(mname, mname + ".sbf")
    argv.append("-b")
    argv.append(buildfile)

    argv.append("-I")
    argv.append(srcPath("sip"))

    pyqtInclPathSeen = 0
    for mod in pytde_imports [mname]:
        if string.find (mod, "q") == 0 and not pyqtInclPathSeen:
            argv.append ("-I")
            argv.append (pyqtcfg.pyqt_sip_dir)
            pyqtInclPathSeen = 1

        elif mod == "dcop" or string.find (mod, "k") == 0 or string.find (mod, "tde") == 0:
            subdir = os.path.join(srcPath("sip"), mod)
            argv.append("-I")
            argv.append(subdir)

    # SIP assumes POSIX style path separators.
    argv.append(srcPath(string.join(["sip", mname, mname + "mod.sip"], "/")))

#    print string.join (argv)
    # finally, run SIP and generate the C++ code
    os.system (string.join(argv))

    # post process the C++ code for TQT_NO_TRANSLATION
    if os.system (string.join ([sys.executable, srcPath("postproc")] + ['-p', mname, "-o", "tr", "*.cpp"])) != 0:
        sipconfig.error ("Post processing of C++ code failed %s (tr)" % mname)

    # Check the result.
    if not os.access(buildfile, os.F_OK):
        sipconfig.error("Unable to create the C++ code.")

    if mname == "tdecore" and not opt_concat:
        postProcess ["tdecore"][-1][-1] = "tdecorecmodule.*"

    # Compile the Python stub.
    if sipcfg.sip_version < 0x040000:
        sipconfig.inform("Compiling %s.py..." % mname)
        py_compile.compile(os.path.join(mname, mname + ".py"), os.path.join(mname, mname + ".pyc"))
    elif mname == "tdecore":
        postProcess ["tdecore"][-1][-1] = "sip" + postProcess ["tdecore"][-1][-1]

    # needs to be here (not earlier) to catch .py files if any
    if postProcess [mname]:
        for s in postProcess [mname]:
            if os.system (string.join ([sys.executable, srcPath("postproc")] + s)) != 0:
                sipconfig.error ("Post processing of C++ code failed %s (%s)" % (mname, s [3]))

    # Generate the Makefile.
    sipconfig.inform("Creating the Makefile for the %s module..." % mname)

    installs = []
    if mname == "dcop":
        if has_objdir:
            installs.append ([[srcPath("extensions/dcopext.py"), srcPath("extensions/dcopexport.py")], opt_pytdemoddir])
        else:
            installs.append ([["../extensions/dcopext.py", "../extensions/dcopexport.py"], opt_pytdemoddir])
            

    if sipcfg.sip_version >= 0x040000:
        warnings = 1
    else:
        warnings = 0
        installs.append([[mname + ".py", mname + ".pyc"], opt_pytdemoddir])

    sipfiles = []

#    for s in glob.glob("sip/*.sip"):
#        sipfiles.append(os.path.join("..", "sip", os.path.basename(s)))
    for s in os.listdir (srcPath(os.path.join ("sip", mname))):
        if s.endswith (".sip"):
            if has_objdir:
                sipfiles.append(srcPath(os.path.join("sip", mname, os.path.basename(s))))
            else:
                sipfiles.append(os.path.join("..", "sip", mname, os.path.basename(s)))
                


    installs.append([sipfiles, os.path.join(opt_pytdesipdir, mname)])

    makefile = sipconfig.SIPModuleMakefile(
        configuration = pyqtcfg,
        build_file = mname + ".sbf",
        dir = mname,
        install_dir = opt_pytdemoddir,
        installs = installs,
        qt = 1,
        opengl = opengl,
        warnings = warnings,
        static = opt_static,
        debug = opt_debug,
    )

    if extra_cflags:
        makefile.extra_cflags.append(extra_cflags)

    if extra_cxxflags:
        makefile.extra_cxxflags.append(extra_cxxflags)

    if opt_dep_warnings == 0:
        makefile.extra_cflags.append ("-Wno-deprecated-declarations")
        makefile.extra_cxxflags.append ("-Wno-deprecated-declarations")

    if extra_define:
        makefile.extra_defines.append(extra_define)

    if has_objdir:
        makefile.extra_include_dirs.append (srcPath(os.path.join("extra", kde_version_extra)))
    else:
        makefile.extra_include_dirs.append (os.path.join ("..", "extra", kde_version_extra))
        
    makefile.extra_include_dirs.append (opt_kdeincdir)
    if kde_includes [mname]:
        for incdir in kde_includes [mname]:
            if "/" not in incdir:
                makefile.extra_include_dirs.append (os.path.join (opt_kdeincdir, incdir))
            else:
                makefile.extra_include_dirs.append (incdir)

    if extra_include_dir:
        makefile.extra_include_dirs.append(extra_include_dir)

    makefile.extra_include_dirs.append ("/usr/include/tqt")

    if extra_lflags:
        makefile.extra_lflags.append(extra_lflags)

    makefile.extra_lib_dirs.append (opt_kdelibdir)
    if extra_lib_dir:
        makefile.extra_lib_dirs.append(extra_lib_dir)

    if extra_lib == "dcop":
        extra_lib = "DCOP"
    elif extra_lib == "tdefile":
        extra_lib = "tdeio"
        
    makefile.extra_libs.append(extra_lib)
    if extra_lib == "tdefx":
        makefile.extra_libs.append ("tdecore")
    if extra_lib == "tdespell":
        makefile.extra_libs.append ("tdeui")
    if extra_lib == "tdeabc" and kde_version >= 0x030200:
        makefile.extra_libs.append ("tdeabc_file")
    if extra_lib == "tdeparts" and kde_version >= 0x030500:
        makefile.extra_lib_dirs.append (os.path.join (opt_kdelibdir, "trinity"))

    if extra_lib == "tdeprint":
        makefile.extra_cflags.append ("-fno-rtti")
        makefile.extra_cxxflags.append ("-fno-rtti")

    if extra_libs:
        makefile.extra_libs.extend(extra_libs)

    if sipcfg.sip_version < 0x040000 and imports:
        # Inter-module links.
        for im in imports:
            makefile.extra_lib_dirs.insert(0, os.path.join("..", im))
            makefile.extra_libs.insert(0, makefile.module_as_lib(im))

    makefile.generate()
    print


def create_makefiles():
    """Create the additional Makefiles.
    """
    subdirs = pytde_modules[:]

    sipconfig.inform("Creating top level Makefile...")

    sipconfig.ParentMakefile(
        configuration = pyqtcfg,
        subdirs = subdirs,
        installs= [("pytdeconfig.py", opt_pytdemoddir), (srcPath("contrib/tdepyuic"), opt_tdebasedir + "/bin")]
    ).generate()


def fileOpts (fn):
    try:
        optfile = open (fn, 'r')
    except:
        error ("Could not open option file %s" % (fn))

    opts = []

    for line in optfile.readlines ():
        if (line [0] == '#') or (line == '\n'):
           continue
        elif line [0] == '-':
            opts.append ((line [0:2], string.strip (line [2:])))
        else:
            opts.append (("-" + line [0:1], string.strip (line [1:])))

    print 'Additional options: ',
    for opt, arg in opts:
        print "%s %s   " %(opt, arg)
    print

    return opts

def main(argv):
    """Create the configuration module module.

    argv is the list of command line arguments.
    """
    try:
        optlist, args = getopt.getopt(argv[1:], "hcd:e:gij:k:L:l:n:o:ruv:wz:")
    except getopt.GetoptError:
        usage()

    global opt_pytdemoddir, opt_pytdesipdir
    global opt_debug, opt_concat, opt_releasegil
    global opt_split, opt_tracing, opt_startModName
    global opt_startmod, opt_endmod
    global opt_tdebasedir, opt_kdelibdir, opt_kdeincdir, opt_libdir
    global pytde_modules, opt_dep_warnings, opt_dist_name
    global pytde_imports, kde_includes
    global opt_libpython

    opt_libpython = None

    # Look for '-z' first and process that switch
    # (command line switches override file switches)
    for opt, arg in optlist:
        if opt == "-z":
             optlist = fileOpts (arg) + optlist
             break
        elif opt == "-h":
            usage (0)
    else:
        if args: usage()

    for opt, arg in optlist:
        if opt == "-h":
            usage(0)

        elif opt == "-e":
            opt_libpython = arg

        # turns on concatentation (on by default, here for consistency)
        elif opt == "-c":
            opt_concat = 1

        elif opt == "-d":
            opt_pytdemoddir = arg
        elif opt == "-g":
            opt_releasegil = 1

        # turns off concatenation (on by default)
        elif opt == "-i":
            opt_concat = 0

        elif opt == "-j":
            try:
                opt_split = int(arg)
            except:
                usage()

        elif opt == "-k":
            opt_tdebasedir = arg

        elif opt == "-L":
            opt_libdir = arg

        # allows build of single module (-lmodule) or all modules
        # beginning at specified module (-lmodule:)
        elif opt == "-l":
            opt_startModName = arg

        elif opt == "-n":
            opt_kdelibdir = arg
        elif opt == "-o":
            opt_kdeincdir = arg
        elif opt == "-r":
            opt_tracing = 1
        elif opt == "-u":
            opt_debug = 1
        elif opt == "-v":
            opt_pytdesipdir = arg
        elif opt == "-w":
            opt_dep_warnings = 1

    inform_user (0)
    init_and_check_sanity ()

    # Set the SIP platform, version and feature flags.
    if kde_version < 0x030200:
        pytde_modules.remove ("tdemdi")
        pytde_modules.remove ("tderesources")
        pytde_imports ["tdeabc"].remove ("tderesources")
        kde_includes ["tdeabc"].remove ("tderesources")

    if kde_version < 0x030300:
        pytde_modules.remove ("tdeutils")
#        pytde_modules.remove ("tdespell2")
        pytde_imports ["tdehtml"].remove ("tdeutils")

    opt_endmod = len (pytde_modules)
    if opt_startModName != "":
        if opt_startModName in pytde_modules:
            single = opt_startModName [-1] != ":"
            if not single:
                opt_startModName = opt_startModName [:-1]

            try:
                opt_startmod = pytde_modules.index (opt_startModName)
                if single:
                    opt_endmod = opt_startmod + 1
            except:
                sipconfig.error ("%s is not a PyKDE module" % opt_startModName)

    print "PyKDE modules to be built:\n   %s\n" % string.join(pytde_modules [opt_startmod:opt_endmod])

    set_sip_flags()

    for module in pytde_modules [opt_startmod:opt_endmod]:
        extra_libs = []
        if opt_libpython:
            extra_libs.append(opt_libpython)
        generate_code (module, pytde_imports [module], extra_lib = module, extra_libs = extra_libs)

    # Create the additional Makefiles.
    create_makefiles()

    # Install the configuration module.
    create_config("pytdeconfig.py", srcPath("pytdeconfig.py.in"))


def reporting_msg ():
    print """
If reporting errors, paste all of the output above into your
message and post to the PyKDE mailing list at:

     mailto:    PyKDE@mats.imk.fraunhofer.de
     subscribe: http://mats.imk.fraunhofer.de/mailman/listinfo/pytde

You can redirect the output into a file (> output.txt) if needed
"""



###############################################################################
# The script starts here.
###############################################################################

if __name__ == "__main__":
    try:
        main(sys.argv)
    except SystemExit:
        reporting_msg ()
        raise
    except:
        reporting_msg ()
        print \
"""
An internal error occured.  Please report all output from the program,
including the following traceback, to the PyKDE mailing list
"""
        raise
