[KDE/Mac] QStandardPaths possible solution

Jeremy Whiting jpwhiting at kde.org
Fri Jan 9 02:54:54 UTC 2015


Ok, with the attached patch I think it should include XDG_CONFIG_DIRS and
XDG_DATA_DIRS for the GenericConfigLocation|ConfigLocation and
GenericDataLocation respectively. However when I try to build qt 5.4 branch
with this patch here I get a link error when it's trying to link moc.

cd tools/rcc/ && ( test -e Makefile ||
/Users/jeremy/devel/kde/src/qt5build/qtbase/bin/qmake
/Users/jeremy/devel/kde/src/qt5/qtbase/src/tools/rcc/rcc.pro -o Makefile )
&& /Applications/Xcode.app/Contents/Developer/usr/bin/make -f Makefile

cd tools/moc/ && ( test -e Makefile ||
/Users/jeremy/devel/kde/src/qt5build/qtbase/bin/qmake
/Users/jeremy/devel/kde/src/qt5/qtbase/src/tools/moc/moc.pro -o Makefile )
&& /Applications/Xcode.app/Contents/Developer/usr/bin/make -f Makefile

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-headerpad_max_install_names -Wl,-dead_strip
-Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk
-stdlib=libc++ -mmacosx-version-min=10.7 -o ../../../bin/rcc .obj/rcc.o
.obj/main.o   -L/opt/local/lib
-L/Users/jeremy/devel/kde/src/qt5build/qtbase/lib -lQt5Bootstrap -framework
CoreServices -framework Foundation -lz

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-headerpad_max_install_names -Wl,-dead_strip
-Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk
-stdlib=libc++ -mmacosx-version-min=10.7 -o ../../../bin/moc .obj/moc.o
.obj/preprocessor.o .obj/generator.o .obj/parser.o .obj/token.o .obj/main.o
  -L/opt/local/lib -L/Users/jeremy/devel/kde/src/qt5build/qtbase/lib
-lQt5Bootstrap -framework CoreServices -framework Foundation -lz

Undefined symbols for architecture x86_64:

  "QLibraryInfo::location(QLibraryInfo::LibraryLocation)", referenced from:

      QStandardPaths::standardLocations(QStandardPaths::StandardLocation)
in libQt5Bootstrap.a(qstandardpaths_mac.o)

      xdgDataDirs() in libQt5Bootstrap.a(qstandardpaths_mac.o)

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see
invocation)

Undefined symbols for architecture x86_64:

  "QLibraryInfo::location(QLibraryInfo::LibraryLocation)", referenced from:

      QStandardPaths::standardLocations(QStandardPaths::StandardLocation)
in libQt5Bootstrap.a(qstandardpaths_mac.o)

      xdgDataDirs() in libQt5Bootstrap.a(qstandardpaths_mac.o)

make[3]: *** [../../../bin/rcc] Error 1

make[2]: *** [sub-rcc-make_first] Error 2

make[2]: *** Waiting for unfinished jobs....

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see
invocation)

make[3]: *** [../../../bin/moc] Error 1

make[2]: *** [sub-moc-make_first] Error 2

make[1]: *** [sub-src-make_first] Error 2

make: *** [module-qtbase-make_first] Error 2


Which confuses me because both QLibraryInfo and QStandardPaths are in
QtCore module. Any ideas how to solve that?


BR,

Jeremy

On Thu, Jan 8, 2015 at 6:44 PM, Marko Käning <mk-lists at email.de> wrote:

