add packages_10.03.2 in preparation for the 10.03.2 interim release
[10.03/packages.git] / lang / pyqt4 / patches / 100-cross-compile.patch
1 Index: PyQt-x11-gpl-4.8.3/configure.py
2 ===================================================================
3 --- PyQt-x11-gpl-4.8.3.orig/configure.py        2011-01-23 11:08:20.000000000 +0100
4 +++ PyQt-x11-gpl-4.8.3/configure.py     2011-03-13 15:03:08.279673485 +0100
5 @@ -33,6 +33,7 @@ import os
6  import glob
7  import optparse
8  import shutil
9 +import re
10  
11  import sipconfig
12  
13 @@ -184,25 +185,17 @@ def create_optparser():
14                  "in the header comments of generated code [default: include "
15                  "timestamps]")
16  
17 -    if sys.platform != 'win32':
18 -        if sys.platform in ('linux2', 'darwin'):
19 -            pip_default = True
20 -            pip_default_str = "enabled"
21 -        else:
22 -            pip_default = False
23 -            pip_default_str = "disabled"
24 -
25 -        g.add_option("--protected-is-public", action="store_true",
26 -                default=pip_default, dest="prot_is_public",
27 -                help="enable building with 'protected' redefined as 'public' "
28 -                        "[default: %s]" % pip_default_str)
29 -        g.add_option("--protected-not-public", action="store_false",
30 -                dest="prot_is_public",
31 -                help="disable building with 'protected' redefined as 'public'")
32 -        g.add_option("-q", "--qmake", action="callback", metavar="FILE",
33 -                default=qmake, dest="qmake", callback=store_abspath_file,
34 -                type="string",
35 -                help="the pathname of qmake [default: %s]" % (qmake or "none"))
36 +    g.add_option("--protected-is-public", action="store_true",
37 +            default=True, dest="prot_is_public",
38 +            help="enable building with 'protected' redefined as 'public' "
39 +                    "[default: True]")
40 +    g.add_option("--protected-not-public", action="store_false",
41 +            dest="prot_is_public",
42 +            help="disable building with 'protected' redefined as 'public'")
43 +    g.add_option("-q", "--qmake", action="callback", metavar="FILE",
44 +            default=qmake, dest="qmake", callback=store_abspath_file,
45 +            type="string",
46 +            help="the pathname of qmake [default: %s]" % (qmake or "none"))
47  
48      g.add_option("-s", "--dbus", action="callback", metavar="DIR",
49              dest="pydbusincdir", callback=store_abspath_dir, type="string",
50 @@ -210,13 +203,13 @@ def create_optparser():
51              "[default: supplied by pkg-config]")
52      p.add_option_group(g)
53  
54 -    if sys.platform == 'darwin':
55 -        g = optparse.OptionGroup(p, title="MacOS X Configuration")
56 -        g.add_option("--use-arch", action="store", metavar="ARCH",
57 -                dest="use_arch", choices=["i386", "x86_64", "ppc"],
58 -                help="the architecture to use when running pyuic4 "
59 -                        "[default: system default]")
60 -        p.add_option_group(g)
61 +    g = optparse.OptionGroup(p, title="Arch Configuration")
62 +    g.add_option("--use-arch", action="store", metavar="ARCH",
63 +            dest="use_arch", choices=["", "i386", "x86_64", "ppc", "arm"],
64 +            default="",
65 +            help="the architecture to use when running pyuic4 "
66 +                    "[default: system default]")
67 +    p.add_option_group(g)
68  
69      # Installation.
70      g = optparse.OptionGroup(p, title="Installation")
71 @@ -275,12 +268,42 @@ def create_optparser():
72              "QTDIR/qsci]")
73      p.add_option_group(g)
74  
75 +    # Crosscompilation
76 +    g = optparse.OptionGroup(p, title="Crosscompilation")
77 +    g.add_option("--crosscompile", action="store_true",
78 +                 default=False, dest="crosscompile",
79 +                 help="Set, if cross-compiling")
80 +    g.add_option("--host-sip-bin", action="callback", metavar="FILE",
81 +                 default=None, dest="host_sip_bin", type="string",
82 +                 callback=store_abspath_file,
83 +                 help="Path to the host SIP binary")
84 +    g.add_option("--sipconfig-macros", action="callback", metavar="FILE",
85 +                 default=None, dest="sipconfig_macros", type="string",
86 +                 callback=store_abspath_file,
87 +                 help="Path to a file containing sipconfig macros")
88 +    g.add_option("--qmake-prefix", action="append",
89 +                default=[], dest="qmake_prefixes", type="string",
90 +                help="Commandline prefix to qmake")
91 +    g.add_option("--qmake-spec", action="callback", metavar="FILE",
92 +                default=None, dest="qmake_spec", callback=store_abspath,
93 +                type="string",
94 +                help="the pathname to qmake spec file")
95 +    g.add_option("--qtdirs-file", action="callback", metavar="FILE",
96 +                 default=None, dest="qtdirs_file", callback=store_abspath_file,
97 +                 type="string",
98 +                 help="Path to a predefined qtdirs file")
99 +    g.add_option("--pydbus-installdir", action="callback", metavar="DIR",
100 +                 default=None, dest="pydbus_installdir", callback=store_abspath,
101 +                 type="string",
102 +                 help="Install dir for pydbus module")
103 +    p.add_option_group(g)
104 +
105      return p
106  
107  
108  class pyrccMakefile(sipconfig.ProgramMakefile):
109      """This class implements the Makefile for pyrcc.  This is specialised so
110 -    that pyrcc is automatically run against the examples.
111 +    that pyrcc is automatically run against the examples, if not crosscompiling.
112      """
113  
114      def __init__(self):
115 @@ -294,6 +317,8 @@ class pyrccMakefile(sipconfig.ProgramMak
116      def generate_target_default(self, mfile):
117          """Generate the default target."""
118          sipconfig.ProgramMakefile.generate_target_default(self, mfile)
119 +        if opts.crosscompile:
120 +            return
121  
122          # The correct call to pyrcc depends on the Python version.
123          if sys.hexversion >= 0x03000000:
124 @@ -807,7 +832,7 @@ include(%s)
125  
126              f.close()
127  
128 -            run_command("%s %s %s" % (opts.qmake, qmake_args, wrapped_pro))
129 +            run_qmake("%s %s" % (qmake_args, wrapped_pro))
130              os.chdir(cwd)
131  
132          sipconfig.inform("Creating QPy support libraries Makefile...")
133 @@ -861,12 +886,16 @@ include(%s)
134          # not on Windows (so that normal console use will work).
135          sipconfig.inform("Creating pyuic4 wrapper...")
136  
137 -        if sys.platform == 'darwin':
138 -            gui = True
139 +        if opts.use_arch:
140 +            gui = False#FIXME
141              use_arch = opts.use_arch
142          else:
143 -            gui = False
144 -            use_arch = ''
145 +            if sys.platform == 'darwin':
146 +                gui = True
147 +                use_arch = opts.use_arch
148 +            else:
149 +                gui = False
150 +                use_arch = ''
151  
152          # The pyuic directory may not exist if we are building away from the
153          # source directory.
154 @@ -926,6 +955,7 @@ include(%s)
155  
156              abi = getattr(sys, 'abiflags', '')
157  
158 +            print "FIXME CROSSCOMPILE" #FIXME: Crosscompile
159              if sys.platform == 'win32':
160                  # Use abiflags in case it is supported in a future version.
161                  lib_dir_flag = quote("-L%s" % sipcfg.py_lib_dir)
162 @@ -988,7 +1018,7 @@ include(%s)
163                  fout.write(prj)
164                  fout.close()
165  
166 -                run_command("%s %s" % (opts.qmake, qmake_args))
167 +                run_qmake(qmake_args)
168                  os.chdir(cwd)
169  
170                  tool.append("designer")
171 @@ -1106,6 +1136,14 @@ def create_config(module, template, macr
172      sipconfig.create_config_module(module, template, content, macros)
173  
174  
175 +def run_qmake(args):
176 +    pfx = " ".join(opts.qmake_prefixes)
177 +    if opts.qmake_spec:
178 +        spec = "-spec \"" + opts.qmake_spec + "\""
179 +    else:
180 +        spec = ""
181 +    run_command(pfx + " " + opts.qmake + " " + spec + " " + args)
182 +
183  def run_command(cmd, envvars=None):
184      """Run a command and display the output if verbose mode is enabled.
185  
186 @@ -1334,30 +1372,38 @@ def check_dbus():
187      """
188      sipconfig.inform("Checking to see if the dbus support module should be built...")
189  
190 -    sout = get_command_stdout("pkg-config --cflags-only-I --libs dbus-1")
191 -    iflags = sout.read().strip()
192 +    if opts.crosscompile and not opts.pydbusincdir:
193 +       sipconfig.inform("Crosscompiling but no dbus incdir specified. Disabling dbus.")
194 +       return
195 +
196 +    if not opts.crosscompile:
197 +        sout = get_command_stdout("pkg-config --cflags-only-I --libs dbus-1")
198 +        iflags = sout.read().strip()
199 +
200 +        if not iflags:
201 +            sipconfig.inform("DBus v1 does not seem to be installed.")
202 +            return
203 +
204 +        # Using str() means it will work with both Python v2 and v3.
205 +        for f in str(iflags).split():
206 +            if f.startswith("-I"):
207 +                dbusincdirs.append(f[2:])
208 +            elif f.startswith("-L"):
209 +                dbuslibdirs.append(f[2:])
210 +            elif f.startswith("-l"):
211 +                dbuslibs.append(f[2:])
212  
213 -    if not iflags:
214 -        sipconfig.inform("DBus v1 does not seem to be installed.")
215 -        return
216 -
217 -    # Using str() means it will work with both Python v2 and v3.
218 -    for f in str(iflags).split():
219 -        if f.startswith("-I"):
220 -            dbusincdirs.append(f[2:])
221 -        elif f.startswith("-L"):
222 -            dbuslibdirs.append(f[2:])
223 -        elif f.startswith("-l"):
224 -            dbuslibs.append(f[2:])
225 -
226 -    try:
227 -        import dbus.mainloop
228 -    except:
229 -        sipconfig.inform("The Python dbus module doesn't seem to be installed.")
230 -        return
231 +        try:
232 +            import dbus.mainloop
233 +        except:
234 +            sipconfig.inform("The Python dbus module doesn't seem to be installed.")
235 +            return
236  
237      global pydbusmoddir
238 -    pydbusmoddir = dbus.mainloop.__path__[0]
239 +    if opts.pydbus_installdir:
240 +        pydbusmoddir = opts.pydbus_installdir
241 +    else:
242 +        pydbusmoddir = dbus.mainloop.__path__[0]
243  
244      # Try and find dbus-python.h.  We don't use pkg-config because it is broken
245      # for dbus-python (at least for versions up to and including v0.81.0).
246 @@ -1443,6 +1489,7 @@ def set_sip_flags(pyqt):
247  
248      pyqt is the configuration instance.
249      """
250 +    #FIXME: Needs some crosscompile fixes.
251      # If we don't check for signed interpreters, we exclude the 'VendorID'
252      # feature
253      if not opts.vendorcheck:
254 @@ -1588,7 +1635,10 @@ def generate_code(mname, extra_include_d
255              needed_qt_libs(mname, qt_libs)
256  
257      # Build the SIP command line.
258 -    argv = ['"' + sipcfg.sip_bin + '"', '-w']
259 +    sip_bin = sipcfg.sip_bin
260 +    if opts.host_sip_bin:
261 +        sip_bin = opts.host_sip_bin
262 +    argv = ['"' + sip_bin + '"', '-w']
263  
264      if opts.no_timestamp:
265          argv.append("-T")
266 @@ -1890,6 +1940,8 @@ def check_qt_installation(macros):
267  def fix_qmake_args(args=""):
268      """Make any platform specific adjustments to the arguments passed to qmake.
269      """
270 +    if opts.crosscompile:
271 +        return args
272      if sys.platform == "darwin":
273          # The Qt binary installer has macx-xcode as the default.
274          args = "-spec %s %s" % (sipcfg.platform, args)
275 @@ -2041,7 +2093,7 @@ int main(int, char **)
276  
277      # Create the makefile, first making sure it doesn't already exist.
278      remove_file(make_file)
279 -    run_command("%s %s %s" % (opts.qmake, qmake_args, pro_file))
280 +    run_qmake("%s %s" % (qmake_args, pro_file))
281  
282      if not os.access(make_file, os.F_OK):
283          sipconfig.error("%s failed to create a makefile. %s" % (opts.qmake, MSG_CHECK_QMAKE))
284 @@ -2063,15 +2115,30 @@ int main(int, char **)
285      if not os.access(exe_file, os.X_OK):
286          sipconfig.error("Failed to determine the layout of your Qt installation. Try again using the --verbose flag to see more detail about the problem.")
287  
288 -    # Create the output file, first making sure it doesn't exist.
289 -    remove_file(out_file)
290 -    run_command(exe_file)
291 +    if opts.qtdirs_file:
292 +        # The user supplied a partial qtdirs.out file. We're probably crosscompiling.
293 +        # Do _not_ try to execute our qtdirs exe. Take the supplied qtdirs.out files
294 +        # instead and add the PyQt_... flags by grepping through the executable.
295 +        # This assumes the executable is not compiled with -O0.
296 +        read_qtdirs_file(opts.qtdirs_file)
297 +        global qt_xfeatures
298 +        print("Got %d features from qtdirs.out file: %s" % (len(qt_xfeatures), str(qt_xfeatures)))
299 +        found = re.findall(r'PyQt_[\w]+', file(exe_file, "r").read())
300 +        print("Grepped %d features from qtdirs.exe file: %s" % (len(found), str(found)))
301 +        qt_xfeatures.extend(found)
302 +    else:
303 +        # Create the output file, first making sure it doesn't exist.
304 +        remove_file(out_file)
305 +        run_command(exe_file)
306 +
307 +        if not os.access(out_file, os.F_OK):
308 +            sipconfig.error("%s failed to create %s. Make sure your Qt v4 installation is correct." % (exe_file, out_file))
309  
310 -    if not os.access(out_file, os.F_OK):
311 -        sipconfig.error("%s failed to create %s. Make sure your Qt v4 installation is correct." % (exe_file, out_file))
312 +        # Read the directories.
313 +        read_qtdirs_file(out_file)
314  
315 -    # Read the directories.
316 -    f = open(out_file, "r")
317 +def read_qtdirs_file(filename):
318 +    f = open(filename, "r")
319      lines = f.read().strip().split("\n")
320      f.close()
321  
322 @@ -2136,6 +2203,24 @@ int main(int, char **)
323              sipconfig.error("Qt has been built as static libraries so either the -g or -k argument should be used.")
324  
325  
326 +def load_sipconfig_macros(filename):
327 +    macros = {}
328 +    fd = file(filename, "r")
329 +    for line in fd.readlines():
330 +        line = line.split()
331 +        try:
332 +            key = line[0]
333 +        except IndexError:
334 +            sipconfig.error("Invalid sipconfig macros file format")
335 +        value = ""
336 +        try:
337 +            value = " ".join(line[1:])
338 +        except IndexError:
339 +            pass
340 +        macros[key] = value
341 +    return macros
342 +
343 +
344  def main():
345      """Create the configuration module module.
346      """
347 @@ -2154,7 +2239,7 @@ def main():
348          opts.no_timestamp = False
349  
350      # Provide defaults for platform-specific options.
351 -    if sys.platform == 'win32':
352 +    if sys.platform == 'win32' and not opts.crosscompile:
353          opts.qmake = find_default_qmake()
354          opts.prot_is_public = False
355  
356 @@ -2187,12 +2272,14 @@ def main():
357              # Install the API file if the default directory exists.
358              opts.api = os.path.isdir(opts.qscidir)
359  
360 -    # Replace the existing build macros with the ones from the Qt installation.
361 -    macros = get_build_macros(args)
362 -
363 -    if macros is None:
364 -        p.print_help()
365 -        sys.exit(2)
366 +    if opts.sipconfig_macros:
367 +        macros = load_sipconfig_macros(opts.sipconfig_macros)
368 +    else:
369 +        # Replace the existing build macros with the ones from the Qt installation.
370 +        macros = get_build_macros(args)
371 +        if macros is None:
372 +            p.print_help()
373 +            sys.exit(2)
374  
375      sipcfg.set_build_macros(macros)
376