[PyKDE] Compiling sip 4.1.1, PyQt 3.13, PyKDE 3.11.3 on Solaris 8micro-Howto

Holger Joukl Holger.Joukl at LBBW.de
Fri Mar 4 14:01:44 MET 2005


As promised, a more detailed description of a successful sip/pyqt/pykde
build on Solaris 8,
using gcc 2.95.2.
As this became rather lengthy I will quick-start with a summary of what
worked for me.
Find the details afterwards.
Thanks to everybody for hints & information.
SIP/pyqt/pykde are great tools!

Cheers,
Holger

Versions:
=========
sip version is 4.1.1 (4.1.1)
PyQt version is 3.13 (3.13.0)
PyKDE version 3.11.3

qscintilla-1.62-gpl-1.5

Python version is 2.3.4
Qt version is 3.3.3
KDE version is 3.3.2 (0x30302)

gcc 2.95.2


Quickstart: Solutions - summary:
================================

sip-4.1.1:
----------
1. For largefile-support-compiled python:

add an extra define when configuring sip:
DEFINES+=__PRAGMA_REDEFINE_EXTNAME
e.g.
${PYTHON} configure.py -b ${SIP_BINDIR} -d ${SIP_LIBDIR} -e
${SIP_INCLUDEDIR} \
                   -l qt-mt -v ${SIP_DIR/share} \
                   RPATH+=${RPATH} \
                   DEFINES+=__PRAGMA_REDEFINE_EXTNAME
would be how I call sip´s configure.py in my custom build script.

2. Change sip-4.1.1/sipgen/gencode.c to use C-style casts instead of static
casts:
<gencode.c>
...
 4002                                  else if (res -> atype == enum_type
&& isProtectedEnum(res -> u.ed))
 4003                                  {
 4004
//prcode(fp,"static_cast<%E>(",res -> u.ed);
 4005                                          // C-style cast
 4006                                          prcode(fp,"(%E) (",res ->
u.ed);
 4007                                          incast = TRUE;
 4008                                  }
...
</gencode.c>

PyQt-x11-gpl-3.13:
------------------
-

PyKDE-3.11.3:
-------------
1. Apply a "patch" to PyKDE I found on the mailing list which adds support
for
KDE 3.3.2 (by using the 3.3.0 stuff):

    for i in `find | grep kde330 | grep diff`; do
        echo $i
        mv -f $i `echo $i | sed 's/330/332/'`
    done

2. Modify pykde configure.py:
<configure.py>
...
   664  #    if extra_lib not in ["kfile"] and extra_lib:
   665      makefile.extra_libs.append(extra_lib)
   666
   667      # Hm, have to link libkdecore.so for kdefx, otherwise:
   668      #  kdefx.so: symbol _._4KURL: referenced symbol not found
   669      # c++filt _._4KURL --> KURL::~KURL(void)
   670      if extra_lib == "kdefx":
   671          makefile.extra_libs.append("kdecore")
   672
...
</configure.py>

3. Run configure.py
4. Manually change generated file PyKDE-3.11.3/kdecore/sipkdecorepart0.cpp.
Line numbers might differ for you (?), but the relevant function is
meth_KStartupInfoData_pids:

