Resolve compiler warning for use of deprecated `KDeclarative::setupBindings`
ClosedPublic

Authored by sharvey on Mar 17 2018, 5:19 PM.

Details

Summary

Version 5.45 of KDeclarative deprecates setupBindings in favor of setupContext and setupEngine, used together. Perform version check of KDeclarative and continue using setupBindings when older versions of KDeclarative are present. This resolves the compiler warning while allowing most users to successfully compile the application.

Test Plan
  • Compile Spectacle normally
  • Note that compiler warning at QuickEditor.cpp line 77 is eliminated
  • Take a rectangular region screenshot; ensure proper operation of QML engine
  • If possible, test compiling against multiple versions of KDeclarative (5.45 versus minimum requirement of 5.29)

Diff Detail

Repository
R166 Spectacle
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
sharvey requested review of this revision.Mar 17 2018, 5:19 PM
sharvey created this revision.
sharvey edited the test plan for this revision. (Show Details)Mar 17 2018, 5:21 PM
sharvey added reviewers: Spectacle, rkflx, ngraham.

This was rather straightforward. setupBindings() has been deprecated in favor of setupEngine() and setupContext(). The two new functions effectively do what setupBindings() did, but in two calls instead of one. According to the API documentation, this is for the proper operation of the i18n functions.

I've done some exploring with QML combined with C++ and these will make setting up the QML engine and context much simpler than using the native QML functions. But I suppose that's the whole point of the KDE Frameworks - simplifying things for the programmer.

sharvey edited the summary of this revision. (Show Details)Mar 17 2018, 5:31 PM
sharvey edited the summary of this revision. (Show Details)
rkflx requested changes to this revision.Mar 17 2018, 11:17 PM

Thanks for the patch, indeed it looks simple. However, it does not compile for me:

src/QuickEditor/QuickEditor.cpp: In constructor ‘QuickEditor::QuickEditor(const QPixmap&, QObject*)’:
src/QuickEditor/QuickEditor.cpp:77:15: error: ‘class KDeclarative::KDeclarative’ has no member named ‘setupEngine’; did you mean ‘setupBindings’?
     d->mDecl->setupEngine(d->mQmlEngine);
               ^~~~~~~~~~~
               setupBindings
src/QuickEditor/QuickEditor.cpp:78:15: error: ‘class KDeclarative::KDeclarative’ has no member named ‘setupContext’
     d->mDecl->setupContext();
               ^~~~~~~~~~~~

Of course I know what the problem is, but maybe you could also imagine why it compiles for you but not for others.

If you have found something, try to come up with a fix. In case you get stuck, here is a hint which you should be able to adapt.

This revision now requires changes to proceed.Mar 17 2018, 11:17 PM

I'm pretty certain I know why, just from reading your error output: I have the latest version of KDeclarative in my setup and you do not. I admit that hadn't occurred to me.

I will look at how this situation is normally handled and resubmit. I've seen it done; I just need to piece together how it works.

Okay. I partially understand.

I see that we can include the header file kdeclarative_version.h and then write a conditional block like this:

#if KDECLARATIVE_VERSION > QT_VERSION_CHECK(5, 45, 0)
    d->mDecl->setupBindings();
#else
    d->mDecl->setupEngine(d->mQmlEngine);
    d->mDecl->setupContext();
#endif

... and I presume the code would compile. However, the presence of the deprecated setupBindings() statement still triggers a compiler warning.

I also know we can adjust the required version of the Frameworks by updating a variable in the main CMakeLists.txt file.

set(KF5_MIN_VERSION    "5.45.0")

While I'm fairly certain that 5.45 is the official current version of the Frameworks, it's unclear to me when the applications have their requirements moved forward accordingly. As of tonight, CMakeLists.txt still only demands Frameworks 5.29, and KDeclarative is the only 5.45 component where we're encountering a deprecated function.

Is the change in the minimum Frameworks requirement tied to the upcoming 18.04 release of the applications? This is where I feel my understanding of the problem shifts from technical to procedural. Changing CMakeLists.txt would force the would-be compiler to update their system with new versions of all the necessary Framework libraries. Leaving the Framework minimum requirement unchanged, but adding the conditional block to the code would enable successful compilation, but still trigger a warning.

In this case, I can see how to resolve the problem, but I don't know which method is correct or customary.

I think you understood the problem, and both of your solutions are normal ways to handle it.

Of course we could require the newest version of KDE Frameworks, but there are some problems with that:

  • Perhaps someone uses a distro which does not compile daily from Git (not even the rolling distros have this change, as it is not even released yet), thus making it difficult to compile Spectacle.
  • KDE Applications should only have dependencies on released versions, but KDE Frameworks 5.45 is not released yet.
  • As per the release schedule we are already past the dependency freeze for 18.04, so we'd have to wait until 18.04 has branched off from master.

We need to balance adding #ifs against making it harder to compile. Here the #if is minimal, so I'd be in favour of going in this direction. That's why my hint suggested to make this conditional instead of bumping the KF5 version. Of course in a couple of years we'll want to remove the #if again to keep the code somewhat clean. The minimum version can also be bumped if required for changes where adding #if everywhere would become unwieldy. It's only for KDE Frameworks itself where dependencies are bumped automatically, in order to enforce one consistent KF5 version on the system.

However, the presence of the deprecated setupBindings() statement still triggers a compiler warning.

That's because you mixed up #if and #else, inverting the condition. Also, it should read >=, not >.

  • Perhaps someone uses a distro which does not compile daily from Git (not even the rolling distros have this change, as it is not even released yet), thus making it difficult to compile Spectacle.

I'm rapidly learning that Neon Dev Unstable is a mixed blessing. I already got sent a new Spectacle binary after you committed my two patches (thanks for that; it was fascinating to see them go through Jenkins). But having ready access to the pre-release libraries can lead to a kind of blindness.

  • KDE Applications should only have dependencies on released versions, but KDE Frameworks 5.45 is not released yet.

My misunderstanding, again. I thought I'd read that 5.45 was released. Thank you for linking to the release schedule. I've bookmarked it. I continue to be impressed by how thoroughly the KDE project is organized - and documented. All the information I need is published and findable; none of it's behind closed doors.

That's because you mixed up #if and #else, inverting the condition. Also, it should read >=, not >.

That's the single most embarrassing mistake I've made in my brief KDE "career". I certainly know better than that. I will revise, re-test, and properly submit, with appropriate humility.

sharvey updated this revision to Diff 29841.Mar 18 2018, 6:39 PM
  • Add version check for KDeclarative, use #if block to select appropriate calls

Include kdeclarative_version.h, use new setupContext and setupEngine under version 5.45; continue using setupBindings for older versions.

sharvey retitled this revision from Resolve compiler warning for use of deprecated `KDeclarative::setupBindings()` to Resolve compiler warning for use of deprecated `KDeclarative::setupBindings`.Mar 18 2018, 6:47 PM
sharvey edited the summary of this revision. (Show Details)
sharvey edited the test plan for this revision. (Show Details)

With my egregious mixup of the #if corrected, the application compiles for me without a warning. It should also compile under KDeclarative versions below 5.45. I thought the mere presence of the older function call triggered the warning. My second attempt at using a preprocessor directive has turned out much better than the first.

rkflx accepted this revision.Mar 19 2018, 12:01 AM

Perfect, just like I would have written this.

As a tip for debugging such constructs, use #error <message> to make the preprocessor stop at a specific place.

This revision is now accepted and ready to land.Mar 19 2018, 12:01 AM
This revision was automatically updated to reflect the committed changes.