Skip to content

Allow building with Clang/CL and fix building with GCC

Hi @dkazakov !

As promised, I'm sending this MR to allow building Krita with MSVC.

While rebuilding my developer environment, I found the following MSVC-specific bits were overlooked in !1334 (merged) (error logs here):

I didn't try to fix these because they seem to be compiler bugs, so instead I switched to Clang/CL for the Krita build itself. Once I did that, I found the following: (error logs here)

  • KDE's CompilerSettings enable many flags that are Clang-specific and are ignored or interpreted differently in the MSVC flavour.
    • Chiefly among them is -Wall, which Clang/CL maps to -Weverything, thus making the build spam hundreds of warnings per file.
  • Implicitly defining destructors of QScopedPointer consumers, like KisBrushOptionWidget, requires that the destructor of the guarded class be available at declaration time. This is not an issue with stock Clang and GCC, but Microsoft does enforce this requirement. This issue was documented previously in d64ee6a5:
  • The new Lager-based KisCurveOption uses std::vector<std::unique_ptr<KisDynamicSensor>>. This causes the implicitly defined copy constructor of KisCurveOption to attempt to access the deleted copy ctor of std::vector.
  • The new Lager-backed KisDynamicSensorFactory doesn't implement QString id() const, yet it's used with KoGenericRegistry where it's required for add(T value). Again, this implicitly relies on GCC construction semantics, whereas MSVC instead requires all concepts to be implemented and elides the APIs at codegen time.
  • I had improperly scoped the SSE flag check for xsimd, since it's not documented that Clang/CL doesn't enable instruction sets in the same way as MSVC (ie. up to SSE4.1 by default on 64). I only found out about this yesterday: https://aomedia-review.googlesource.com/c/aom/+/173762

(EDIT)

Upon further review, I decided to also test with the spare compiler I have in my environment, GCC UCRT64 12.2.0. There I found much more serious errors (logs here), so I decided to actually patch up Lager in 3rdparty.

  • Lager breaks the C++17 standard by attempting to define final, non-virtual functions in the nodes.
  • zug::map uses deduction on the transformer function to pass the object to be transformed as the first parameter; you relied on this in turn, to call into member functions to obtain the LOD restrictions. This is also non-standards-compliant, because member functions aren't directly callable except through std::function, std::bind, or lambdas.

The functionality described in the last item is actually a post C++ 17 proposal that Clang implements for some reason: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0312r1.html

It's also described here: https://devblogs.microsoft.com/cppblog/trip-report-evolution-working-group-at-the-summer-iso-c-standards-meeting-toronto/

Test Plan

Build Krita.

Note

The flag compatibility commit must be cherry-picked to 5.1 to allow me to test backports.

Formalities Checklist

  • I confirmed this builds.
  • I confirmed Krita ran and the relevant functions work.
  • I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!)
  • I made sure my commits build individually and have good descriptions as per KDE guidelines.
  • I made sure my code conforms to the standards set in the HACKING file.
  • I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per KDE Licensing Policy.

Reminder: the reviewer is responsible for merging the patch, this is to ensure at the least two people can build the patch. In case a patch breaks the build, both the author and the reviewer should be contacted to fix the build. If this is not possible, the commits shall be reverted, and a notification with the reasoning and any relevant logs shall be sent to the mailing list, kimageshop@kde.org.

Edited by Amy spark

Merge request reports