[Development] Switching Qt default builds to C++20 where supported

Thiago Macieira thiago.macieira at intel.com
Thu Oct 10 18:57:23 CEST 2024


Re: https://codereview.qt-project.org/c/qt/qtbase/+/463425

TL;DR: for some std::format functionality, we really want to have out-of-line 
implementations, which requires QtCore compiled with C++20. See 
https://codereview.qt-project.org/c/qt/qtbase/+/595309/2/src/corelib/text/
qstring.cpp for the thinking. Let's focus first on the C++ language, because 
the ABI discussion is irrelevant if we don't do this.

So I'd like to propose that we switch all Qt builds to C++20 by default where 
the compilers support it and have supported it for years, but not require it 
for platforms where either the compiler or the standard library are unable to 
compile in C++20 mode.

This switch can be overridden in the configure/cmake command-line in a 
developer-build-like "use voids warranty" option. That is, the only people who 
should change the default are people reading this mailing list. Other users, 
including all Linux packagers, Homebrew, vcpkg and the official QtC binaries 
should not touch that option. This override is intended solely so we can test 
the ability to compile C++17 without having to install those OSes above (none 
of which are freely available anyway). 

Moreover, our headers must build with C++17, so this is not a licence to use 
C++20 without compile-time checks (asking for that for the desktop platforms 
is a future discussion).

Because this is meant to be developer-build-like only, I think we need to 
remove the FEATURE_cxx20 and FEATURE_cxx2b cmake options too. This is because 
some user scripts may be using those and users need to understand the change 
in nature, that this is "voids warranty" now.

Points of discussion:
0) should we do this? Is there any side-effect?
Please note that downgrading compilers and Standard Library versions has never 
been allowed, so even if the Qt libs get some stickiness to the lib as a 
result of this, that is by itself not a problem. But it would be a problem if 
we do get it on a symbol that is not yet guaranteed to be ABI-stable.

1) what is the option to select C++17 or C++23 for testing?
My patch uses the CMAKE_CXX_STANDARD variable. Just pass it in your cmake 
command-line with -D and it will apply.

2) how should other modules inherit qtbase's setting?
The current patch does not inherit the setting at all and, instead, each 
module gets the default again. Each module can be independently overridden 
using CMAKE_CXX_STANDARD.

I prefer it this way because:
a) it's simpler, without inter-module dependencies
  (it was much simpler to implement)
b) the only people switching the language are us (incl. the CI) and we can 
   simply pass -DCMAKE_CXX_STANDARD where desired
c) allows for modules to make their own choices if they want to mandate C++17 
  or C++20 for some reason
d) allows for the CI to test mix-and-match C++17 and C++20 downstream of 
  qtbase

Alexandru makes a point that some developers may want to have a setting in one 
place and have it inherited to all other modules. This need not remove any of 
the points I made above, though, except that it would be a slightly more 
complex implementation.

3) how should we detect the platforms where C++17 is still required?
I hardcoded it:
* QNX, INTEGRITY, VxWorks: C++17 by default
* everyone else: C++20 by default
There's no configure-time checking that C++20 works for those platforms where 
it's set by default. The current patch allows CMake to fall back if it can't 
find the functionality, but maybe we just don't allow it to fall back.

There's an implicit question here whether having a per-platform default is a 
good idea. My stance on this is that I think being held back by platforms that 
won't update more than once a decade puts undue penalty on everyone else who 
does. I don't begrudge anyone from choosing those three above, but I also 
don't want your choices to constrain me.

4) should we support building Qt with C++17 on the C++20-by-default platforms?
Please note this is about building Qt itself, not about user code. User code 
must be compilable with C++17 because we don't know yet whether they have 
content that fails at C++20 for some reason.

My answer, as shown by my labeling the override option "voids warranty" is a 
very clear and definite NO. This means that if you have GCC 10 or later or 
Clang 13 or thereabouts or later or Visual Studio with the normal Standard 
Libraries, your only supported build is C++20. This means all desktop 
platforms, Android, and Apple mobile devices would use C++20.

Because we need that build ourselves to check our own headers, we will need to 
keep it working. But there will be consequences, when we do start allowing 
limited ABI dependency (like std::format).

5) which platforms and how much should the CI test C++17?
Undecided yet. I suggest we allow all builds to go to C++20 and deduplicate 
from there, then add (in decreasing order of time complexity):
* build everything (including examples and tests) using C++17, on Linux, but 
   not run any test
* header checks only and/or example build on Mac and Windows using C++17
* Android: header check?

The headers check can be achieved by configuring the module in question and 
running "ninja headersclean_check" instead of "ninja".

Alternatively, we can make the headerscheck target for C++20-enabled builds 
check each header in both modes. Maybe add C++23 there too.

6) when should we do this?
The last time we discussed C++20, it was made clear that we can only do such 
changes on LTS+1 releases. That's 6.9.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Principal Engineer - Intel DCAI Platform & System Engineering
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5152 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20241010/47763523/attachment.bin>


More information about the Development mailing list