diff --git a/lang/pyqt4/Makefile b/lang/pyqt4/Makefile new file mode 100644 index 000000000..902544a40 --- /dev/null +++ b/lang/pyqt4/Makefile @@ -0,0 +1,158 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pyqt4 +PKG_VERSION:=4.7.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=PyQt-x11-gpl-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://www.riverbankcomputing.co.uk/static/Downloads/PyQt4 +PKG_MD5SUM:=88e9f1bc467cccf424d2032e3470982c +PKG_BUILD_DIR:=$(BUILD_DIR)/PyQt-x11-gpl-$(PKG_VERSION) +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +PKG_BUILD_DEPENDS:=python-sip qt4 + +include $(INCLUDE_DIR)/package.mk +$(call include_mk, python-package.mk) +$(call include_mk, python-sip-package.mk) + +define Package/pyqt4 + SECTION:=language-python + CATEGORY:=Languages + SUBMENU:=Python + TITLE:=Python QT4 + URL:=http://www.riverbankcomputing.co.uk/software/pyqt/download + DEPENDS:=+qt4 +dbus-python +python-sip @QT4_WS_X11 +endef + +define Package/pyqt4/Description + Python QT4 framework bindings. +endef + +TARGET_INCDIRS+=$(STAGING_DIR)/include \ + $(STAGING_DIR)/usr/include \ + $(STAGING_DIR)/usr/include/Qt \ + $(STAGING_DIR)/usr/include/Qt3Support \ + $(STAGING_DIR)/usr/include/QtCore \ + $(STAGING_DIR)/usr/include/QtDBus \ + $(STAGING_DIR)/usr/include/QtGui \ + $(STAGING_DIR)/usr/include/QtNetwork \ + $(STAGING_DIR)/usr/include/QtSql \ + $(STAGING_DIR)/usr/include/QtSvg \ + $(STAGING_DIR)/usr/include/QtTest \ + $(STAGING_DIR)/usr/include/QtXml \ + $(STAGING_DIR)/usr/include/python$(PYTHON_VERSION) \ + $(STAGING_DIR)/usr/lib/dbus-1.0/include \ + $(TOOLCHAIN_DIR)/include \ + $(TOOLCHAIN_DIR)/usr/include + +TARGET_LIBDIRS+=$(STAGING_DIR)/lib \ + $(STAGING_DIR)/usr/lib \ + $(TOOLCHAIN_DIR)/lib \ + $(TOOLCHAIN_DIR)/usr/lib + +EXTRA_CFLAGS:= +EXTRA_LDFLAGS:=-Wl,-rpath-link=$(STAGING_DIR)/usr/lib \ + -Wl,-rpath=/usr/lib/ + +QTDIRSFILE:=$(PKG_BUILD_DIR)/qtdirs.out +SIPCFGFILE:=$(PKG_BUILD_DIR)/sipconfig.macros + +QT_VERSION:=./files/qt_versioning.sh version "$(STAGING_DIR)/usr/include" "$(PKG_BUILD_DIR)/qtver.tmp" +QT_EDITION:=./files/qt_versioning.sh edition "$(STAGING_DIR)/usr/include" "$(PKG_BUILD_DIR)/qtver.tmp" + +# Welcome to cross compilation hell. Dinner is served! + +define Build/Configure + echo "$(STAGING_DIR)/usr" > $(QTDIRSFILE); \ + echo "$(STAGING_DIR)/usr/include" >> $(QTDIRSFILE); \ + echo "$(STAGING_DIR)/usr/lib" >> $(QTDIRSFILE); \ + echo "$(STAGING_DIR)/usr/bin" >> $(QTDIRSFILE); \ + echo "$(STAGING_DIR)/usr/share" >> $(QTDIRSFILE); \ + echo "$(STAGING_DIR)/usr/lib/Qt/plugins" >> $(QTDIRSFILE); \ + $(QT_VERSION) >> $(QTDIRSFILE); \ + $(QT_EDITION) >> $(QTDIRSFILE); \ + echo "Open Source" >> $(QTDIRSFILE); \ + echo "shared" >> $(QTDIRSFILE); \ + \ + $(CP) "$(PYTHON_SIP_CONFIG_TEMPLATE)" "$(SIPCFGFILE)"; \ + echo "INCDIR_QT $(STAGING_DIR)/usr/include" >> $(SIPCFGFILE); \ + echo "LIBDIR_QT $(STAGING_DIR)/usr/lib" >> $(SIPCFGFILE); \ + echo "MOC $(STAGING_DIR_HOST)/bin/moc" >> $(SIPCFGFILE); \ + echo "QT_INSTALL_BINS $(STAGING_DIR)/usr/bin" >> $(SIPCFGFILE); \ + echo "QT_INSTALL_HEADERS $(STAGING_DIR)/usr/include" >> $(SIPCFGFILE); \ + echo "QT_INSTALL_LIBS $(STAGING_DIR)/usr/lib" >> $(SIPCFGFILE); \ + echo "INCDIR $(TARGET_INCDIRS)" >> $(SIPCFGFILE); \ + echo "INCDIR_OPENGL $(TARGET_INCDIRS)" >> $(SIPCFGFILE); \ + echo "INCDIR_X11 $(TARGET_INCDIRS)" >> $(SIPCFGFILE); \ + echo "LIBDIR $(TARGET_LIBDIRS)" >> $(SIPCFGFILE); \ + echo "LIBDIR_OPENGL $(TARGET_LIBDIRS)" >> $(SIPCFGFILE); \ + echo "LIBDIR_X11 $(TARGET_LIBDIRS)" >> $(SIPCFGFILE); \ + ( \ + export PYTHONPATH="$(STAGING_DIR_HOST)/$(PYTHON_PKG_DIR)"; \ + cd "$(PKG_BUILD_DIR)"; \ + python -B ./configure.py \ + --use-arch="$(ARCH)" \ + --qmake="$(STAGING_DIR_HOST)/bin/qmake" \ + --qmake-spec="$(STAGING_DIR)/usr/share/mkspecs/linux-openwrt-g++" \ + --qmake-prefix='TARGET_CC="$(TARGET_CROSS)gcc"' \ + --qmake-prefix='TARGET_CXX="$(TARGET_CROSS)g++"' \ + --qmake-prefix='TARGET_AR="$(TARGET_CROSS)ar cqs"' \ + --qmake-prefix='TARGET_OBJCOPY="$(TARGET_CROSS)objcopy"' \ + --qmake-prefix='TARGET_RANLIB="$(TARGET_CROSS)ranlib"' \ + --qmake-prefix='TARGET_CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)"' \ + --qmake-prefix='TARGET_CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)"' \ + --qmake-prefix='TARGET_LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)"' \ + --qmake-prefix='TARGET_INCDIRS="$(TARGET_INCDIRS)"' \ + --qmake-prefix='TARGET_LIBDIRS="$(TARGET_LIBDIRS)"' \ + --qmake-prefix='STAGING_DIR_HOST="$(STAGING_DIR)/../host"' \ + --qtdirs-file="$(QTDIRSFILE)" \ + --sipconfig-macros="$(SIPCFGFILE)" \ + --dbus="$(STAGING_DIR)/usr/include/dbus-1.0" \ + --bindir="$(PKG_INSTALL_DIR)/usr/bin" \ + --destdir="$(PKG_INSTALL_DIR)/$(PYTHON_PKG_DIR)" \ + --plugin-destdir="$(PKG_INSTALL_DIR)/usr/lib/Qt/plugins" \ + --pydbus-installdir="$(PKG_INSTALL_DIR)/$(PYTHON_PKG_DIR)" \ + --sipdir="$(PKG_INSTALL_DIR)/usr/share/sip" \ + --protected-is-public \ + --crosscompile \ + --no-designer-plugin \ + --no-qsci-api \ + --confirm-license \ + --verbose \ + ); \ + ./files/fixup.sh "$(PKG_BUILD_DIR)" +endef + +#FIXME: Something still puts the host Python include path into the CFLAGS. +# I'm currently unsure who does this. Most likely SIP. arghh.. + +define Build/Compile + $(MAKE_VARS) $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) +endef + +define Build/Install + $(MAKE_VARS) DESTDIR="" $(MAKE) -C $(PKG_BUILD_DIR) install +endef + +define Package/pyqt4/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_DIR) $(1)/$(PYTHON_PKG_DIR)/PyQt4 + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/{pylupdate4,pyrcc4,pyuic4} $(1)/usr/bin + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/$(PYTHON_PKG_DIR)/qt.so $(1)/$(PYTHON_PKG_DIR) + $(CP) $(PKG_INSTALL_DIR)/$(PYTHON_PKG_DIR)/PyQt4 $(1)/$(PYTHON_PKG_DIR) +endef + +$(eval $(call RequireCommand,python, \ + Please install Python 2.x \ +)) + +$(eval $(call BuildPackage,pyqt4)) diff --git a/lang/pyqt4/files/fixup.sh b/lang/pyqt4/files/fixup.sh new file mode 100755 index 000000000..c4203a06c --- /dev/null +++ b/lang/pyqt4/files/fixup.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +PKG_BUILD_DIR="$1" + +# SIP uses PyLong_FromUnsignedLong to convert from void * to +# PyLong. This results in a compilation error for the implicit cast +# on C++ compilers. Make an explicit cast. +sed -i -e 's/PyLong_FromUnsignedLong(/PyLong_FromUnsignedLong((unsigned long)/g' $PKG_BUILD_DIR/QtCore/sipQtCoreQThread.cpp + diff --git a/lang/pyqt4/files/qt_versioning.sh b/lang/pyqt4/files/qt_versioning.sh new file mode 100755 index 000000000..ec4fe9480 --- /dev/null +++ b/lang/pyqt4/files/qt_versioning.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +die() +{ + echo "PyQt qt_versioning.sh: $*" >&2 + exit 1 +} + +[ $# -eq 3 ] || die "Invalid arguments" + +action="$1" +qtincdir="$2" +tmpfile="$3" + +cp -f "$qtincdir/QtCore/qglobal.h" "$tmpfile" || die "cp failed" +echo "int QT_VERSION_IS = QT_VERSION;" >> "$tmpfile" || die "patching failed (1)" +echo "int QT_EDITION_IS = QT_EDITION;" >> "$tmpfile" || die "patching failed (2)" +# First resolve all preprocessor macros +cpp -x c++ -traditional-cpp "-I$qtincdir" "$tmpfile" > "$tmpfile.processed" || die "CPP failed" + +if [ "$action" = "version" ]; then + raw="$(grep -e 'QT_VERSION_IS' "$tmpfile.processed" | cut -d'=' -f2 | cut -d';' -f1)" +elif [ "$action" = "edition" ]; then + raw="$(grep -e 'QT_EDITION_IS' "$tmpfile.processed" | cut -d'=' -f2 | cut -d';' -f1)" +else + die "Invalid action" +fi +# We use python to evaluate the arithmetic C++ expression. Languages are similar +# enough in that area for this to succeed. +python -c "print \"%d\" % ($raw)" || die "C++ evaluation failed" + +exit 0 diff --git a/lang/pyqt4/patches/100-cross-compile.patch b/lang/pyqt4/patches/100-cross-compile.patch new file mode 100644 index 000000000..2eb458034 --- /dev/null +++ b/lang/pyqt4/patches/100-cross-compile.patch @@ -0,0 +1,362 @@ +--- + configure.py | 218 ++++++++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 149 insertions(+), 69 deletions(-) + +--- PyQt-x11-gpl-4.7.4.orig/configure.py ++++ PyQt-x11-gpl-4.7.4/configure.py +@@ -33,6 +33,7 @@ import os + import glob + import optparse + import shutil ++import re + + import sipconfig + +@@ -173,25 +174,17 @@ def create_optparser(): + metavar="PLUGIN", dest="staticplugins", help="add PLUGIN to the " + "list be linked (if Qt is built as static libraries)") + +- if sys.platform != 'win32': +- if sys.platform in ('linux2', 'darwin'): +- pip_default = True +- pip_default_str = "enabled" +- else: +- pip_default = False +- pip_default_str = "disabled" +- +- g.add_option("--protected-is-public", action="store_true", +- default=pip_default, dest="prot_is_public", +- help="enable building with 'protected' redefined as 'public' " +- "[default: %s]" % pip_default_str) +- g.add_option("--protected-not-public", action="store_false", +- dest="prot_is_public", +- help="disable building with 'protected' redefined as 'public'") +- g.add_option("-q", "--qmake", action="callback", metavar="FILE", +- default=qmake, dest="qmake", callback=store_abspath_file, +- type="string", +- help="the pathname of qmake [default: %s]" % (qmake or "none")) ++ g.add_option("--protected-is-public", action="store_true", ++ default=True, dest="prot_is_public", ++ help="enable building with 'protected' redefined as 'public' " ++ "[default: True]") ++ g.add_option("--protected-not-public", action="store_false", ++ dest="prot_is_public", ++ help="disable building with 'protected' redefined as 'public'") ++ g.add_option("-q", "--qmake", action="callback", metavar="FILE", ++ default=qmake, dest="qmake", callback=store_abspath_file, ++ type="string", ++ help="the pathname of qmake [default: %s]" % (qmake or "none")) + + g.add_option("-s", "--dbus", action="callback", metavar="DIR", + dest="pydbusincdir", callback=store_abspath_dir, type="string", +@@ -199,13 +192,13 @@ def create_optparser(): + "[default: supplied by pkg-config]") + p.add_option_group(g) + +- if sys.platform == 'darwin': +- g = optparse.OptionGroup(p, title="MacOS X Configuration") +- g.add_option("--use-arch", action="store", metavar="ARCH", +- dest="use_arch", choices=["i386", "x86_64", "ppc"], +- help="the architecture to use when running pyuic4 " +- "[default: system default]") +- p.add_option_group(g) ++ g = optparse.OptionGroup(p, title="Arch Configuration") ++ g.add_option("--use-arch", action="store", metavar="ARCH", ++ dest="use_arch", choices=["", "i386", "x86_64", "ppc", "arm"], ++ default="", ++ help="the architecture to use when running pyuic4 " ++ "[default: system default]") ++ p.add_option_group(g) + + # Installation. + g = optparse.OptionGroup(p, title="Installation") +@@ -264,12 +257,38 @@ def create_optparser(): + "QTDIR/qsci]") + p.add_option_group(g) + ++ # Crosscompilation ++ g = optparse.OptionGroup(p, title="Crosscompilation") ++ g.add_option("--crosscompile", action="store_true", ++ default=False, dest="crosscompile", ++ help="Set, if cross-compiling") ++ g.add_option("--sipconfig-macros", action="callback", metavar="FILE", ++ default=None, dest="sipconfig_macros", type="string", ++ callback=store_abspath_file, ++ help="Path to a file containing sipconfig macros") ++ g.add_option("--qmake-prefix", action="append", ++ default=[], dest="qmake_prefixes", type="string", ++ help="Commandline prefix to qmake") ++ g.add_option("--qmake-spec", action="callback", metavar="FILE", ++ default=None, dest="qmake_spec", callback=store_abspath, ++ type="string", ++ help="the pathname to qmake spec file") ++ g.add_option("--qtdirs-file", action="callback", metavar="FILE", ++ default=None, dest="qtdirs_file", callback=store_abspath_file, ++ type="string", ++ help="Path to a predefined qtdirs file") ++ g.add_option("--pydbus-installdir", action="callback", metavar="DIR", ++ default=None, dest="pydbus_installdir", callback=store_abspath, ++ type="string", ++ help="Install dir for pydbus module") ++ p.add_option_group(g) ++ + return p + + + class pyrccMakefile(sipconfig.ProgramMakefile): + """This class implements the Makefile for pyrcc. This is specialised so +- that pyrcc is automatically run against the examples. ++ that pyrcc is automatically run against the examples, if not crosscompiling. + """ + + def __init__(self): +@@ -282,6 +301,8 @@ class pyrccMakefile(sipconfig.ProgramMak + def generate_target_default(self, mfile): + """Generate the default target.""" + sipconfig.ProgramMakefile.generate_target_default(self, mfile) ++ if opts.crosscompile: ++ return + + # The correct call to pyrcc depends on the Python version. + if sys.hexversion >= 0x03000000: +@@ -772,7 +793,7 @@ include(%s) + + f.close() + +- run_command("%s %s %s" % (opts.qmake, qmake_args, wrapped_pro)) ++ run_qmake("%s %s" % (qmake_args, wrapped_pro)) + os.chdir(cwd) + + sipconfig.inform("Creating QPy support libraries Makefile...") +@@ -825,12 +846,16 @@ include(%s) + # not on Windows (so that normal console use will work). + sipconfig.inform("Creating pyuic4 wrapper...") + +- if sys.platform == 'darwin': +- gui = True ++ if opts.use_arch: ++ gui = False#FIXME + use_arch = opts.use_arch + else: +- gui = False +- use_arch = '' ++ if sys.platform == 'darwin': ++ gui = True ++ use_arch = opts.use_arch ++ else: ++ gui = False ++ use_arch = '' + + uicdir=os.path.join(pyqt_modroot, "uic") + wrapper = sipconfig.create_wrapper(os.path.join(uicdir, "pyuic.py"), os.path.join("pyuic", "pyuic4"), gui, use_arch) +@@ -880,6 +905,7 @@ include(%s) + py_major = sipcfg.py_version >> 16 + py_minor = (sipcfg.py_version >> 8) & 0x0ff + ++ print "FIXME CROSSCOMPILE" #FIXME: Crosscompile + if sys.platform == 'win32': + lib_dir_flag = quote("-L%s" % sipcfg.py_lib_dir) + link = "%s -lpython%d%d" % (lib_dir_flag, py_major, py_minor) +@@ -938,7 +964,7 @@ include(%s) + fout.write(prj) + fout.close() + +- run_command("%s %s" % (opts.qmake, qmake_args)) ++ run_qmake(qmake_args) + os.chdir(cwd) + + tool.append("designer") +@@ -1056,6 +1082,14 @@ def create_config(module, template, macr + sipconfig.create_config_module(module, template, content, macros) + + ++def run_qmake(args): ++ pfx = " ".join(opts.qmake_prefixes) ++ if opts.qmake_spec: ++ spec = "-spec \"" + opts.qmake_spec + "\"" ++ else: ++ spec = "" ++ run_command(pfx + " " + opts.qmake + " " + spec + " " + args) ++ + def run_command(cmd): + """Run a command and display the output if verbose mode is enabled. + +@@ -1272,30 +1306,38 @@ def check_dbus(): + """ + sipconfig.inform("Checking to see if the dbus support module should be built...") + +- sout = get_command_stdout("pkg-config --cflags-only-I --libs dbus-1") +- iflags = sout.read().strip() ++ if opts.crosscompile and not opts.pydbusincdir: ++ sipconfig.inform("Crosscompiling but no dbus incdir specified. Disabling dbus.") ++ return ++ ++ if not opts.crosscompile: ++ sout = get_command_stdout("pkg-config --cflags-only-I --libs dbus-1") ++ iflags = sout.read().strip() ++ ++ if not iflags: ++ sipconfig.inform("DBus v1 does not seem to be installed.") ++ return ++ ++ # Using str() means it will work with both Python v2 and v3. ++ for f in str(iflags).split(): ++ if f.startswith("-I"): ++ dbusincdirs.append(f[2:]) ++ elif f.startswith("-L"): ++ dbuslibdirs.append(f[2:]) ++ elif f.startswith("-l"): ++ dbuslibs.append(f[2:]) + +- if not iflags: +- sipconfig.inform("DBus v1 does not seem to be installed.") +- return +- +- # Using str() means it will work with both Python v2 and v3. +- for f in str(iflags).split(): +- if f.startswith("-I"): +- dbusincdirs.append(f[2:]) +- elif f.startswith("-L"): +- dbuslibdirs.append(f[2:]) +- elif f.startswith("-l"): +- dbuslibs.append(f[2:]) +- +- try: +- import dbus.mainloop +- except: +- sipconfig.inform("The Python dbus module doesn't seem to be installed.") +- return ++ try: ++ import dbus.mainloop ++ except: ++ sipconfig.inform("The Python dbus module doesn't seem to be installed.") ++ return + + global pydbusmoddir +- pydbusmoddir = dbus.mainloop.__path__[0] ++ if opts.pydbus_installdir: ++ pydbusmoddir = opts.pydbus_installdir ++ else: ++ pydbusmoddir = dbus.mainloop.__path__[0] + + # Try and find dbus-python.h. We don't use pkg-config because it is broken + # for dbus-python (at least for versions up to and including v0.81.0). +@@ -1381,6 +1423,7 @@ def set_sip_flags(pyqt): + + pyqt is the configuration instance. + """ ++ #FIXME: Needs some crosscompile fixes. + # If we don't check for signed interpreters, we exclude the 'VendorID' + # feature + if not opts.vendorcheck: +@@ -1779,6 +1822,8 @@ def check_qt_installation(macros): + def fix_qmake_args(args=""): + """Make any platform specific adjustments to the arguments passed to qmake. + """ ++ if opts.crosscompile: ++ return args + if sys.platform == "darwin": + # The Qt binary installer has macx-xcode as the default. + args = "-spec %s %s" % (sipcfg.platform, args) +@@ -1930,7 +1975,7 @@ int main(int, char **) + + # Create the makefile, first making sure it doesn't already exist. + remove_file(make_file) +- run_command("%s %s %s" % (opts.qmake, qmake_args, pro_file)) ++ run_qmake("%s %s" % (qmake_args, pro_file)) + + if not os.access(make_file, os.F_OK): + sipconfig.error("%s failed to create a makefile. %s" % (opts.qmake, MSG_CHECK_QMAKE)) +@@ -1952,15 +1997,30 @@ int main(int, char **) + if not os.access(exe_file, os.X_OK): + sipconfig.error("Failed to determine the layout of your Qt installation. Try again using the --verbose flag to see more detail about the problem.") + +- # Create the output file, first making sure it doesn't exist. +- remove_file(out_file) +- run_command(exe_file) ++ if opts.qtdirs_file: ++ # The user supplied a partial qtdirs.out file. We're probably crosscompiling. ++ # Do _not_ try to execute our qtdirs exe. Take the supplied qtdirs.out files ++ # instead and add the PyQt_... flags by grepping through the executable. ++ # This assumes the executable is not compiled with -O0. ++ read_qtdirs_file(opts.qtdirs_file) ++ global qt_xfeatures ++ print("Got %d features from qtdirs.out file: %s" % (len(qt_xfeatures), str(qt_xfeatures))) ++ found = re.findall(r'PyQt_[\w]+', file(exe_file, "r").read()) ++ print("Grepped %d features from qtdirs.exe file: %s" % (len(found), str(found))) ++ qt_xfeatures.extend(found) ++ else: ++ # Create the output file, first making sure it doesn't exist. ++ remove_file(out_file) ++ run_command(exe_file) ++ ++ if not os.access(out_file, os.F_OK): ++ sipconfig.error("%s failed to create %s. Make sure your Qt v4 installation is correct." % (exe_file, out_file)) + +- if not os.access(out_file, os.F_OK): +- sipconfig.error("%s failed to create %s. Make sure your Qt v4 installation is correct." % (exe_file, out_file)) ++ # Read the directories. ++ read_qtdirs_file(out_file) + +- # Read the directories. +- f = open(out_file, "r") ++def read_qtdirs_file(filename): ++ f = open(filename, "r") + lines = f.read().strip().split("\n") + f.close() + +@@ -2022,6 +2082,24 @@ int main(int, char **) + sipconfig.error("Qt has been built as static libraries so either the -g or -k argument should be used.") + + ++def load_sipconfig_macros(filename): ++ macros = {} ++ fd = file(filename, "r") ++ for line in fd.readlines(): ++ line = line.split() ++ try: ++ key = line[0] ++ except IndexError: ++ sipconfig.error("Invalid sipconfig macros file format") ++ value = "" ++ try: ++ value = " ".join(line[1:]) ++ except IndexError: ++ pass ++ macros[key] = value ++ return macros ++ ++ + def main(): + """Create the configuration module module. + """ +@@ -2036,7 +2114,7 @@ def main(): + opts, args = p.parse_args() + + # Provide defaults for platform-specific options. +- if sys.platform == 'win32': ++ if sys.platform == 'win32' and not opts.crosscompile: + opts.qmake = find_default_qmake() + opts.prot_is_public = False + +@@ -2069,12 +2147,14 @@ def main(): + # Install the API file if the default directory exists. + opts.api = os.path.isdir(opts.qscidir) + +- # Replace the existing build macros with the ones from the Qt installation. +- macros = get_build_macros(args) +- +- if macros is None: +- p.print_help() +- sys.exit(2) ++ if opts.sipconfig_macros: ++ macros = load_sipconfig_macros(opts.sipconfig_macros) ++ else: ++ # Replace the existing build macros with the ones from the Qt installation. ++ macros = get_build_macros(args) ++ if macros is None: ++ p.print_help() ++ sys.exit(2) + + sipcfg.set_build_macros(macros) +