<sipkdecorepart0.cpp>
...
48621  static PyObject *meth_KStartupInfoData_pids(PyObject
*sipSelf,PyObject *sipArgs)
 48622  {
 48623          int sipArgsParsed = 0;
 48624
 48625          {
 48626                  KStartupInfoData *sipCpp;
 48627
 48628                  if
(sipParseArgs(&sipArgsParsed,sipArgs,"m",sipSelf,sipClass_KStartupInfoData,&sipCpp))
 48629                  {
 48630                          const QValueList<int> *sipRes;
 48631
 48632                          // sipRes = &sipCpp ->
KStartupInfoData::pids();
 48633                          sipRes = reinterpret_cast<const
QValueList<int> *>( &sipCpp -> KStartupInfoData::pids() );
 48634
 48635                          PyObject *sipResObj =
sipConvertFrom_QValueList_1800(const_cast<QValueList<int> *>(sipRes));
 48636
 48637                          return sipResObj;
 48638                  }
 48639          }
...
</sipkdecorepart0.cpp>

5.build


Detailed problems & solutions:
==============================
Trying a naive out-of-the-box compile I ran into the following problems:

sip-4.1.1:
----------
Compiled just fine, no difficulties.

PyQt-x11-gpl-3.13:
------------------
Compiles fine, but trying an example fails:

PyQt examples:
$ PYTHONPATH=../../build/lib/python2.3/site-packages/ python2.3 gears..py
Traceback (most recent call last):
  File "gears.py", line 6, in ?
    from qt import *
ImportError: ld.so.1: python2.3: fatal: relocation error: file
/data/pydev/DOWNLOADS/PYQTKDE/versions/20050302/build/lib/python2.3/site-packages/qt.so:
 symbol truncate64__7QStringUi: referenced symbol not found
???
$ c++filt truncate64__7QStringUi
QString::truncate64(unsigned int)

The reason for this is some bogus Solaris system headers.
My python is compiled with largefile support:
<pyconfig.h>
...
/* This must be set to 64 on some systems to enable large file support. */
#define _FILE_OFFSET_BITS 64

/* Define on Linux to activate all library features */
#define _GNU_SOURCE 1

/* This must be defined on some systems to enable large file support. */
#define _LARGEFILE_SOURCE 1
...
</pyconfig.h>

The problem is that _FILE_OFFSET_BITS 64 causes
/usr/include/unistd.h to #define truncate to truncate64, which breaks the
above calls to QString member functions QString::truncate.

Solution:
You can either:
a) Modify the sip header file sip-4.1.1/siplib/sip.h:
$ diff sip-4.1.1/siplib/sip.h ./sip.h.UNDEF_TRUNC
21a22,28
> // Python.h includes unistd.h
> // POSIX large file support redefines truncate to truncate64
> // --> this would break all QString::truncate calls
> #ifdef truncate
> #undef truncate
> #endif

(I think you will run into yet another problem later on, when compiling
pykde
if you do this. The problem has the same reason, a bogus redefine of
connect to
__xnet_connect in sys/socket.h. Alternative b fixes both of these issues,
so that might be the better way to go.)


OR

b) add an extra define when configuring sip:
DEFINES+=__PRAGMA_REDEFINE_EXTNAME
e.g.
${PYTHON} configure.py -b ${SIP_BINDIR} -d ${SIP_LIBDIR} -e
${SIP_INCLUDEDIR} \
                   -l qt-mt -v ${SIP_DIR/share} \
                   RPATH+=${RPATH} \
                   DEFINES+=__PRAGMA_REDEFINE_EXTNAME
would be how I call sip´s configure.py in my custom build script.

Do not forget to rebuild & reinstall sip afterwards!

Note: I am not sure about any side effects of these suggested solutions..
It took me quite some time to find b) and documentation is sparse (or my
lack
of understanding too big :-)
I went for b), so far I have seen no problems.

PyKDE-3.11.3:
-------------

To make it compile I had to:
1. Apply a "patch" to PyKDE I found on the mailing list which adds support
for
KDE 3.3.2 (by using the 3.3.0 stuff):

    for i in `find | grep kde330 | grep diff`; do
        echo $i
        mv -f $i `echo $i | sed 's/330/332/'`
    done
2. Change sip-4.1.1/sipgen/gencode.c to use C-style casts instead of static
casts:
<gencode.c>
...
 4002                                  else if (res -> atype == enum_type
&& isProtectedEnum(res -> u.ed))
 4003                                  {
 4004
//prcode(fp,"static_cast<%E>(",res -> u.ed);
 4005                                          // C-style cast
 4006                                          prcode(fp,"(%E) (",res ->
u.ed);
 4007                                          incast = TRUE;
 4008                                  }
...
</gencode.c>

Rebuild & reinstall sip!

3. After generating the pykde C++ sources, I had to manually change
PyKDE-3.11.3/kdecore/sipkdecorepart0.cpp.
Line numbers might differ for you (?), but the relevant function is
meth_KStartupInfoData_pids:

