Bug#760535: Experimental qgis FTBS on armel and armhf due to Qreal issue

peter green plugwash-urgent at p10link.net
Fri Sep 5 02:22:51 UTC 2014


Package: qgis
Version: 2.4.0-1~exp1
Severity: important
X-debbugs-cc: rossgammon at mail.dk

Ross Gammon wrote:
> Hi Peter,
>
> I am working in the Debian GIS Team and I am hoping you can help me with
> a build failure on arm*:
>   
                                             ^
>(without having any detailed knowledge of the issue)

The issue is that on arm platforms with qt4 qreal is defined as float 
rather than double. You can safely assign between qreal and double 
because you can safely assign between float and double but more complex 
cases involving templates or pointers can give problems.

Since there is a lot of analysis in this message i'm turning this into a 
bug report so it doesn't get lost.
> /«PKGBUILDDIR»/src/gui/qgscomposerview.cpp: In member function 'virtual
> void QgsComposerView::mouseReleaseEvent(QMouseEvent*)':
> /«PKGBUILDDIR»/src/gui/qgscomposerview.cpp:872:189: error: no matching
> function for call to 'qMax(qreal, double)'
>          newTable->setSceneRect( QRectF(
> mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(),
> mRubberBandItem->rect().width(), qMax( mRubberBandItem->rect().height(),
> 15.0 ) ) );
>
>
>                                              ^
> /«PKGBUILDDIR»/src/gui/qgscomposerview.cpp:872:189: note: candidate is:
> In file included from /usr/include/qt4/QtCore/qnamespace.h:45:0,
>                  from /usr/include/qt4/QtCore/qobjectdefs.h:45,
>                  from /usr/include/qt4/QtCore/qobject.h:47,
>                  from /usr/include/qt4/QtCore/qcoreapplication.h:45,
>                  from /usr/include/qt4/QtGui/qapplication.h:45,
>                  from /usr/include/qt4/QtGui/QApplication:1,
>                  from /«PKGBUILDDIR»/src/gui/qgscomposerview.cpp:18:
> /usr/include/qt4/QtCore/qglobal.h:1219:34: note: template<class T> const
> T& qMax(const T&, const T&)
>  Q_DECL_CONSTEXPR inline const T &qMax(const T &a, const T &b) { return
> (a < b) ? b : a; }
>                                   ^
> /usr/include/qt4/QtCore/qglobal.h:1219:34: note:   template argument
> deduction/substitution failed:
> /«PKGBUILDDIR»/src/gui/qgscomposerview.cpp:872:189: note:   deduced
> conflicting types for parameter 'const T' ('float' and 'double')
>          newTable->setSceneRect( QRectF(
> mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(),
> mRubberBandItem->rect().width(), qMax( mRubberBandItem->rect().height(),
> 15.0 ) ) );
>   
In this case qMax is a template. The result is it will work with 
arguments of any numeric type but the two arguments must be the same 
type. The literal 12.0 is type double. So on a platform where qreal is 
float qMax gets passed one float and one double and the compiler can't 
decide which to use for the template parameter and errors out. Easy 
enough to fix by casting the literal to qreal.


Unfortunately after fixing that the buidl fails later with
[ 94%] Generating analysis/sip_analysispart0.cpp, 
analysis/sip_analysispart1.cpp, analysis/sip_analysispart2.cpp, 
analysis/sip_analysispart3.cpp
cd /qgis-2.4.0/obj-arm-linux-gnueabihf/python && /usr/bin/cmake -E echo

cd /qgis-2.4.0/obj-arm-linux-gnueabihf/python && /usr/bin/cmake -E touch 
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/analysis/sip_analysispart0.cpp 
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/analysis/sip_analysispart1.cpp 
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/analysis/sip_analysispart2.cpp 
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/analysis/sip_analysispart3.cpp
cd /qgis-2.4.0/obj-arm-linux-gnueabihf/python && /usr/bin/sip -w -e -x 
ANDROID -x HAVE_TOUCH -x MOBILITY_LOCATION -x QSETINT_CONVERSION -x 
QSETTYPE_CONVERSION -x VendorID -t WS_X11 -x PyQt_NoPrintRangeBug -x 
PyQt_qreal_double -t Qt_4_8_6 -x Py_v3 -g -o -a 
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/qgis.analysis.api -j 4 -c 
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/analysis -I 
/usr/share/sip/PyQt4 -I /qgis-2.4.0/python 
/qgis-2.4.0/python/analysis/analysis.sip
sip: /qgis-2.4.0/python/core/composer/qgsatlascomposition.sip:165: 
QgsAtlasComposition::predefinedScales() unsupported function return type 
- provide %MethodCode and a C++ signature
python/CMakeFiles/python_module_qgis__analysis.dir/build.make:305: 
recipe for target 'python/analysis/sip_analysispart0.cpp' failed
make[4]: *** [python/analysis/sip_analysispart0.cpp] Error 1
make[4]: Leaving directory '/qgis-2.4.0/obj-arm-linux-gnueabihf'
CMakeFiles/Makefile2:3415: recipe for target 
'python/CMakeFiles/python_module_qgis__analysis.dir/all' failed
make[3]: *** [python/CMakeFiles/python_module_qgis__analysis.dir/all] 
Error 2