> Jeremy,
>
> On 09 Jan 2015, at 01:29 , David Faure <faure at kde.org> wrote:
>
> > On Friday 09 January 2015 00:05:28 Marko Käning wrote:
> >>> PS: the last patch I saw didn't use XDG_CONFIG_DIRS, don't you want
> that
> >>> as  well?
> >>
> >> We don’t need this for the CI system, which is why Jeremy did not
> include it
> >> in  the current QSP patch. But it is no problem to re-insert the code
> from
> >> my older QSP patch, if you think we should go for this right way.
> >
> > I think it would be pretty inconsistent to support one and not the other
> - and
> > the CI doesn't test everything ;) some apps won't find their installed
> config
> > files (for the few that do pre-install something), without this in QSP.
>
> will you include this code in your to-be-submitted patch:
> ---
>     // http://standards.freedesktop.org/basedir-spec/latest/
>     const QString xdgConfigDirs =
> QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));
>
>     switch (type) {
>     case ConfigLocation:
>     case GenericConfigLocation:
>         if (!xdgConfigDirs.isEmpty())
>             dirs = xdgConfigDirs.split(QLatin1Char(':'));
>         break;
> ---
> for QStandardPaths::standardLocations(StandardLocation type)!
>
> Sorry, there it is again, my switch statement. :)
>
> Thanks,
> Marko
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kde-mac/attachments/20150108/71aa3d7c/attachment-0001.html>
-------------- next part --------------
diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm
index 01d1c01..90bb5b6 100644
--- a/src/corelib/io/qstandardpaths_mac.mm
+++ b/src/corelib/io/qstandardpaths_mac.mm
@@ -33,6 +33,7 @@
 
 #include "qstandardpaths.h"
 #include <qdir.h>
+#include <qlibraryinfo.h>
 #include <qurl.h>
 #include <private/qcore_mac_p.h>
 
@@ -177,6 +178,56 @@ QString QStandardPaths::writableLocation(StandardLocation type)
     }
 }
 
+static void normalizeDirs(QStringList &dirs) {
+    // Normalize paths, skip relative paths
+    QMutableListIterator<QString> it(dirs);
+    while (it.hasNext()) {
+        const QString dir = it.next();
+        if (!dir.startsWith(QLatin1Char('/')))
+            it.remove();
+        else
+            it.setValue(QDir::cleanPath(dir));
+    }
+
+    // Remove duplicates from the list, there's no use for duplicated
+    // paths in XDG_CONFIG_DIRS - if it's not found in the given
+    // directory the first time, it won't be there the second time.
+    // Plus duplicate paths causes problems for example for mimetypes,
+    // where duplicate paths here lead to duplicated mime types returned
+    // for a file, eg "text/plain,text/plain" instead of "text/plain"
+    dirs.removeDuplicates();
+}
+
+static QStringList xdgConfigDirs()
+{
+    QStringList dirs;
+    // http://standards.freedesktop.org/basedir-spec/latest/
+    QString xdgConfigDirsEnv = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));
+    if (xdgConfigDirsEnv.isEmpty()) {
+        dirs.append(QLibraryInfo::location(QLibraryInfo::PrefixPath) + QString::fromLatin1("/config"));
+    } else {
+        dirs = xdgConfigDirsEnv.split(QLatin1Char(':'), QString::SkipEmptyParts);
+
+        normalizeDirs(dirs);
+    }
+    return dirs;
+}
+
+static QStringList xdgDataDirs()
+{
+    QStringList dirs;
+    // http://standards.freedesktop.org/basedir-spec/latest/
+    QString xdgDataDirsEnv = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
+    if (xdgDataDirsEnv.isEmpty()) {
+        dirs.append(QLibraryInfo::location(QLibraryInfo::PrefixPath) + QString::fromLatin1("/share"));
+    } else {
+        dirs = xdgDataDirsEnv.split(QLatin1Char(':'), QString::SkipEmptyParts);
+
+        normalizeDirs(dirs);
+    }
+    return dirs;
+}
+
 QStringList QStandardPaths::standardLocations(StandardLocation type)
 {
     QStringList dirs;
@@ -187,7 +238,18 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
             dirs.append(path);
     }
 
+    if (type == GenericDataLocation)
+        dirs.append(xdgDataDirs());
+
+    if (type == GenericConfigLocation || type == ConfigLocation)
+        dirs.append(xdgConfigDirs());
+
     if (type == AppDataLocation || type == AppLocalDataLocation) {
+        QStringList xdgDirs = xdgDataDirs();
+        for (int i = 0; i < xdgDirs.count(); ++i)
+            appendOrganizationAndApp(xdgDirs[i]);
+        dirs.append(xdgDirs);
+
         CFBundleRef mainBundle = CFBundleGetMainBundle();
         if (mainBundle) {
             CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle);


More information about the kde-mac mailing list