You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1439 lines
45 KiB
1439 lines
45 KiB
# This script generates the PyQt configuration and generates the Makefiles.
|
|
#
|
|
# Copyright (c) 2007
|
|
# Riverbank Computing Limited <info@riverbankcomputing.co.uk>
|
|
#
|
|
# This file is part of PyQt.
|
|
#
|
|
# This copy of PyQt 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.
|
|
#
|
|
# PyQt 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
|
|
# PyQt; 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
|
|
|
|
import sipconfig
|
|
|
|
|
|
# Initialise the globals.
|
|
pyqt_version = 0x031102
|
|
pyqt_version_str = "3.17.2"
|
|
|
|
sip_min_version = 0x040600
|
|
|
|
|
|
# Try and find a Qt installation to use as the default.
|
|
try:
|
|
qt_dir = os.environ["QTDIR"]
|
|
except KeyError:
|
|
qt_dir = ""
|
|
|
|
|
|
qt_version = 0
|
|
qt_edition = ""
|
|
qt_incdir = None
|
|
qt_libdir = None
|
|
qt_threaded = 0
|
|
qt_winconfig = ""
|
|
|
|
pyqt = None
|
|
pyqt_modules = []
|
|
qt_sip_flags = []
|
|
qtext_sip_flags = []
|
|
qtpe_sip_flags = []
|
|
qsci_version = 0
|
|
disabled_classes = []
|
|
|
|
if sys.platform == "win32":
|
|
qsci_define = "QEXTSCINTILLA_DLL"
|
|
else:
|
|
qsci_define = ""
|
|
|
|
# Get the SIP configuration.
|
|
sipcfg = sipconfig.Configuration()
|
|
|
|
# Command line options.
|
|
opt_qtlib = None
|
|
opt_qconfigdir = None
|
|
opt_pyqtbindir = sipcfg.default_bin_dir
|
|
opt_pyqtmoddir = sipcfg.default_mod_dir
|
|
opt_pyqtsipdir = sipcfg.default_sip_dir
|
|
opt_qtpetag = None
|
|
opt_qsciincdir = None
|
|
opt_qscilibdir = None
|
|
opt_static = 0
|
|
opt_debug = 0
|
|
opt_concat = 0
|
|
opt_split = 1
|
|
opt_tracing = 0
|
|
opt_verbose = 0
|
|
opt_keepfeatures = 0
|
|
|
|
opt_vendorcheck = 0
|
|
opt_vendincdir = sipcfg.py_inc_dir
|
|
opt_vendlibdir = sipcfg.py_lib_dir
|
|
|
|
|
|
def usage(rcode = 2):
|
|
"""Display a usage message and exit.
|
|
|
|
rcode is the return code passed back to the calling process.
|
|
"""
|
|
if qt_dir:
|
|
def_qt_dir = qt_dir
|
|
else:
|
|
def_qt_dir = "none"
|
|
|
|
print "Usage:"
|
|
print " python configure.py [-h] [-a tag] [-b dir] [-c] [-d dir] [-f] [-g dir] [-i] [-j #] [-k] [-l dir] [-m dir] [-n dir] [-o dir] [-q dir] [-r] [-s] [-u] [-v dir] [-w] [-y lib] option=value option+=value ..."
|
|
print "where:"
|
|
print " -h display this help message"
|
|
print " -a tag explicitly enable the qtpe module"
|
|
print " -b dir where pyuic and pylupdate will be installed [default %s]" % opt_pyqtbindir
|
|
print " -c concatenate each module's C/C++ source files"
|
|
print " -d dir where the PyQt modules will be installed [default %s]" % opt_pyqtmoddir
|
|
print " -f keep any existing features file (when cross-compiling) [default remove]"
|
|
print " -g dir where the Qt qconfig.h file can be found [default Qt include directory]"
|
|
print " -i enable checking of signed interpreters using the VendorID package [default disabled]"
|
|
print " -j # split the concatenated C++ source files into # pieces [default 1]"
|
|
print " -k build the PyQt modules as static libraries"
|
|
print " -l dir the directory containing the VendorID header file [default %s]" % opt_vendincdir
|
|
print " -m dir the directory containing the VendorID library [default %s]" % opt_vendlibdir
|
|
print " -n dir the directory containing the QScintilla header files [default Qt include directory]"
|
|
print " -o dir the directory containing the QScintilla library [default Qt lib directory]"
|
|
print " -q dir the root directory of the Qt installation [default %s]" % def_qt_dir
|
|
print " -r generate code with tracing enabled [default disabled]"
|
|
print " -s QScintilla is a static library and not a DLL (Windows only)"
|
|
print " -u build with debugging symbols (requires a debug build of Python on Windows"
|
|
print " -v dir where the PyQt .sip files will be installed [default %s]" % opt_pyqtsipdir
|
|
print " -w don't suppress compiler output during configuration"
|
|
print " -y lib explicitly specify the type of Qt library, either qt, qt-mt, qte, qte-mt or qtmt"
|
|
|
|
sys.exit(rcode)
|
|
|
|
|
|
class ConfigureBase:
|
|
"""This is the base class for all PyQt version specific configurer classes.
|
|
Anything here is common to all configurers.
|
|
"""
|
|
def check_modules(self):
|
|
"""Check which modules should be built and add them to the global list.
|
|
|
|
Returns the name of any additional library that needs to be linked with
|
|
the main module.
|
|
"""
|
|
return None
|
|
|
|
def sip_flags(self):
|
|
"""Get the configuration specific SIP flags.
|
|
|
|
Returns a list of flags.
|
|
"""
|
|
return []
|
|
|
|
def qt_version_tags(self):
|
|
"""Get the versions tags for the configuration.
|
|
|
|
Returns a dictionary of versions and corresponding tags.
|
|
"""
|
|
return {}
|
|
|
|
def code(self, extra_include_dirs, extra_lib_dir, extra_libs):
|
|
"""Generate the code for a configuration.
|
|
|
|
extra_include_dirs is a list of directories to add to those supplied by
|
|
the SIP configuration.
|
|
extra_lib_dir is an optional directory to add to those supplied by the
|
|
SIP configuration.
|
|
extra_lib_dirs is an optional list of directories to add to those
|
|
supplied by the SIP configuration.
|
|
"""
|
|
pass
|
|
|
|
def tools(self):
|
|
"""Create the Makefiles for any other sub-directories and return a list
|
|
of those directories.
|
|
|
|
Returns a list of sub-directories with Makefile.
|
|
"""
|
|
return []
|
|
|
|
def module_dir(self):
|
|
"""Return the configuration's module directory.
|
|
"""
|
|
return opt_pyqtmoddir
|
|
|
|
def module_installs(self):
|
|
"""Return a list of files to install in the module directory other than
|
|
the modules themselves.
|
|
"""
|
|
return ["pyqtconfig.py"]
|
|
|
|
def sip_dir(self):
|
|
"""Return the configuration's .sip files directory.
|
|
"""
|
|
return opt_pyqtsipdir
|
|
|
|
|
|
class ConfigurePyQt3(ConfigureBase):
|
|
"""This class defines the methods to configure PyQt v3.
|
|
"""
|
|
def check_modules(self):
|
|
pyqt_modules.append("qt")
|
|
|
|
check_module("qtcanvas", "qcanvas.h", "QCanvas()")
|
|
check_module("qtnetwork", "qsocket.h", "QSocket()")
|
|
check_module("qttable", "qtable.h", "QTable()")
|
|
check_module("qtxml", "qdom.h", "QDomImplementation()")
|
|
check_module("qtgl", "qgl.h", "QGLWidget()", opengl=1)
|
|
|
|
if qt_version >= 0x030000:
|
|
check_module("qtui", "qwidgetfactory.h", "QWidgetFactory()", lib="qui")
|
|
|
|
if qt_edition in ("enterprise", "free"):
|
|
check_module("qtsql", "qsql.h", "QSql()")
|
|
|
|
if sys.platform == "win32" and sipcfg.sip_version >= 0x040200:
|
|
check_module("qtaxcontainer", "qaxobject.h", "QAxObject()", lib="qaxcontainer")
|
|
|
|
if qsci_version:
|
|
check_module("qtext", "qextscintillabase.h", "QextScintillaBase()", define=qsci_define, include_dir=opt_qsciincdir, lib_dir=opt_qscilibdir, lib="qscintilla")
|
|
|
|
if opt_qtpetag:
|
|
pyqt_modules.append("qtpe")
|
|
|
|
qtmod_lib = None
|
|
|
|
if qt_version >= 0x030100:
|
|
sipconfig.inform("Checking to see if the QAssistantClient class is available...")
|
|
|
|
if check_class("qassistantclient.h", "QAssistantClient(\"foo\")", lib="qassistantclient"):
|
|
qtmod_lib = "qassistantclient"
|
|
else:
|
|
disabled_classes.append("QAssistantClient")
|
|
|
|
return qtmod_lib
|
|
|
|
def sip_flags(self):
|
|
return get_feature_flags()
|
|
|
|
def qt_version_tags(self):
|
|
return {
|
|
0x010403: None,
|
|
0x020000: "Qt_1_43",
|
|
0x020100: "Qt_2_00",
|
|
0x020200: "Qt_2_1_0",
|
|
0x020300: "Qt_2_2_0",
|
|
0x020301: "Qt_2_3_0",
|
|
0x030000: "Qt_2_3_1",
|
|
0x030001: "Qt_3_0_0",
|
|
0x030002: "Qt_3_0_1",
|
|
0x030004: "Qt_3_0_2",
|
|
0x030005: "Qt_3_0_4",
|
|
0x030006: "Qt_3_0_5",
|
|
0x030100: "Qt_3_0_6",
|
|
0x030101: "Qt_3_1_0",
|
|
0x030102: "Qt_3_1_1",
|
|
0x030200: "Qt_3_1_2",
|
|
0x030300: "Qt_3_2_0",
|
|
0x030305: "Qt_3_3_0",
|
|
0x030306: "Qt_3_3_5",
|
|
0x040000: "Qt_3_3_6"
|
|
}
|
|
|
|
def code(self, extra_include_dirs, extra_lib_dir, extra_libs):
|
|
generate_code("qt", extra_include_dirs=extra_include_dirs, extra_lib_dir=extra_lib_dir, extra_libs=extra_libs)
|
|
|
|
if "qtext" in pyqt_modules:
|
|
generate_code("qtext", extra_define=qsci_define, extra_include_dirs=[opt_qsciincdir], extra_lib_dir=opt_qscilibdir, extra_libs=["qscintilla"], sip_flags=qtext_sip_flags)
|
|
|
|
if "qtgl" in pyqt_modules:
|
|
generate_code("qtgl", opengl=1)
|
|
|
|
if "qtpe" in pyqt_modules:
|
|
generate_code("qtpe", extra_libs=["qpe"], sip_flags=qtpe_sip_flags)
|
|
|
|
if "qtui" in pyqt_modules:
|
|
generate_code("qtui", extra_libs=["qui"])
|
|
|
|
if "qtaxcontainer" in pyqt_modules:
|
|
generate_code("qtaxcontainer", extra_libs=["qaxcontainer"])
|
|
|
|
# The rest don't need special handling.
|
|
for m in ("qtcanvas", "qtnetwork", "qtsql", "qttable", "qtxml"):
|
|
if m in pyqt_modules:
|
|
generate_code(m)
|
|
|
|
def tools(self):
|
|
tool_dirs = []
|
|
|
|
if qt_version >= 0x030000:
|
|
# The Professional Edition needs special handling.
|
|
prof = (qt_edition == "professional")
|
|
|
|
sipconfig.inform("Creating pyuic Makefile...")
|
|
|
|
if prof or "qtxml" not in pyqt_modules:
|
|
buildfile= "pyuic-prof.sbf"
|
|
|
|
for xml in ("qdom.cpp", "qxml.cpp"):
|
|
shutil.copyfile(qt_dir + "/src/xml/" + xml, "pyuic3/" + xml)
|
|
else:
|
|
buildfile= "pyuic.sbf"
|
|
|
|
makefile = sipconfig.ProgramMakefile(
|
|
configuration=sipcfg,
|
|
build_file=buildfile,
|
|
dir="pyuic3",
|
|
install_dir=opt_pyqtbindir,
|
|
console=1,
|
|
qt=1,
|
|
warnings=1
|
|
)
|
|
|
|
makefile.extra_defines.append("UIC")
|
|
makefile.extra_defines.append("QT_INTERNAL_XML")
|
|
|
|
if prof or "qtxml" not in pyqt_modules:
|
|
makefile.extra_defines.append("QT_MODULE_XML")
|
|
|
|
if qt_version < 0x030100:
|
|
makefile.extra_include_dirs.append(qt_dir + "/src/3rdparty/zlib")
|
|
|
|
makefile.generate()
|
|
tool_dirs.append("pyuic3")
|
|
|
|
sipconfig.inform("Creating pylupdate Makefile...")
|
|
|
|
if prof or "qtxml" not in pyqt_modules:
|
|
buildfile= "pylupdate-prof.sbf"
|
|
|
|
shutil.copyfile(qt_dir + "/src/xml/qxml.cpp", "pylupdate3/qxml.cpp")
|
|
else:
|
|
buildfile= "pylupdate.sbf"
|
|
|
|
makefile = sipconfig.ProgramMakefile(
|
|
configuration=sipcfg,
|
|
build_file=buildfile,
|
|
dir="pylupdate3",
|
|
install_dir=opt_pyqtbindir,
|
|
console=1,
|
|
qt=1,
|
|
warnings=1
|
|
)
|
|
|
|
makefile.extra_defines.append("QT_INTERNAL_XML")
|
|
|
|
if prof or "qtxml" not in pyqt_modules:
|
|
makefile.extra_defines.append("QT_MODULE_XML")
|
|
|
|
makefile.generate()
|
|
tool_dirs.append("pylupdate3")
|
|
elif qt_version >= 0x020000:
|
|
sipconfig.inform("Creating pyuic Makefile...")
|
|
|
|
makefile = sipconfig.ProgramMakefile(
|
|
configuration=sipcfg,
|
|
build_file="pyuic.sbf",
|
|
dir="pyuic2",
|
|
install_dir=opt_pyqtbindir,
|
|
console=1,
|
|
qt=1,
|
|
warnings=1
|
|
)
|
|
|
|
makefile.extra_defines.append("UIC")
|
|
makefile.extra_include_dirs.append(qt_dir + "/src/3rdparty/zlib")
|
|
|
|
makefile.generate()
|
|
tool_dirs.append("pyuic2")
|
|
|
|
return tool_dirs
|
|
|
|
|
|
def inform_user():
|
|
"""Tell the user the option values that are going to be used.
|
|
"""
|
|
if qt_edition:
|
|
edstr = qt_edition + " edition "
|
|
else:
|
|
edstr = ""
|
|
|
|
sipconfig.inform("Qt v%s %sis being used." % (sipconfig.version_to_string(qt_version), edstr))
|
|
sipconfig.inform("SIP %s is being used." % sipcfg.sip_version_str)
|
|
sipconfig.inform("These PyQt modules will be built: %s." % string.join(pyqt_modules))
|
|
|
|
if disabled_classes:
|
|
sipconfig.inform("Support for these Qt classes has been disabled: %s." % string.join(disabled_classes))
|
|
|
|
sipconfig.inform("The PyQt modules will be installed in %s." % opt_pyqtmoddir)
|
|
sipconfig.inform("The PyQt .sip files will be installed in %s." % opt_pyqtsipdir)
|
|
|
|
sipconfig.inform("The Qt header files are in %s." % qt_incdir)
|
|
sipconfig.inform("The %s Qt library is in %s." % (opt_qtlib, qt_libdir))
|
|
|
|
if qt_version >= 0x020000:
|
|
sipconfig.inform("pyuic will be installed in %s." % opt_pyqtbindir)
|
|
|
|
if qt_version >= 0x030000:
|
|
sipconfig.inform("pylupdate will be installed in %s." % opt_pyqtbindir)
|
|
|
|
if opt_vendorcheck:
|
|
sipconfig.inform("PyQt will only be usable with signed interpreters.")
|
|
|
|
|
|
def create_config(module, template, macros):
|
|
"""Create the PyQt configuration module so that it can be imported by build
|
|
scripts.
|
|
|
|
module is the module file name.
|
|
template is the template file name.
|
|
macros is the dictionary of platform specific build macros.
|
|
"""
|
|
sipconfig.inform("Creating %s..." % module)
|
|
|
|
content = {
|
|
"pyqt_config_args": sys.argv[1:],
|
|
"pyqt_version": pyqt_version,
|
|
"pyqt_version_str": pyqt_version_str,
|
|
"pyqt_bin_dir": opt_pyqtbindir,
|
|
"pyqt_mod_dir": opt_pyqtmoddir,
|
|
"pyqt_sip_dir": opt_pyqtsipdir,
|
|
"pyqt_modules": pyqt_modules,
|
|
"pyqt_qt_sip_flags": qt_sip_flags,
|
|
"qt_version": qt_version,
|
|
"qt_edition": qt_edition,
|
|
"qt_winconfig": qt_winconfig,
|
|
"qt_framework": 0,
|
|
"qt_threaded": qt_threaded,
|
|
"qt_dir": qt_dir,
|
|
"qt_inc_dir": qt_incdir,
|
|
"qt_lib": opt_qtlib,
|
|
"qt_lib_dir": qt_libdir
|
|
}
|
|
|
|
if "qtaxcontainer" in pyqt_modules:
|
|
content["pyqt_qtaxcontainer_sip_flags"] = qt_sip_flags
|
|
|
|
if "qtcanvas" in pyqt_modules:
|
|
content["pyqt_qtcanvas_sip_flags"] = qt_sip_flags
|
|
|
|
if "qtext" in pyqt_modules:
|
|
content["pyqt_qtext_sip_flags"] = qtext_sip_flags
|
|
|
|
# These are internal.
|
|
content["_pyqt_qscintilla_defines"] = qsci_define
|
|
content["_pyqt_qscintilla_inc_dir"] = opt_qsciincdir
|
|
content["_pyqt_qscintilla_lib_dir"] = opt_qscilibdir
|
|
|
|
if "qtgl" in pyqt_modules:
|
|
content["pyqt_qtgl_sip_flags"] = qt_sip_flags
|
|
|
|
if "qtnetwork" in pyqt_modules:
|
|
content["pyqt_qtnetwork_sip_flags"] = qt_sip_flags
|
|
|
|
if "qtpe" in pyqt_modules:
|
|
content["pyqt_qtpe_sip_flags"] = qtpe_sip_flags
|
|
|
|
if "qtsql" in pyqt_modules:
|
|
content["pyqt_qtsql_sip_flags"] = qt_sip_flags
|
|
|
|
if "qttable" in pyqt_modules:
|
|
content["pyqt_qttable_sip_flags"] = qt_sip_flags
|
|
|
|
if "qtui" in pyqt_modules:
|
|
content["pyqt_qtui_sip_flags"] = qt_sip_flags
|
|
|
|
if "qtxml" in pyqt_modules:
|
|
content["pyqt_qtxml_sip_flags"] = qt_sip_flags
|
|
|
|
sipconfig.create_config_module(module, template, content, macros)
|
|
|
|
|
|
def compile_qt_program(name, define=None, include_dir=None, lib_dir=None, lib=None, opengl=0, python=0, debug=0):
|
|
"""Compile a simple Qt application.
|
|
|
|
name is the name of the single source file.
|
|
define is a name to add to the list of preprocessor defines.
|
|
include_dir is the name of a directory to add to the list of include
|
|
directories.
|
|
lib_dir is the name of a directory to add to the list of library
|
|
directories.
|
|
lib is the name of a library to add to the list of libraries.
|
|
opengl is set if the application uses OpenGL.
|
|
python is set if the application #includes Python.h.
|
|
debug is set if this is a debug build.
|
|
|
|
Returns the name of the executable suitable for running or None if it
|
|
wasn't created.
|
|
"""
|
|
makefile = sipconfig.ProgramMakefile(sipcfg, console=1, qt=1, warnings=0, opengl=opengl, python=python, debug=debug)
|
|
|
|
if define:
|
|
makefile.extra_defines.append(define)
|
|
|
|
if include_dir:
|
|
makefile.extra_include_dirs.append(include_dir)
|
|
|
|
if lib_dir:
|
|
makefile.extra_lib_dirs.append(lib_dir)
|
|
|
|
if lib:
|
|
makefile.extra_libs.append(lib)
|
|
|
|
exe, build = makefile.build_command(name)
|
|
|
|
# Make sure the executable file doesn't exist.
|
|
try:
|
|
os.remove(exe)
|
|
except OSError:
|
|
pass
|
|
|
|
if not opt_verbose and hasattr(os, "popen4"):
|
|
fin, fout = os.popen4(build)
|
|
|
|
# Read stdout and stderr until there is no more output.
|
|
lout = fout.readline()
|
|
while lout:
|
|
lout = fout.readline()
|
|
|
|
fin.close()
|
|
fout.close()
|
|
|
|
try:
|
|
os.wait()
|
|
except:
|
|
pass
|
|
else:
|
|
os.system(build)
|
|
|
|
if not os.access(exe, os.X_OK):
|
|
return None
|
|
|
|
if sys.platform != "win32":
|
|
exe = "./" + exe
|
|
|
|
return exe
|
|
|
|
|
|
def check_qscintilla():
|
|
"""See if QScintilla can be found and what its version is.
|
|
"""
|
|
# Set the defaults if they haven't been explicitly specified.
|
|
global opt_qsciincdir, opt_qscilibdir
|
|
|
|
if opt_qsciincdir is None:
|
|
opt_qsciincdir = qt_incdir
|
|
|
|
if opt_qscilibdir is None:
|
|
opt_qscilibdir = qt_libdir
|
|
|
|
# Find the QScintilla header files.
|
|
sciglobal = os.path.join(opt_qsciincdir, "qextscintillaglobal.h")
|
|
|
|
if os.access(sciglobal, os.F_OK):
|
|
# Get the QScintilla version number.
|
|
global qsci_version
|
|
|
|
qsci_version, sciversstr = sipconfig.read_version(sciglobal, "QScintilla", "QSCINTILLA_VERSION", "QSCINTILLA_VERSION_STR")
|
|
|
|
if glob.glob(os.path.join(opt_qscilibdir, "*qscintilla*")):
|
|
sipconfig.inform("QScintilla %s is being used." % sciversstr)
|
|
|
|
# If we find a snapshot then set a negative version number as a
|
|
# special case.
|
|
if string.find(sciversstr, "snapshot") >= 0:
|
|
qsci_version = -1
|
|
else:
|
|
sipconfig.inform("The QScintilla library could not be found in %s and so the qtext module will not be built. If QScintilla is installed then use the -o argument to explicitly specify the correct directory." % opt_qscilibdir)
|
|
else:
|
|
sipconfig.inform("qextscintillaglobal.h could not be found in %s and so the qtext module will not be built. If QScintilla is installed then use the -n argument to explicitly specify the correct directory." % opt_qsciincdir)
|
|
|
|
|
|
def check_vendorid():
|
|
"""See if the VendorID library and include file can be found.
|
|
"""
|
|
global opt_vendorcheck
|
|
|
|
if opt_vendorcheck:
|
|
if os.access(os.path.join(opt_vendincdir, "vendorid.h"), os.F_OK):
|
|
if glob.glob(os.path.join(opt_vendlibdir, "*vendorid*")):
|
|
sipconfig.inform("The VendorID package was found.")
|
|
else:
|
|
opt_vendorcheck = 0
|
|
sipconfig.inform("The VendorID library could not be found in %s and so signed interpreter checking will be disabled. If the VendorID library is installed then use the -m argument to explicitly specify the correct directory." % opt_vendlibdir)
|
|
else:
|
|
opt_vendorcheck = 0
|
|
sipconfig.inform("vendorid.h could not be found in %s and so signed interpreter checking will be disabled. If the VendorID package is installed then use the -l argument to explicitly specify the correct directory." % opt_vendincdir)
|
|
|
|
|
|
def check_module(mname, incfile, ctor, define=None, include_dir=None, lib_dir=None, lib=None, opengl=0):
|
|
"""See if a module can be built and, if so, add it to the global list of
|
|
modules.
|
|
|
|
mname is the name of the module.
|
|
incfile is the name of the include file needed for the test.
|
|
ctor is the C++ constructor of the class being used for the test.
|
|
define is a name to add to the list of preprocessor defines.
|
|
include_dir is the name of a directory to add to the list of include
|
|
directories.
|
|
lib_dir is the name of a directory to add to the list of library
|
|
directories.
|
|
lib is the name of a library to add to the list of libraries.
|
|
opengl is set if the application uses OpenGL.
|
|
"""
|
|
# Check the module's main .sip file exists.
|
|
if os.access(os.path.join("sip", mname, mname + "mod.sip"), os.F_OK):
|
|
sipconfig.inform("Checking to see if the %s module should be built..." % mname)
|
|
|
|
if check_class(incfile, ctor, define, include_dir, lib_dir, lib, opengl):
|
|
pyqt_modules.append(mname)
|
|
|
|
|
|
def check_class(incfile, ctor, define=None, include_dir=None, lib_dir=None, lib=None, opengl=0):
|
|
"""Return non-zero if a class is available.
|
|
|
|
incfile is the name of the include file needed for the test.
|
|
ctor is the C++ constructor of the class.
|
|
define is a name to add to the list of preprocessor defines.
|
|
include_dir is the name of a directory to add to the list of include
|
|
directories.
|
|
lib_dir is the name of a directory to add to the list of library
|
|
directories.
|
|
lib is the name of a library to add to the list of libraries.
|
|
opengl is set if the application uses OpenGL.
|
|
"""
|
|
cfgtest = "cfgtest.cpp"
|
|
|
|
f = open(cfgtest, "w")
|
|
|
|
f.write("""#include <%s>
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
new %s;
|
|
}
|
|
""" % (incfile, ctor))
|
|
|
|
f.close()
|
|
|
|
return compile_qt_program(cfgtest, define, include_dir, lib_dir, lib, opengl)
|
|
|
|
|
|
def check_plugin(cname, incfile):
|
|
"""Return non-zero if a class that might be a plugin is in the main Qt
|
|
library.
|
|
|
|
cname is the name of the class.
|
|
incfile is the name of the include file needed for the test.
|
|
"""
|
|
sipconfig.inform("Checking to see if the %s class is built in..." % cname)
|
|
|
|
return check_class(incfile, cname + "()")
|
|
|
|
|
|
def create_features_file(name):
|
|
"""Create the features file.
|
|
|
|
name is the name of the features file in the current directory.
|
|
"""
|
|
# The features that a given Qt configuration may or may not support. Note
|
|
# that STYLE_WINDOWSXP and ASSISTANTCLIENT require special handling.
|
|
flist = ["ACTION", "CLIPBOARD", "CODECS", "COLORDIALOG", "DATASTREAM",
|
|
"DIAL", "DNS", "DOM", "DRAGANDDROP", "ICONVIEW", "IMAGE_TEXT",
|
|
"INPUTDIALOG", "FILEDIALOG", "FONTDATABASE", "FONTDIALOG",
|
|
"MESSAGEBOX", "MIMECLIPBOARD",
|
|
"NETWORKPROTOCOL", "NETWORKPROTOCOL_FTP", "NETWORKPROTOCOL_HTTP",
|
|
"PICTURE", "PRINTDIALOG", "PRINTER", "PROGRESSDIALOG",
|
|
"PROPERTIES",
|
|
"SEMIMODAL", "SIZEGRIP", "SOUND", "SPLITTER", "STYLE_CDE",
|
|
"STYLE_INTERLACE", "STYLE_MOTIF", "STYLE_MOTIFPLUS",
|
|
"STYLE_PLATINUM", "STYLE_SGI", "STYLE_WINDOWS",
|
|
"TABDIALOG", "TABLE", "TABLEVIEW", "TRANSFORMATIONS",
|
|
"TRANSLATION", "WIZARD", "WORKSPACE"]
|
|
|
|
# Generate the program which will generate the features file.
|
|
f = open("mkfeatures.cpp", "w")
|
|
|
|
f.write(
|
|
"""#include <Python.h>
|
|
#include <stdio.h>
|
|
#include <qglobal.h>
|
|
#include <qapplication.h>
|
|
|
|
int main(int argc,char **argv)
|
|
{
|
|
FILE *fp;
|
|
QApplication app(argc,argv,0);
|
|
|
|
if ((fp = fopen("%s","w")) == NULL)
|
|
{
|
|
printf("Unable to create '%s'\\n");
|
|
return 1;
|
|
}
|
|
|
|
#if !defined(WITH_THREAD) || !defined(QT_THREAD_SUPPORT)
|
|
fprintf(fp,"-x Qt_THREAD_SUPPORT\\n");
|
|
#endif
|
|
|
|
#if !defined(Q_WS_WIN) || QT_VERSION < 0x030000 || defined(QT_NO_STYLE_WINDOWSXP)
|
|
fprintf(fp,"-x Qt_STYLE_WINDOWSXP\\n");
|
|
#endif
|
|
|
|
#if defined(Q_OS_WIN64)
|
|
fprintf(fp,"-x Qt_Q_LONG_IS_long\\n");
|
|
#endif
|
|
""" % (name, name))
|
|
|
|
for feat in flist:
|
|
f.write(
|
|
"""
|
|
#if defined(QT_NO_%s)
|
|
fprintf(fp,"-x Qt_%s\\n");
|
|
#endif
|
|
""" % (feat, feat))
|
|
|
|
# Disable QAssistantClient for the Professional Edition.
|
|
if "QAssistantClient" in disabled_classes:
|
|
f.write(
|
|
"""
|
|
fprintf(fp,"-x Qt_ASSISTANTCLIENT\\n");
|
|
""")
|
|
|
|
f.write(
|
|
"""
|
|
fclose(fp);
|
|
|
|
return 0;
|
|
}
|
|
""")
|
|
|
|
f.close()
|
|
|
|
# Build the program.
|
|
exe = compile_qt_program("mkfeatures.cpp", include_dir=sipcfg.py_inc_dir, python=1)
|
|
if not exe:
|
|
sipconfig.error("Unable to build mkfeatures utility.")
|
|
|
|
os.system(exe)
|
|
|
|
# Check the file was created.
|
|
if not os.access(name, os.F_OK):
|
|
sipconfig.error("There was an error creating the features file.")
|
|
|
|
# Check what features have been implemented as plugins and disable them.
|
|
plugins = [("STYLE_CDE", "qcdestyle.h", "QCDEStyle"),
|
|
("STYLE_INTERLACE", "qinterlacestyle.h", "QInterlaceStyle"),
|
|
("STYLE_MOTIF", "qmotifstyle.h", "QMotifStyle"),
|
|
("STYLE_MOTIFPLUS", "qmotifplusstyle.h", "QMotifPlusStyle"),
|
|
("STYLE_PLATINUM", "qplatinumstyle.h", "QPlatinumStyle"),
|
|
("STYLE_SGI", "qsgistyle.h", "QSGIStyle"),
|
|
("STYLE_WINDOWSXP", "qwindowsxpstyle.h", "QWindowsXPStyle"),
|
|
("STYLE_WINDOWS", "qwindowsstyle.h", "QWindowsStyle")]
|
|
|
|
f = open(name, "a")
|
|
|
|
for (feat, incfile, cname) in plugins:
|
|
if not check_plugin(cname, incfile):
|
|
f.write("-x Qt_%s\n" % feat)
|
|
disabled_classes.append(cname)
|
|
|
|
f.close()
|
|
|
|
|
|
def get_feature_flags():
|
|
"""Return the list of SIP flags that exclude unsupported Qt features.
|
|
"""
|
|
featfile = "features"
|
|
|
|
# Create the features file if it doesn't exist and we are not keeping it.
|
|
if opt_keepfeatures and os.access(featfile,os.F_OK):
|
|
sipconfig.inform("Using existing features file.")
|
|
else:
|
|
sipconfig.inform("Creating features file...")
|
|
create_features_file(featfile)
|
|
|
|
# Parse the features file.
|
|
ff = open(featfile, "r")
|
|
|
|
flags = []
|
|
|
|
line = ff.readline()
|
|
while line:
|
|
flags.extend(string.split(line))
|
|
line = ff.readline()
|
|
|
|
return flags
|
|
|
|
|
|
def set_sip_flags():
|
|
"""Set the SIP platform, version and feature flags.
|
|
"""
|
|
qt_sip_flags.extend(pyqt.sip_flags())
|
|
|
|
# If we don't check for signed interpreters, we exclude the 'VendorID'
|
|
# feature
|
|
if not opt_vendorcheck:
|
|
qt_sip_flags.append("-x")
|
|
qt_sip_flags.append("VendorID")
|
|
|
|
# Handle the platform tag.
|
|
if opt_qtpetag:
|
|
plattag = "WS_QWS"
|
|
elif sys.platform == "win32":
|
|
plattag = "WS_WIN"
|
|
elif sys.platform == "darwin":
|
|
if "__DARWIN_X11__" in sipcfg.build_macros()["DEFINES"]:
|
|
plattag = "WS_X11"
|
|
else:
|
|
plattag = "WS_MACX"
|
|
else:
|
|
plattag = "WS_X11"
|
|
|
|
qt_sip_flags.append("-t")
|
|
qt_sip_flags.append(plattag)
|
|
|
|
# Handle the Qt version tag.
|
|
verstag = sipconfig.version_to_sip_tag(qt_version, pyqt.qt_version_tags(), "Qt")
|
|
|
|
if verstag:
|
|
qt_sip_flags.append("-t")
|
|
qt_sip_flags.append(verstag)
|
|
|
|
# The flags so far are common.
|
|
for f in qt_sip_flags:
|
|
qtext_sip_flags.append(f)
|
|
qtpe_sip_flags.append(f)
|
|
|
|
# Handle the QScintilla version tag.
|
|
if qsci_version:
|
|
qscitags = {
|
|
0x010100: None,
|
|
0x010200: "QScintilla_1_1",
|
|
0x010300: "QScintilla_1_2",
|
|
0x010400: "QScintilla_1_3",
|
|
0x010500: "QScintilla_1_4",
|
|
0x010600: "QScintilla_1_5",
|
|
0x010700: "QScintilla_1_6",
|
|
0x020000: "QScintilla_1_7"
|
|
}
|
|
|
|
verstag = sipconfig.version_to_sip_tag(qsci_version, qscitags, "QScintilla")
|
|
|
|
if verstag:
|
|
qtext_sip_flags.append("-t")
|
|
qtext_sip_flags.append(verstag)
|
|
|
|
# Handle the Qtopia tag.
|
|
if opt_qtpetag:
|
|
qtpe_sip_flags.append("-t")
|
|
qtpe_sip_flags.append(opt_qtpetag)
|
|
|
|
|
|
def generate_code(mname, extra_cflags=None, extra_cxxflags=None, extra_define=None, extra_include_dirs=None, extra_lflags=None, extra_lib_dir=None, extra_libs=None, opengl=0, sip_flags=None):
|
|
"""Generate the code for a module.
|
|
|
|
mname is the name of the module.
|
|
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_dirs is a list of directories 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_libs is a list of the names of extra libraries 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)
|
|
|
|
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 + '"']
|
|
|
|
if sip_flags is None:
|
|
sip_flags = qt_sip_flags
|
|
|
|
argv.extend(sip_flags)
|
|
|
|
if opt_concat:
|
|
argv.append("-j")
|
|
argv.append(str(opt_split))
|
|
|
|
if opt_tracing:
|
|
argv.append("-r")
|
|
|
|
argv.append("-c")
|
|
argv.append(mname)
|
|
|
|
buildfile = os.path.join(mname, mname + ".sbf")
|
|
argv.append("-b")
|
|
argv.append(buildfile)
|
|
|
|
argv.append("-I")
|
|
argv.append("sip")
|
|
|
|
# SIP assumes POSIX style path separators.
|
|
argv.append(string.join(["sip", mname, mname + "mod.sip"], "/"))
|
|
|
|
os.system(string.join(argv))
|
|
|
|
# Check the result.
|
|
if not os.access(buildfile, os.F_OK):
|
|
sipconfig.error("Unable to create the C++ code.")
|
|
|
|
# Generate the Makefile.
|
|
sipconfig.inform("Creating the Makefile for the %s module..." % mname)
|
|
|
|
installs = []
|
|
sipfiles = []
|
|
|
|
for s in glob.glob("sip/" + mname + "/*.sip"):
|
|
sipfiles.append(os.path.join("..", "sip", mname, os.path.basename(s)))
|
|
|
|
installs.append([sipfiles, os.path.join(pyqt.sip_dir(), mname)])
|
|
|
|
makefile = sipconfig.SIPModuleMakefile(
|
|
configuration=sipcfg,
|
|
build_file=mname + ".sbf",
|
|
dir=mname,
|
|
install_dir=pyqt.module_dir(),
|
|
installs=installs,
|
|
qt=1,
|
|
opengl=opengl,
|
|
warnings=1,
|
|
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 extra_define:
|
|
makefile.extra_defines.append(extra_define)
|
|
|
|
if extra_include_dirs:
|
|
makefile.extra_include_dirs.extend(extra_include_dirs)
|
|
|
|
if extra_lflags:
|
|
makefile.extra_lflags.append(extra_lflags)
|
|
|
|
if extra_lib_dir:
|
|
makefile.extra_lib_dirs.append(extra_lib_dir)
|
|
|
|
if extra_libs:
|
|
makefile.extra_libs.extend(extra_libs)
|
|
|
|
makefile.generate()
|
|
|
|
|
|
def check_license():
|
|
"""Handle the validation of the PyQt license.
|
|
"""
|
|
try:
|
|
import license
|
|
ltype = license.LicenseType
|
|
lname = license.LicenseName
|
|
|
|
try:
|
|
lfile = license.LicenseFile
|
|
except AttributeError:
|
|
lfile = None
|
|
except ImportError:
|
|
ltype = None
|
|
|
|
if ltype is None:
|
|
ltype = "GPL"
|
|
lname = "GNU General Public License"
|
|
lfile = None
|
|
|
|
sipconfig.inform("This is the %s version of PyQt %s (licensed under the %s) for Python %s on %s." % (ltype, pyqt_version_str, lname, string.split(sys.version)[0], sys.platform))
|
|
|
|
# Common checks.
|
|
if ltype == "GPL" and sys.platform == "win32":
|
|
error("You cannot use the GPL version of PyQt under Windows.")
|
|
|
|
try:
|
|
qted = qt_edition
|
|
except AttributeError:
|
|
qted = None
|
|
|
|
if qted and ltype != "internal":
|
|
if (qted == "free" and ltype != "GPL") or (qted != "free" and ltype == "GPL"):
|
|
sipconfig.error("This version of PyQt and the %s edition of Qt have incompatible licenses." % qted)
|
|
|
|
# Confirm the license.
|
|
print
|
|
print "Type 'L' to view the license."
|
|
print "Type 'yes' to accept the terms of the license."
|
|
print "Type 'no' to decline the terms of the license."
|
|
print
|
|
|
|
while 1:
|
|
try:
|
|
resp = raw_input("Do you accept the terms of the license? ")
|
|
except:
|
|
resp = ""
|
|
|
|
resp = string.lower(string.strip(resp))
|
|
|
|
if resp == "yes":
|
|
break
|
|
|
|
if resp == "no":
|
|
sys.exit(0)
|
|
|
|
if resp == "l":
|
|
os.system("more LICENSE")
|
|
|
|
# If there should be a license file then check it is where it should be.
|
|
if lfile:
|
|
if os.access(os.path.join("sip", lfile), os.F_OK):
|
|
sipconfig.inform("Found the license file %s." % lfile)
|
|
else:
|
|
sipconfig.error("Please copy the license file %s to the sip directory." % lfile)
|
|
|
|
|
|
def get_build_macros(overrides):
|
|
"""Return the dictionary of platform specific build macros from the Qt
|
|
installation. Return None if any of the overrides was invalid.
|
|
|
|
overrides is a list of macros overrides from the user.
|
|
"""
|
|
# Get the name of the qmake configuration file to take the macros from.
|
|
if "QMAKESPEC" in os.environ.keys():
|
|
fname = os.path.join(qt_dir, "mkspecs", os.environ["QMAKESPEC"], "qmake.conf")
|
|
else:
|
|
fname = os.path.join(qt_dir, "mkspecs", "default", "qmake.conf")
|
|
|
|
if not os.access(fname, os.F_OK):
|
|
sipconfig.error("Unable to find the default configuration file %s. You can use the QMAKESPEC environment variable to specify the correct platform instead of \"default\"." % fname)
|
|
|
|
# Add the Qt specific macros to the default.
|
|
names = sipcfg.build_macros().keys()
|
|
names.append("INCDIR_QT")
|
|
names.append("LIBDIR_QT")
|
|
names.append("MOC")
|
|
|
|
# Make sure $QTDIR reflects any directory passed on the command line.
|
|
os.environ["QTDIR"] = qt_dir
|
|
|
|
properties = {
|
|
"QT_INSTALL_BINS": os.path.join(qt_dir, "bin"),
|
|
"QT_INSTALL_HEADERS": os.path.join(qt_dir, "include"),
|
|
"QT_INSTALL_LIBS": os.path.join(qt_dir, "lib")
|
|
}
|
|
|
|
return sipconfig.parse_build_macros(fname, names, overrides, properties)
|
|
|
|
|
|
def check_qt_installation(macros):
|
|
"""Check the Qt installation and get the version number and edition.
|
|
|
|
macros is the dictionary of build macros.
|
|
"""
|
|
# Get the Makefile generator.
|
|
generator = macros["MAKEFILE_GENERATOR"]
|
|
|
|
# Set the Qt include and lib directories.
|
|
global qt_incdir, qt_libdir
|
|
|
|
qt_incdir = macros["INCDIR_QT"]
|
|
|
|
if not qt_incdir:
|
|
qt_incdir = os.path.join(qt_dir, "include")
|
|
macros["INCDIR_QT"] = qt_incdir
|
|
|
|
qt_libdir = macros["LIBDIR_QT"]
|
|
|
|
if not qt_libdir:
|
|
qt_libdir = os.path.join(qt_dir, "lib")
|
|
macros["LIBDIR_QT"] = qt_libdir
|
|
|
|
# Check the Qt header files have been installed. Quietly check for Qt v4.
|
|
qt4_d = os.path.join(qt_incdir, "QtCore")
|
|
|
|
qglobal = os.path.join(qt4_d, "qglobal.h")
|
|
|
|
if not os.access(qglobal, os.F_OK):
|
|
qglobal = os.path.join(qt_incdir, "qglobal.h")
|
|
|
|
if not os.access(qglobal, os.F_OK):
|
|
sipconfig.error("qglobal.h could not be found in %s." % qt_incdir)
|
|
|
|
# Get the Qt version number.
|
|
global qt_version
|
|
|
|
qt_version, ignore = sipconfig.read_version(qglobal, "Qt", "QT_VERSION")
|
|
|
|
# Early versions of Qt for the Mac didn't include everything. Rather than
|
|
# maintain these in the future we just mandate a later version.
|
|
if sys.platform == "darwin" and qt_version < 0x030100:
|
|
sipconfig.error("PyQt for MacOS/X requires Qt v3.1.0 or later.")
|
|
|
|
# The way SIP v4.2 and later handle connections between signals and Python
|
|
# slots only works with Qt v3 and later. Therefore Qt v2 and earlier needs
|
|
# SIP v3.
|
|
if qt_version < 0x030000:
|
|
sipconfig.error("Qt v2.x and earlier require SIP v3.x.")
|
|
|
|
if qt_version >= 0x040000:
|
|
sipconfig.error("Qt v4.x requires PyQt v4.x.")
|
|
|
|
# Try and work out which edition it is.
|
|
global qt_edition
|
|
|
|
if qt_version >= 0x030000:
|
|
if opt_qconfigdir:
|
|
qconfigdir = opt_qconfigdir
|
|
else:
|
|
qconfigdir = qt_incdir
|
|
|
|
qconfig = os.path.join(qconfigdir, "qconfig.h")
|
|
|
|
if not os.access(qconfig,os.F_OK):
|
|
sipconfig.error("qconfig.h could not be found in %s." % qconfigdir)
|
|
|
|
f = open(qconfig)
|
|
l = f.readline()
|
|
|
|
while l:
|
|
wl = string.split(l)
|
|
if len(wl) == 3 and wl[0] == "#define" and wl[1] == "QT_PRODUCT_LICENSE":
|
|
qt_edition = wl[2][4:-1]
|
|
break
|
|
|
|
l = f.readline()
|
|
|
|
f.close()
|
|
|
|
if not qt_edition:
|
|
sipconfig.error("The Qt edition could not be determined by parsing %s." % qconfig)
|
|
elif qt_version == 0x020300 and sys.platform == "win32":
|
|
# See if we have the Qt v2 non-commercial version.
|
|
if os.access(os.path.join(qt_libdir, "qt-mt230nc.lib"), os.F_OK):
|
|
qt_edition = "non-commercial"
|
|
|
|
if sys.platform == "win32":
|
|
# Work out how Qt was built on Windows.
|
|
|
|
global qt_winconfig
|
|
|
|
try:
|
|
f = open(os.path.join(qt_dir, ".qtwinconfig"), "r")
|
|
except IOError:
|
|
f = None
|
|
|
|
if f:
|
|
cfg = f.readline()
|
|
f.close()
|
|
|
|
val = string.find(cfg, "=")
|
|
|
|
if val >= 0:
|
|
qt_winconfig = string.strip(cfg[val + 1:])
|
|
else:
|
|
# Assume it was built as a DLL.
|
|
qt_winconfig = "shared"
|
|
|
|
# Determine the Qt library to link against and if it has thread support.
|
|
global qt_threaded
|
|
|
|
resolve_qt3_library(generator)
|
|
|
|
if opt_qtlib in ("qt-mt", "qt-mtedu", "qt-mteval", "qte-mt", "qtmt", "qtmtedu", "qtmteval"):
|
|
qt_threaded = 1
|
|
|
|
global pyqt
|
|
|
|
pyqt = ConfigurePyQt3()
|
|
|
|
# We haven't yet factored out sipconfig's knowledge of how to build Qt
|
|
# binaries and it is expecting to find these in the configuration when it
|
|
# generates the Makefiles.
|
|
sipcfg.qt_version = qt_version
|
|
sipcfg.qt_edition = qt_edition
|
|
sipcfg.qt_winconfig = qt_winconfig
|
|
sipcfg.qt_framework = 0
|
|
sipcfg.qt_threaded = qt_threaded
|
|
sipcfg.qt_dir = qt_dir
|
|
sipcfg.qt_lib = opt_qtlib
|
|
sipcfg.qt_lib_dir = qt_libdir
|
|
|
|
|
|
def resolve_qt3_library(generator):
|
|
"""See which version of the Qt v3 library can be found. (We can't trust
|
|
the configuration files.)
|
|
|
|
generator is the name of the Makefile generator.
|
|
"""
|
|
global opt_qtlib
|
|
|
|
if opt_qtlib:
|
|
if not is_qt_library(generator, opt_qtlib):
|
|
sipconfig.error("The %s Qt library could not be found in %s." % (opt_qtlib, qt_libdir))
|
|
else:
|
|
stlib = is_qt_library(generator, "qt")
|
|
mtlib = is_qt_library(generator, "qt-mt")
|
|
edlib = is_qt_library(generator, "qt-mtedu")
|
|
evlib = is_qt_library(generator, "qt-mteval")
|
|
emlib = is_qt_library(generator, "qte")
|
|
etlib = is_qt_library(generator, "qte-mt")
|
|
|
|
# Borland likes to be a little different.
|
|
bmtlib = is_qt_library(generator, "qtmt")
|
|
bedlib = is_qt_library(generator, "qtmtedu")
|
|
bevlib = is_qt_library(generator, "qtmteval")
|
|
|
|
names = []
|
|
|
|
if stlib:
|
|
opt_qtlib = "qt"
|
|
names.append(opt_qtlib)
|
|
|
|
if mtlib:
|
|
opt_qtlib = "qt-mt"
|
|
names.append(opt_qtlib)
|
|
|
|
if edlib:
|
|
opt_qtlib = "qt-mtedu"
|
|
names.append(opt_qtlib)
|
|
|
|
if evlib:
|
|
opt_qtlib = "qt-mteval"
|
|
names.append(opt_qtlib)
|
|
|
|
if emlib:
|
|
opt_qtlib = "qte"
|
|
names.append(opt_qtlib)
|
|
|
|
if etlib:
|
|
opt_qtlib = "qte-mt"
|
|
names.append(opt_qtlib)
|
|
|
|
if bmtlib:
|
|
opt_qtlib = "qtmt"
|
|
names.append(opt_qtlib)
|
|
|
|
if bedlib:
|
|
opt_qtlib = "qtmtedu"
|
|
names.append(opt_qtlib)
|
|
|
|
if bevlib:
|
|
opt_qtlib = "qtmteval"
|
|
names.append(opt_qtlib)
|
|
|
|
if not names:
|
|
sipconfig.error("No Qt libraries could be found in %s." % qt_libdir)
|
|
|
|
if len(names) > 1:
|
|
sipconfig.error("These Qt libraries were found: %s. Use the -y argument to explicitly specify which you want to use." % string.join(names))
|
|
|
|
|
|
def is_qt_library(generator, lib):
|
|
"""See if a particular Qt library is installed.
|
|
|
|
generator is the name of the Makefile generator.
|
|
lib is the name of the library.
|
|
"""
|
|
if generator in ("MSVC", "MSVC.NET", "BMAKE"):
|
|
lpatts = [lib + "[0-9]*.lib", lib + ".lib"]
|
|
else:
|
|
lpatts = ["lib" + lib + ".*"]
|
|
|
|
for lpatt in lpatts:
|
|
lmatch = glob.glob(os.path.join(qt_libdir, lpatt))
|
|
|
|
if lmatch:
|
|
return lmatch
|
|
|
|
return []
|
|
|
|
|
|
def main(argv):
|
|
"""Create the configuration module module.
|
|
|
|
argv is the list of command line arguments.
|
|
"""
|
|
# Check SIP is new enough.
|
|
if sipcfg.sip_version_str[:8] != "snapshot":
|
|
if sipcfg.sip_version < sip_min_version:
|
|
sipconfig.error("This version of PyQt requires SIP v%s or later" % sipconfig.version_to_string(sip_min_version))
|
|
|
|
# Parse the command line.
|
|
try:
|
|
optlist, args = getopt.getopt(argv[1:], "ha:b:cd:fg:ij:kl:m:n:o:q:rsuv:wy:")
|
|
except getopt.GetoptError:
|
|
usage()
|
|
|
|
global qt_dir, opt_qtlib, opt_qconfigdir
|
|
global opt_pyqtbindir, opt_pyqtmoddir, opt_pyqtsipdir
|
|
global opt_qtpetag, opt_static, opt_debug, opt_concat
|
|
global opt_split, opt_tracing, opt_verbose, opt_keepfeatures
|
|
global opt_qsciincdir, opt_qscilibdir, qsci_define
|
|
global opt_vendorcheck, opt_vendincdir, opt_vendlibdir
|
|
|
|
for opt, arg in optlist:
|
|
if opt == "-h":
|
|
usage(0)
|
|
elif opt == "-a":
|
|
opt_qtpetag = arg
|
|
elif opt == "-b":
|
|
opt_pyqtbindir = os.path.abspath(arg)
|
|
elif opt == "-c":
|
|
opt_concat = 1
|
|
elif opt == "-d":
|
|
opt_pyqtmoddir = os.path.abspath(arg)
|
|
elif opt == "-f":
|
|
opt_keepfeatures = 1
|
|
elif opt == "-g":
|
|
opt_qconfigdir = os.path.abspath(arg)
|
|
elif opt == "-i":
|
|
opt_vendorcheck = 1
|
|
elif opt == "-j":
|
|
try:
|
|
opt_split = int(arg)
|
|
except:
|
|
usage()
|
|
elif opt == "-k":
|
|
opt_static = 1
|
|
elif opt == "-l":
|
|
opt_vendincdir = arg
|
|
elif opt == "-m":
|
|
opt_vendlibdir = arg
|
|
elif opt == "-n":
|
|
opt_qsciincdir = arg
|
|
elif opt == "-o":
|
|
opt_qscilibdir = arg
|
|
elif opt == "-q":
|
|
qt_dir = os.path.abspath(arg)
|
|
elif opt == "-r":
|
|
opt_tracing = 1
|
|
elif opt == "-s":
|
|
qsci_define = ""
|
|
elif opt == "-u":
|
|
opt_debug = 1
|
|
elif opt == "-v":
|
|
opt_pyqtsipdir = os.path.abspath(arg)
|
|
elif opt == "-w":
|
|
opt_verbose = 1
|
|
elif opt == "-y":
|
|
if arg in ("qt", "qt-mt", "qt-mtedu", "qt-mteval", "qte", "qte-mt", "qtmt", "qtmtedu"):
|
|
opt_qtlib = arg
|
|
else:
|
|
usage()
|
|
|
|
# Check that we know the name of the Qt root directory.
|
|
if not qt_dir:
|
|
sipconfig.error("A Qt installation could not be found. Use use the -q argument or the QTDIR environment variable to explicitly specify the correct directory.")
|
|
|
|
# When building static libraries, signed interpreter checking makes no
|
|
# sense.
|
|
if opt_vendorcheck and opt_static:
|
|
sipconfig.error("Using the VendorID package when building static libraries makes no sense.")
|
|
|
|
# Replace the existing build macros with the ones from the Qt installation.
|
|
macros = get_build_macros(args)
|
|
|
|
if macros is None:
|
|
usage()
|
|
|
|
sipcfg.set_build_macros(macros)
|
|
|
|
# Check Qt is what we need.
|
|
check_qt_installation(macros)
|
|
|
|
# Check the licenses are compatible.
|
|
check_license()
|
|
|
|
# Check for QScintilla.
|
|
check_qscintilla()
|
|
|
|
# Check which modules to build.
|
|
qtmod_lib = pyqt.check_modules()
|
|
|
|
# Check for the VendorID package.
|
|
check_vendorid()
|
|
|
|
# Set the SIP platform, version and feature flags.
|
|
set_sip_flags()
|
|
|
|
# Tell the user what's been found.
|
|
inform_user()
|
|
|
|
# Generate the code.
|
|
|
|
extra_include_dirs = []
|
|
extra_libs = []
|
|
|
|
if qtmod_lib:
|
|
extra_libs.append(qtmod_lib)
|
|
|
|
if opt_vendorcheck:
|
|
extra_include_dirs.append(opt_vendincdir)
|
|
extra_lib_dir = opt_vendlibdir
|
|
extra_libs.append("vendorid")
|
|
else:
|
|
extra_lib_dir = None
|
|
|
|
pyqt.code(extra_include_dirs, extra_lib_dir, extra_libs)
|
|
|
|
# Create the additional Makefiles.
|
|
sipconfig.inform("Creating top level Makefile...")
|
|
|
|
sipconfig.ParentMakefile(
|
|
configuration=sipcfg,
|
|
subdirs=pyqt_modules + pyqt.tools(),
|
|
installs=(pyqt.module_installs(), pyqt.module_dir())
|
|
).generate()
|
|
|
|
# Install the configuration module.
|
|
create_config("pyqtconfig.py", "pyqtconfig.py.in", macros)
|
|
|
|
|
|
###############################################################################
|
|
# The script starts here.
|
|
###############################################################################
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
main(sys.argv)
|
|
except SystemExit:
|
|
raise
|
|
except:
|
|
print \
|
|
"""An internal error occured. Please report all the output from the program,
|
|
including the following traceback, to support@riverbankcomputing.co.uk.
|
|
"""
|
|
raise
|