I changed double to qreal in the .sip file in a couple of places and 
that made the file build but I wasn't sure if it was a correct fix or 
not. In particular I wasn't sure if there is some  corresponding peice 
of native code that needs to be changed to match.

Then it failed with

/qgis-2.4.0/obj-arm-linux-gnueabihf/python/core/sip_corepart2.cpp:12735:67: 
error: no matching function for call to 'QVector<float>::QVector(const 
QVector<double>&)'
                 sipRaiseUnknownException();
                                                                   ^
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/core/sip_corepart2.cpp:12735:67: 
note: candidates are:
In file included from /usr/include/qt4/QtGui/qbrush.h:47:0,
                 from /usr/include/qt4/QtGui/qgraphicseffect.h:49,
                 from /usr/include/qt4/QtGui/QGraphicsEffect:1,
                 from 
/qgis-2.4.0/python/../src/core/composer/qgscomposereffect.h:21,
                 from 
/qgis-2.4.0/python/../src/core/composer/qgscomposeritem.h:21,
                 from 
/qgis-2.4.0/python/../src/core/composer/qgspaperitem.h:21,
                 from /qgis-2.4.0/python/core/composer/qgspaperitem.sip:21:
/usr/include/qt4/QtCore/qvector.h:123:12: note: 
QVector<T>::QVector(const QVector<T>&) [with T = float]
     inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if 
(!d->sharable) detach_helper(); }
            ^
/usr/include/qt4/QtCore/qvector.h:123:12: note:   no known conversion 
for argument 1 from 'const QVector<double>' to 'const QVector<float>&'
/usr/include/qt4/QtCore/qvector.h:429:1: note: QVector<T>::QVector(int, 
const T&) [with T = float]
 QVector<T>::QVector(int asize, const T &t)
 ^
/usr/include/qt4/QtCore/qvector.h:429:1: note:   candidate expects 2 
arguments, 1 provided
/usr/include/qt4/QtCore/qvector.h:411:1: note: QVector<T>::QVector(int) 
[with T = float]
 QVector<T>::QVector(int asize)
 ^
/usr/include/qt4/QtCore/qvector.h:411:1: note:   no known conversion for 
argument 1 from 'const QVector<double>' to 'int'
/usr/include/qt4/QtCore/qvector.h:120:12: note: QVector<T>::QVector() 
[with T = float]
     inline QVector() : d(&QVectorData::shared_null) { d->ref.ref(); }
            ^
/usr/include/qt4/QtCore/qvector.h:120:12: note:   candidate expects 0 
arguments, 1 provided
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/core/sip_corepart2.cpp: In 
function 'PyObject* 
meth_QgsAtlasComposition_setPredefinedScales(PyObject*, PyObject*)':
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/core/sip_corepart2.cpp:12774:44: 
error: no matching function for call to 
'QgsAtlasComposition::setPredefinedScales(const QVector<float>&)'
             sipReleaseType(const_cast<QVector<qreal> 
*>(a0),sipType_QVector_2200,a0State);
                                            ^
/qgis-2.4.0/obj-arm-linux-gnueabihf/python/core/sip_corepart2.cpp:12774:44: 
note: candidate is:
In file included from 
/qgis-2.4.0/python/../src/core/composer/qgscomposition.h:34:0,
                 from 
/qgis-2.4.0/python/core/composer/qgscomposition.sip:10:
/qgis-2.4.0/python/../src/core/composer/qgsatlascomposition.h:194:10: 
note: void QgsAtlasComposition::setPredefinedScales(const QVector<double>&)
     void setPredefinedScales( const QVector<double>& scales );
          ^
/qgis-2.4.0/python/../src/core/composer/qgsatlascomposition.h:194:10: 
note:   no known conversion for argument 1 from 'const QVector<float>' 
to 'const QVector<double>&'
python/CMakeFiles/python_module_qgis__core.dir/build.make:330: recipe 
for target 
'python/CMakeFiles/python_module_qgis__core.dir/core/sip_corepart2.cpp.o' 
failed
make[4]: *** 
[python/CMakeFiles/python_module_qgis__core.dir/core/sip_corepart2.cpp.o] 
Error 1

So it seems the .sip file is used to generate native code and the types 
in the native code generated from the sip file not matching the types 
used in the native code caused a build failure.

I attempted to fix this by adding versions of the getter and setter that 
took a QVector<float> and performed conversions but then found that was 
not possible due to C++ not allowing overloading based on return type. 
So I decided to try outright changing the type to qreal, fortunately it 
looks like the API in question is totally new in 2.4 so this shouldn't 
break too much third party stuff. There were some knockon impacts within 
the qgis source but nothing massive.

My changes make the package build but I would certainly want to discuss 
it with upstream before applying to check that the lower precision isn't 
likely to be a problem (or at least not any more of a problem than it 
already is in other places), to check if upstream can think of any other 
knockon impacts the change might have and also because if upstream 
decides to fix it in a different way (e.g. by finding some way to make 
sip accept qvector<double> on arm) it could leave us ABI-incompatible 
with upstream.

Debdiff attatched, no intent to NMU and as I stated above I would 
strongly advise discussion with upstream before uploading.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qgis.debdiff
URL: <http://lists.alioth.debian.org/pipermail/pkg-grass-devel/attachments/20140905/cf817925/attachment.ksh>


More information about the Pkg-grass-devel mailing list