<sipkdecorepart0.cpp>
...
48621  static PyObject *meth_KStartupInfoData_pids(PyObject
*sipSelf,PyObject *sipArgs)
 48622  {
 48623          int sipArgsParsed = 0;
 48624
 48625          {
 48626                  KStartupInfoData *sipCpp;
 48627
 48628                  if
(sipParseArgs(&sipArgsParsed,sipArgs,"m",sipSelf,sipClass_KStartupInfoData,&sipCpp))
 48629                  {
 48630                          const QValueList<int> *sipRes;
 48631
 48632                          // sipRes = &sipCpp ->
KStartupInfoData::pids();
 48633                          sipRes = reinterpret_cast<const
QValueList<int> *>( &sipCpp -> KStartupInfoData::pids() );
 48634
 48635                          PyObject *sipResObj =
sipConvertFrom_QValueList_1800(const_cast<QValueList<int> *>(sipRes));
 48636
 48637                          return sipResObj;
 48638                  }
 48639          }
...
</sipkdecorepart0.cpp>

This is necessary because
-pid_t is typedef´d to long on my machine (but PyKDE typedefs it to int)
-sizeof(int)==sizeof(long) for 32bit builds
-QValueList<long> is not defined in PyQt-x11-gpl-3.13/sip/qt/qvaluelist..sip
(I tried that also, simply copying the QValueList<int> code and removing
some
of the now unnecessary casts, but was not successful. Must have missed
s.th. else...)

B.t.w.: Should be addressed in the latest PyKDE snapshot 20050301 announced
by Jim Bublitz,
but it is not up on riverbankcomputing.co.uk until now (?)

After these steps I could compile, but running a test application failed at
this position:
>>> import kdefx
dlopen("/data/pydev/DOWNLOADS/PYQTKDE/versions/20050228/build/lib/python2.3/site-packages/kdefx.so",
 2);
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ImportError: ld.so.1: python2.3: fatal: relocation error: file
/data/pydev/DOWNLOADS/PYQTKDE/versions/20050228/build/lib/python2.3/site-packages/kdefx.so:
 symbol _._4KURL: referenced symbol not found

For some reason kdefx needs to additionally link libkdecore.so.
I modified pykde configure.py to force this:
<configure.py>
...
   664  #    if extra_lib not in ["kfile"] and extra_lib:
   665      makefile.extra_libs.append(extra_lib)
   666
   667      # Hm, have to link libkdecore.so for kdefx, otherwise:
   668      #  kdefx.so: symbol _._4KURL: referenced symbol not found
   669      # c++filt _._4KURL --> KURL::~KURL(void)
   670      if extra_lib == "kdefx":
   671          makefile.extra_libs.append("kdecore")
   672
...
</configure.py>

Reconfigured, Recompiled, modified the generated sipkdecorepart0.cpp again
and voila, everything is fine.

After a closer look at the build system I still wonder if it is possible to
set certain build
options for pykde (or pyqt) specifically. It seems that all the extra
build_macros can only be
set for sip (and will then be reused by pyqt/pykde). But I do not want
libkdecore.so as extra
library for everything, so I did not see another way than modifying pykde´s
configure.py



Der Inhalt dieser E-Mail ist vertraulich. Falls Sie nicht der angegebene
Empfänger sind oder falls diese E-Mail irrtümlich an Sie adressiert wurde,
verständigen Sie bitte den Absender sofort und löschen Sie die E-Mail
sodann. Das unerlaubte Kopieren sowie die unbefugte Übermittlung sind nicht
gestattet. Die Sicherheit von Übermittlungen per E-Mail kann nicht
garantiert werden. Falls Sie eine Bestätigung wünschen, fordern Sie bitte
den Inhalt der E-Mail als Hardcopy an.

The contents of this  e-mail are confidential. If you are not the named
addressee or if this transmission has been addressed to you in error,
please notify the sender immediately and then delete this e-mail.  Any
unauthorized copying and transmission is forbidden. E-Mail transmission
cannot be guaranteed to be secure. If verification is required, please
request a hard copy version.



More information about the PyKDE mailing list