building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
Hi, A priori Qt guarantees that you can run binaries against a different, newer Qt version than they were built against, as long as no private APIs are used. This also works if that newer Qt version is installed elsewhere, provided you set LD_LIBRARY_PATH correctly (and possibly LD_PRELOAD). I think this also means you can build code against such a newer (test) Qt install even if that code uses libraries which were built against the older Qt version (as long as no mixups occur at runtime; I've done this successfully with code that uses Phonon, for instance). I'm not having a lot of luck building code that uses KF5 frameworks this way. Even after getting cmake to find the intended newer Qt version I still get header conflicts because something inserts unwanted header search paths. I don't expect there to be official support for this kind of tricky things. Still, testing code against a new Qt version installed in parallel doesn't seem to be such an usual thing to do so if there is a trick to this I'd love to hear it. Is there a way to insert a `-isystem /path/to/new/qt/include` BEFORE the `-isystem /path/to/system/qt/include` that gets added by cmake, for instance? Thanks, R.
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Saturday, April 25, 2020 2:23:34 PM CEST René J.V. Bertin wrote: > Hi, > > A priori Qt guarantees that you can run binaries against a different, newer > Qt version than they were built against, as long as no private APIs are > used. This also works if that newer Qt version is installed elsewhere, > provided you set LD_LIBRARY_PATH correctly Yes. > (and possibly LD_PRELOAD). I don't see why you would set LD_PRELOAD in this configuration. > I think this also means you can build code against such a newer (test) Qt > install even if that code uses libraries which were built against the older > Qt version (as long as no mixups occur at runtime; I've done this > successfully with code that uses Phonon, for instance). Yes when Qt itself is upgraded to a newer version. Switching between two Qt prefixes at cmake time is another issue though, which seems to be what you're experiencing. > I'm not having a lot of luck building code that uses KF5 frameworks this > way. Even after getting cmake to find the intended newer Qt version I still > get header conflicts because something inserts unwanted header search > paths. I think this is because the KF5 target brings its own include paths as part of the imported target. > I don't expect there to be official support for this kind of tricky things. > Still, testing code against a new Qt version installed in parallel doesn't > seem to be such an usual thing to do so if there is a trick to this I'd > love to hear it. Build against the old Qt, run against the new Qt? Then it's back to "only" LD_LIBRARY_PATH switcheroo which works well, while at the buildsystem level it's all based upon the old Qt so no mixup there. -- David Faure, fa...@kde.org, http://www.davidfaure.fr Working on KDE Frameworks 5
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday April 26 2020 14:12:01 David Faure wrote: >> (and possibly LD_PRELOAD). > >I don't see why you would set LD_PRELOAD in this configuration. This may be necessary if even one of the multiple libraries that get loaded has an old-style link to a Qt library which makes it ignore LD_LIBRARY_PATH. I've seen that with libQt5QtCore (and also with libdbus). >I think this is because the KF5 target brings its own include paths as part of >the imported target. Probably, yes. And that's enough to stop the build I was attempting, so I cannot affirm nor infirm if something similar won't happen with linker paths. >Build against the old Qt, run against the new Qt? >Then it's back to "only" LD_LIBRARY_PATH switcheroo which works well, while at >the buildsystem level it's all based upon the old Qt so no mixup there. Yeah, except that then you can't test those #if QT_VERSION hacks... Talking about version test hacks (or not-so-hacks): why is it that KFOO_VERSION isn't defined systematically when you include any header of the FOO KF5 framework? With Qt you never have to worry about QT_VERSION being defined. This would be less of an issue if -Wundef was part of -Wall (or if IDE parsers always flagged undefined macros used in a preprocessor expression that isn't a simple #ifdef (or #if defined)... R.
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday, April 26, 2020 3:21:34 PM CEST René J.V. Bertin wrote: > On Sunday April 26 2020 14:12:01 David Faure wrote: > >> (and possibly LD_PRELOAD). > > > >I don't see why you would set LD_PRELOAD in this configuration. > > This may be necessary if even one of the multiple libraries that get loaded > has an old-style link to a Qt library which makes it ignore > LD_LIBRARY_PATH. I've seen that with libQt5QtCore (and also with libdbus). This should only ever happen if RPATH is used instead of RUNPATH. I haven't seen this in 15 years or so. > >I think this is because the KF5 target brings its own include paths as part > >of the imported target. > > Probably, yes. And that's enough to stop the build I was attempting, so I > cannot affirm nor infirm if something similar won't happen with linker > paths. Right. Those are most likely full paths too. > >Build against the old Qt, run against the new Qt? > >Then it's back to "only" LD_LIBRARY_PATH switcheroo which works well, while > >at the buildsystem level it's all based upon the old Qt so no mixup there. > > Yeah, except that then you can't test those #if QT_VERSION hacks... Well, yeah, you can't have it all. Or, you can, but you need two full builds. > Talking about version test hacks (or not-so-hacks): why is it that > KFOO_VERSION isn't defined systematically when you include any header of > the FOO KF5 framework? With Qt you never have to worry about QT_VERSION > being defined. Well, everything in Qt ends up including global.h There's no such central header in KF5 frameworks (which are more modular, by definition), so you need to include the framework_version.h header. > This would be less of an issue if -Wundef was part of -Wall > (or if IDE parsers always flagged undefined macros used in a preprocessor > expression that isn't a simple #ifdef (or #if defined)... We have -Wundef by default. extra-cmake-modules/kde-modules/KDECompilerSettings.cmake: 367:set(_KDE_GCC_COMMON_WARNING_FLAGS "-Wall -Wextra -Wcast-align -Wchar- subscripts -Wformat-security -Wno-long-long -Wpointer-arith -Wundef") -- David Faure, fa...@kde.org, http://www.davidfaure.fr Working on KDE Frameworks 5
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday April 26 2020 15:46:35 David Faure wrote: >Well, yeah, you can't have it all. I suppose that the appropriate ECM could provide a function that returns the path to the "official" Qt headers (or an expression that evaluates to that path) unless something like QT_HEADER_PATH is defined. Idem for linker paths. Of course then individual frameworks would still accept to use those functions. >Or, you can, but you need two full builds. Yeah, I don't think that what I was trying is important enough to warrant the investment that comes with having another build... >There's no such central header in KF5 frameworks (which are more modular, by >definition), so you need to include the framework_version.h header. Don't you think it'd make sense to expect the version to be defined if you include the KFoo header if framework Foo provides one (I count 17 that do, among the 60+ frameworks I installed)? As a side-note, I'd even argue that it would make sense to provide an all-inclusive header per framework, just like Apple's frameworks do. Allowing code to include only the exact few headers it needs is nice, but is there a reason to disallow code from doing the opposite if it wants to shorten the list of #includes? >We have -Wundef by default. Yes, in the compiler settings, which is why I caught the FOO_VERSION not defined thing purely by chance rather than because of unexpected behaviour at runtime. KDevelop doesn't include the flag in its options for the clang-based parser.
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday, April 26, 2020 4:32:46 PM CEST René J.V. Bertin wrote: > On Sunday April 26 2020 15:46:35 David Faure wrote: > >Well, yeah, you can't have it all. > > I suppose that the appropriate ECM could provide a function that returns the > path to the "official" Qt headers (or an expression that evaluates to that > path) unless something like QT_HEADER_PATH is defined. Idem for linker > paths. Of course then individual frameworks would still accept to use those > functions. None of that would work with imported targets. > >Or, you can, but you need two full builds. > > Yeah, I don't think that what I was trying is important enough to warrant > the investment that comes with having another build... Your choice. > >There's no such central header in KF5 frameworks (which are more modular, > >by definition), so you need to include the framework_version.h header. > > Don't you think it'd make sense to expect the version to be defined if you > include the KFoo header if framework Foo provides one (I count 17 that do, > among the 60+ frameworks I installed)? No. There's no "main header" concept. As you say, this would only work for 17/60 frameworks anyway, not really a good solution. > As a side-note, I'd even argue that > it would make sense to provide an all-inclusive header per framework, just > like Apple's frameworks do. It's said to improve compilation times with precompiled headers, but in practice nobody knows if the person compiling the code has that, so I fail to see the point. Who needs all of ? Nobody. > >We have -Wundef by default. > > Yes, in the compiler settings, which is why I caught the FOO_VERSION not > defined thing purely by chance rather than because of unexpected behaviour > at runtime. I wouldn't call this "purely by chance". I set -Wundef there for a reason :-) > KDevelop doesn't include the flag in its options for the > clang-based parser. OK, talk to the KDevelop people then :-) -- David Faure, fa...@kde.org, http://www.davidfaure.fr Working on KDE Frameworks 5
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday April 26 2020 16:58:10 David Faure wrote: >> As a side-note, I'd even argue that >> it would make sense to provide an all-inclusive header per framework, just >> like Apple's frameworks do. > >It's said to improve compilation times with precompiled headers, but in >practice nobody knows if the person compiling the code has that, so I fail to >see the point. The possibility to use precompiled headers is only an argument here when increased compilation times are brought up as an argument against such a header. But that's not really an argument if you can continue to use just the headers you need. (But FWIW, in my experience it's much more efficient to use ccache, possibly in combination with distcc.) >Who needs all of ? Nobody. I could just as well maintain that nobody needs any of that particular framework ;) But the question isn't who needs all of. People including or (better example) also rarely need all of those frameworks. It's just a convenience: no need to jump back and forth between your editing location and the file preamble (after deciding if you want the required additional header in the implementation file or in the corresponding header file), and no need to maintain a long list of include statements which ideally you should prune every time you stop using a certain class. (Just how often do people forget to remove the corresponding header?) I'm not saying that either approach is better - they both are, just for different people ;) >I wouldn't call this "purely by chance". I set -Wundef there for a reason :-) I still call me seeing the warning a pure chance given the fact it's there. The fact of me seeing it if it were not there would also be a pure chance ... hopefully close enough to 0 ;) Seriously, catching this among the very copious output of multiple concurrent compiler jobs echoing their incredibly long command lines to the terminal is really rather unlikely unless most files generate several of these warnings. >OK, talk to the KDevelop people then :-) Done! R.
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday, April 26, 2020 5:50:40 PM CEST René J.V. Bertin wrote: > On Sunday April 26 2020 16:58:10 David Faure wrote: > >> As a side-note, I'd even argue that > >> it would make sense to provide an all-inclusive header per framework, > >> just > >> like Apple's frameworks do. > > > >It's said to improve compilation times with precompiled headers, but in > >practice nobody knows if the person compiling the code has that, so I fail > >to see the point. > > The possibility to use precompiled headers is only an argument here when > increased compilation times are brought up as an argument against such a > header. But that's not really an argument if you can continue to use just > the headers you need. Well, then you never need all-inclusive headers. > >Who needs all of ? Nobody. > > I could just as well maintain that nobody needs any of that particular > framework ;) OK now you make no sense at all anymore, since I can give you 500 proofs of the contrary: actual pieces of code that use some parts of KCoreAddons, and none of them which use all of it. > But the question isn't who needs all of. People including > or (better example) also rarely > need all of those frameworks. It's just a convenience: no need to jump back > and forth between your editing location and the file preamble (after > deciding if you want the required additional header in the implementation > file or in the corresponding header file), and no need to maintain a long > list of include statements which ideally you should prune every time you > stop using a certain class. (Just how often do people forget to remove the > corresponding header?) And then people commit code that uses "everything", slowing down compilation times. We don't accept it in KF5 code (nor in most of KDE apps/workspace AFAIK), I don't see why we should provide something that we forbid. > I still call me seeing the warning a pure chance given the fact it's there. > The fact of me seeing it if it were not there would also be a pure chance > ... hopefully close enough to 0 ;) -Werror=undef is your friend. Actually I'll add it to my default set of flags, to see how much breaks ;-) -- David Faure, fa...@kde.org, http://www.davidfaure.fr Working on KDE Frameworks 5
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday April 26 2020 18:19:28 David Faure wrote: >> The possibility to use precompiled headers is only an argument here when >> increased compilation times are brought up as an argument against such a >> header. But that's not really an argument if you can continue to use just >> the headers you need. > >Well, then you never need all-inclusive headers. Who was talking about a hard need?! Convenience isn't need... And as to precompiled headers: have you already used them? You need *an* all-inclusive header, but AFAIK you can only have a single precompiled entity, which typically means that you create such a header beast for your project, in which you include every header that can be included from as many of your source files as possible. So we're back to the convenience argument: you could keep it selective for minimum build overhead (and maybe a little less dead code if your linker isn't too good at stripping that), or you can keep it short and include that hypothetic single header per framework. >> I could just as well maintain that nobody needs any of that particular >> framework ;) > >OK now you make no sense at all anymore, since I can give you 500 proofs of >the contrary: actual pieces of code that use some parts of KCoreAddons, and >none of them which use all of it. I was referring to code that just rolls their own implementation of the code in almost an given library. It's a bit of a pathological argument but I'd say it's beyond argument that you can always do that, whereas even exhaustive knowledge of all existing code that uses that particular library (and only part of it) constitutes no proof that no code could every need all of it. In fact, all one has to do to reject your hypothesis is write a single application that contains an exhaustive set of unit tests of all of the library's APIs. In fact, just unit tests of the ctors would do for most libraries/frameworks. >And then people commit code that uses "everything", slowing down compilation >times. We don't accept it in KF5 code (nor in most of KDE apps/workspace >AFAIK), I don't see why we should provide something that we forbid. That's another argument, but one that ought to be backed up with actual measurements of that slowdown. And: aren't KF5 frameworks supposed to be appeal as universally interesting sets of additions to Qt, outside of actual KDE apps (which I thought didn't exist anymore after KDE4 O:-) )? Providing something doesn't mean you have to accept its use under all conditions (Qt's private APIs come to mind as a relevant example). >-Werror=undef is your friend. That'd be the 1st time a -Werror is actually a friend, but I see your point. R
Re: building KF5 projects against a different Qt5 version (than the one the KF5 frameworks were built against)
On Sunday April 26 2020 20:16:33 René J.V. Bertin wrote: >I was referring to code that just rolls their own implementation of the code >in almost an given library. It's a bit of a pathological argument but I'd say >it's beyond argument that you can always do that, whereas even exhaustive >knowledge of all existing code that uses that particular library (and only >part of it) constitutes no proof that no code could every need all of it. >In fact, all one has to do to reject your hypothesis is write a single >application that contains an exhaustive set of unit tests of all of the >library's APIs. In fact, just unit tests of the ctors would do for most >libraries/frameworks. Shall we just write this exchange off to the effects of lock-up and "social distancing"? :)