[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