[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