[Soprano] 7e84700 Soprano cannot define qHash(const QUrl &) after Qt
Thiago Macieira
thiago at kde.org
Tue Oct 26 13:02:35 BST 2010
A soprano/qhashqurlcompat.cpp [License: LGPL(v2)]
commit 7e84700178eb3463f6efbaabd55ca3471bd440de
Author: Thiago Macieira <thiago at kde.org>
Date: Tue Jan 12 18:58:46 2010 +0000
Soprano cannot define qHash(const QUrl &) after Qt 4.7.
Qt 4.7 will come with its own hashing function for QUrl. If Soprano
continues to define such a function, compilation errors will occur.
This is technically a binary incompatible change. However, I have
taken steps to minimise the issue. Most users will not see a problem,
but it could happen:
1) on non-ELF platforms (Mac and Windows), 'uint qHash(const QUrl &)'
is defined in a different library, so applications will need to be
relinked. However, Windows allows for the same symbol to be present
in many libraries, so we'll just define it in both Qt and Soprano.
For Mac users, this is a fully binary-incompatible change. I don't
see a way around the issue.
2) The hashing function is different from what Soprano is currently
using. I have added the functionality to Qt 4.6 as private API to
ease transition, but this requires recompiling Soprano with Qt
4.6.2 or later for it to kick in.
This is a runtime-incompatibility issue,
This affects any public API with QHash<QUrl, T>. Scanning KDE for
uses of QHash<QUrl, T> revealed only one public API, in
kdelibs/nepomuk/core/resource.h.
Any users of that API need to agree on the hashing function. That
means Soprano MUST have been recompiled with Qt 4.6.2 everywhere
before Nepomuk-using code sarts getting compiled with Qt 4.7.
Sorry, but this is Soprano's fault for defining qHash for a Qt
type. This should have been caught earlier.
CCMAIL:kde-core-devel at kde.org
svn path=/trunk/kdesupport/soprano/; revision=1073734
diff --git a/soprano/CMakeLists.txt b/soprano/CMakeLists.txt
index d4a432f..4f387b1 100644
--- a/soprano/CMakeLists.txt
+++ b/soprano/CMakeLists.txt
@@ -35,6 +35,7 @@ set(soprano_SRCS
pluginmanager.cpp
pluginstub.cpp
plugin.cpp
+ qhashqurlcompat.cpp
backend.cpp
backend.h
global.cpp
diff --git a/soprano/node.cpp b/soprano/node.cpp
index c53d23b..65c4a06 100644
--- a/soprano/node.cpp
+++ b/soprano/node.cpp
@@ -484,8 +484,16 @@ uint Soprano::qHash( const Soprano::Node& node )
}
-uint qHash( const QUrl& url )
-{
- // implementation taken from KUrl by David Faure
- return qHash(url.scheme()) ^ qHash(url.path()) ^ qHash(url.fragment()) ^ qHash(url.encodedQuery());
+namespace Soprano {
+ // see qhashqurlcompat.cpp
+ uint soprano_qHash_QUrl(const QUrl &url)
+ {
+#if QT_VERSION < 0x040602
+ // implementation taken from KUrl by David Faure
+ return qHash(url.scheme()) ^ qHash(url.path()) ^ qHash(url.fragment()) ^ qHash(url.encodedQuery());
+#else
+ // implementation from Qt 4.7 to ease transition
+ return qHash(url.toEncoded(QUrl::FormattingOption(0x100)));
+#endif
+ }
}
diff --git a/soprano/node.h b/soprano/node.h
index 89e8824..1695bc2 100644
--- a/soprano/node.h
+++ b/soprano/node.h
@@ -464,6 +464,8 @@ SOPRANO_EXPORT QDebug operator<<( QDebug s, const Soprano::Node& );
*/
SOPRANO_EXPORT QTextStream& operator<<( QTextStream& s, const Soprano::Node& );
+#if QT_VERSION < 0x040700
SOPRANO_EXPORT uint qHash( const QUrl& url );
+#endif
#endif // SOPRANO_NODE_H
diff --git a/soprano/qhashqurlcompat.cpp b/soprano/qhashqurlcompat.cpp
new file mode 100644
index 0000000..6b7dd78
--- /dev/null
+++ b/soprano/qhashqurlcompat.cpp
@@ -0,0 +1,54 @@
+/*
+ * This file is part of Soprano Project
+ *
+ * Copyright (C) 2010 Thiago Macieira <thiago at kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This file is a most ugly hack.
+ *
+ * Soprano defined 'uint qHash(const QUrl &)' as public API and
+ * exported it from its library. Since Qt 4.7, Qt will provide its own
+ * hashing function.
+ *
+ * To avoid breaking binary compatibility, this file defines the
+ * function again and does the same as the Qt 4.7 code does.
+ *
+ * We cannot define the function on Mac OS X because its file format
+ * does not allow for duplicated symbols. All other platforms allow
+ * for duplication.
+ *
+ * Unfortunately, we can't #include <QUrl> because that would cause a
+ * compilation error. So we need to divert to a separate .cpp that
+ * implements the actual call (see the bottom of node.cpp).
+ */
+
+#include "soprano_export.h"
+class QUrl;
+
+SOPRANO_EXPORT uint qHash(const QUrl &);
+namespace Soprano {
+ uint soprano_qHash_QUrl(const QUrl &);
+}
+
+#if !(defined(Q_OS_MACX) && QT_VERSION >= 0x040700)
+uint qHash(const QUrl &url)
+{
+ return Soprano::soprano_qHash_QUrl(url);
+}
+#endif
More information about the kde-core-devel
mailing list