Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qt6 fixes (generator code) #113

Closed
wants to merge 8 commits into from
Closed

Qt6 fixes (generator code) #113

wants to merge 8 commits into from

Conversation

jbowler
Copy link
Contributor

@jbowler jbowler commented Oct 2, 2023

These commits fix a number of cases where PythonQt is using features that were obsolete in QT 5.15 LTS. This is just in the "generator" code - I can't get a build to get any further than generator/parser/parser.cpp yet so there will be other deprecated (and not removed) cases later in the build.

At this point parser.cpp fails to build because Qt6 did a rewrite of QtXml and removed all the "SAX" classes. It looks like rewriting parser.cpp to match could be done blind and would work in earlier versions as the Qt6 recommendation is to use a class (QXmlStreamReader) which has existed since Qt 4.3. Unfortunately its a rewrite and I'm not happy trying that; I don't know anything about the schema being used for one thing!

So I might try using Qt5Compat as a temporary fix to avoid the rewrite and see if further progress is possible without major or incompatible (with Qt5.15) changes.

Qt6 *requires* support for the C++17 standard.  This is the default with
current versions of g++ (GNU) and is also the default standard level
enabled by qmake6 (see https://doc.qt.io/qt-6/qmake-variable-reference.html)
however QMAKE_CXXFLAGS is set to force -std=c++98 (-ansi is an alias for
this).  The qmake CONFIG options try to explicitly enable c++11 (not
sufficient for Qt6) and this does result in qmake5 setting -std=c++11.
This does not happen, or does not happen always, with qmake6 and,
anyway, is insufficient.

It is also the case that a standard to use should not be set to
conflicing values in two different places.  Ideally it should be left to
the person who supplies the compiler.  (cmake does, in fact, provide
flags to ensure a suitable compiler is used.)

This fix simply removes both conflicting attempts to set the C++
standard.  It therefore allows compilation with later versions of the
standard (e.g. c++20).  It works with both Qt5 and Qt6.  Tested with:

qmake5:
  Make version 3.1
  Using Qt version 5.15.10 in /usr/lib64

qmake6:
  QMake version 3.1
  Using Qt version 6.5.3 in /usr/lib64

With g++ and glibc 2.38:
  g++ (Gentoo 13.2.1_p20230826 p7) 13.2.1 20230826
This function is deprecated in Qt5 and, therefore, does not exist in
Qt6. This patch follows the recommendation here:

https://doc.qt.io/qt-5.15/qatomicpointer-obsolete.html#load

Tested with qmake5 (complete build/installation) and qmake6 (builds past
this error to the next one.)
This is not required in Qt5 and in Qt6 QStringList is apparently a
typedef so declaring it as a class is technically incorrect; enough for
the build to fail with qmake6.

Signed-off-by: John Bowler <jbowler@acm.org>
This causes a g++ compile error in codemodel.cpp (see the end of this
comment).  Apparently it "works" in Qt5 but adding the "const" in the
relevant places does not break the compile, so:

bool TypeInfo::operator==(const TypeInfo&)

Apparently does not modify the LHS; this means that adding the const is
safe (there would be a compile error if somoething in the implementation
did modify part of the LHS).

It makes sense to me that Qt6 would do something to prevent an ==
operator with a mutable LHS.  So far as I can see QList would have to
make a complete copy of the LHS under some circumstances resulting in a
potentially significant performance hit (depending on the complexity of
the type involved).

This is a harmless but possibly beneficial change to both 'master' and 'qt6' branches.

Here is the precise compiler message from g++ 13.2.1:

parser/codemodel.cpp: In member function ‘bool TypeInfo::operator==(const TypeInfo&)’:
parser/codemodel.cpp:237:51: error: no match for ‘operator==’ (operand types are ‘QList<TypeInfo>’ and ‘const QList<TypeInfo>’)
  237 |     && (!m_flags.m_functionPointer || m_arguments == other.m_arguments);
      |                                       ~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~~~~
      |                                       |                    |
      |                                       QList<[...]>         QList<[...]>
In file included from /usr/include/qt6/QtCore/QList:1,
                 from parser/codemodel_fwd.h:47,
                 from parser/codemodel.h:46:
/usr/include/qt6/QtCore/qlist.h:322:56: note: candidate: ‘template<class U> QTypeTraits::compare_eq_result_container<QList<T>, U> QList<T>::operator==(const QList<T>&) const [with T = TypeInfo]’
  322 |     QTypeTraits::compare_eq_result_container<QList, U> operator==(const QList &other) const
      |                                                        ^~~~~~~~
/usr/include/qt6/QtCore/qlist.h:322:56: note:   template argument deduction/substitution failed:
In file included from /usr/include/qt6/QtCore/qglobal.h:13,
                 from /usr/include/qt6/QtCore/qshareddata.h:7,
                 from /usr/include/qt6/QtCore/QSharedData:1,
                 from parser/codemodel_pointer.h:45,
                 from parser/codemodel_fwd.h:46:
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/type_traits: In substitution of ‘template<bool _Cond, class _Tp> using std::enable_if_t = typename std::enable_if::type [with bool _Cond = false; _Tp = bool]’:
/usr/include/qt6/QtCore/qtypeinfo.h:319:7:   required by substitution of ‘template<class Container, class ... T> using QTypeTraits::compare_eq_result_container = std::enable_if_t<conjunction_v<std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_equal<T> >...>, bool> [with Container = QList<TypeInfo>; T = {TypeInfo}]’
/usr/include/qt6/QtCore/qlist.h:322:56:   required by substitution of ‘template<class U> QTypeTraits::compare_eq_result_container<QList<TypeInfo>, U> QList<TypeInfo>::operator==(const QList<TypeInfo>&) const [with U = TypeInfo]’
parser/codemodel.cpp:237:60:   required from here
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/type_traits:2610:11: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
 2610 |     using enable_if_t = typename enable_if<_Cond, _Tp>::type;
      |           ^~~~~~~~~~~
make[1]: *** [Makefile:1112: codemodel.o] Error 1

Signed-off-by: John Bowler <jbowler@acm.org>
These are not valid ISO-C and therefore -Wpendantic (-pedantic) causes
warnings to be emitted.  In practice the code can either fail
compilation (as it would with -Werror) or work correctly so turning
these warnings off is harmless and removes confusing and misleading
reports.

A better fix is to give the structs a name (within the containing union)
and change all the references to include the name.  This is trivial but
changes a lot of lines so I'm not happy doing that because of the likely
merge conflicts.

Signed-off-by: John Bowler <jbowler@acm.org>
The move happened in Qt5.14 (where the QString definition was deprecated
in favor of a new one in Qt) but Qt6 deleted the QString definition.
This fix will work either side of the 5.14 change.

Signed-off-by: John Bowler <jbowler@acm.org>
The suggested replacements are std::stable_sort and std::sort which work
(compile) in both Qt5 (5.15LTS) and Qt6.

Signed-off-by: John Bowler <jbowler@acm.org>
These have been removed in Qt6, use Qt::endl instead (compiles with
Qt5.15 LTS).

Signed-off-by: John Bowler <jbowler@acm.org>
@jbowler
Copy link
Contributor Author

jbowler commented Oct 2, 2023

I'll do it in bits. loadRelaxed was not introduced until 5.14 (the docs say this, but don't point out that load was only deprecated after that...)

@jbowler jbowler closed this Oct 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant