[KDE/Mac] [OS X] adding a link module to all KF5 targets

David Faure faure at kde.org
Thu Sep 24 20:56:37 UTC 2015

[warning: long, and I change my mind mid-way; I left it all so you can follow my reasoning]

On Thursday 24 September 2015 05:44:18 Jeremy Whiting wrote:
> That does sound like a bit more interesting question. Browsing through
> http://lxr.kde.org/ident?_i=QStandardPaths&_remember=1 (quite a long
> list...) a couple of things come to mind. First anything that's using
> QStandardPaths isn't necessarily using any frameworks at all. Looking
> at http://agateau.com/2013/kf5-diagrams/kf5.png (which admittedly may
> not be up to date either) it seems KCoreAddons is a very commonly used
> framework. Also depended on by many other frameworks and used by many
> applications. It contains KAboutData which is used by pretty much any
> GUI application that we release, I'm not sure if it matters if it
> needs to be used by command-line tools also or not. I'm not sure how
> many if any command line tools or system daemons etc. are using
> QStandardPaths. Maybe try with KCoreAddons and see if that's a
> suitable enough place?

Right, I was going to suggest that too.

If you're really only thinking of apps made by the KDE community, I would be
surprised to see any one of them not linking to kcoreaddons.

I want to stay on record saying that this goes against the modularity principle
of KF5 for other applications, of course. If someone wants to only use KItemModels,
they should be able to do just that. But in this context that's fine, this would likely
not be an app from the KDE community (which is expected to integrate with others)
but more likely an external, more standalone app.

So OK, kcoreaddons could switch QSP behavior on Mac, provided that
it's documented with a huge warning, and that it can be turned off. It breaks
the principle of least surprise ("ever since my app started using one tiny
unrelated class out of KF5, my users lost all their previous configuration!").

In addition to that, we should still make sure that KF5 frameworks work with
the default Apple-conformant QSP (either because they don't link to KCoreAddons,
or because someone turned off the QSP-switching), but I totally understand if you want to
leave that to somebody else (to each man his own battle).

Now, if a global object in kcoreaddons switches QSP behavior, how can someone
turn that off? It's a bit tricky because another global object in the app could be constructed
before or after the one in kcoreaddons (unless there's a spec that ensures it happens
in libs before apps? I'm no expert on this, I only know order of construction is undefined
within a given library at least).

In details, my idea would be:
KCoreAddons has in a cpp file: Q_CONSTRUCTOR_FUNCTION(func1) where func1 switches QSP to XDG mode.
If an app doesn't want that: Q_CONSTRUCTOR_FUNCTION(func2) where func2 switches QSP path to OSX mode.
If it's guaranteed that the ctor func in the app runs last we're fine. Otherwise we need a tristate logic
(default, forcedToXDG, forcedToOSX) where kcoreaddons would say "switch to xdg unless forced to OSX").
Any OSX linker experts around? :)

The advantage of this solution compared to your initial question: no build system hackery
(which would break the principle of least surprise even more, I would say).

One thing I like about this, as a side effect, is that my unittests which need to
have control over *global* QSP paths (which I do by setting XDG_DATA_DIRS
but I have to skip such unittests on OSX/Windows) could then be enabled on OSX.
But of course I would also solve that by adding setters to QSP cross-platform...
I just always wanted to stay away from that because it only makes sense in tests.
Libs and apps would fight over it, if this was misused (one lib could make other libs
not able to find their stuff anymore, or apps would break libs, etc.). Which is kind
of the issue here with the global QSP mode, but at least it's a single setting to
fight over ;-)

.... which means the suggested solution here would break third-party libs which
installed stuff into default QSP paths, and then we toggle the mode to XDG, and they
can't find their stuff anymore...

Maybe this needs to be per-method-call then.... :
* if libA installs stuff into XDG paths, then it would find it using QSP::locate(type, filename, XDG)
* the alternative would be QSP::locate(type, filename, Native), which would be the default.
This seems more correct to me after all, no? Porting the KDE code would be just running
one perl script, don't worry about that part.

David Faure, faure at kde.org, http://www.davidfaure.fr
Working on KDE Frameworks 5

More information about the kde-mac mailing list