Skip to content

Conversation

hjmjohnson
Copy link
Contributor

@hjmjohnson hjmjohnson commented Sep 26, 2025

This PR modernizes PythonQt’s wrapper generation & build pipeline and aligns CI with Qt 6.10. It removes legacy, checked-in Qt5 wrapper directories, relies on explicit/generated paths at build time, normalizes macOS includes to bare Qt headers, adds qmake toggles for targeted builds, and updates CI to first generate wrappers then build without the generator. It also excludes a new std::string_view operator introduced in Qt 6.10 that is not yet supported by the generator.

Summary

  • Add CONFIG+=generator_only (build just the wrapper generator).

  • Add CONFIG+=exclude_generator (build everything except the generator).

  • CI

  • Switch "latest" pipeline from Qt 6.9 -> Qt 6.10 (workaround missing Updates.xml.sha256 for 6.9.3).

  • Restructure jobs to:

    1. build generator,
    2. run pythonqt_generator,
    3. build without the generator and run tests.
  • On macOS, generate wrappers for both Debug and Release.

  • Repository housekeeping

  • Remove stale example wrapper trees:

    • generated_cpp_50, generated_cpp_53, generated_cpp_54, generated_cpp_56, generated_cpp_511
    • Keep generated_cpp_515 as the canonical example.

How to build now

Preferred: generate wrappers into ../generated_cpp (relative to the build) or point qmake at an absolute path.

# Option A: generate to ../generated_cpp
qmake CONFIG+=generator_only
make -C generator
./generator/pythonqt_generator  # emits to ../generated_cpp by default

# Option B: use a custom location
qmake PYTHONQT_GENERATED_PATH=/abs/path/to/generated_cpp

Then build without the generator:

qmake CONFIG+=exclude_generator
make -j$(nproc)

If wrappers are missing, the build will fail early with a message listing searched locations and how to generate them.

Notes

  • Removed fallbacks: Projects that relied on the repository’s Qt5 wrapper directories must re-generate wrappers for their Qt version.
  • Qt 6.10: CI now targets 6.10. Local builds with older Qt versions should still work if wrappers are generated for that version.
  • macOS: Header normalization only affects generated include lines; no behavior change at runtime.
  • Temporarily excluded API: The Qt 6.10 std::string_view operator is skipped in the typesystem until binding support is implemented.

@hjmjohnson hjmjohnson force-pushed the remove-old-generated-code branch from d86b49e to fede61a Compare September 26, 2025 18:56
@jcfr

This comment was marked as outdated.

@jcfr

This comment was marked as outdated.

@hjmjohnson hjmjohnson force-pushed the remove-old-generated-code branch from adbed21 to b84b752 Compare September 26, 2025 21:29
@hjmjohnson

This comment was marked as outdated.

@hjmjohnson

This comment was marked as outdated.

@hjmjohnson hjmjohnson force-pushed the remove-old-generated-code branch from b84b752 to f173927 Compare September 26, 2025 22:00
@hjmjohnson hjmjohnson marked this pull request as draft September 26, 2025 22:01
@hjmjohnson hjmjohnson changed the title STYLE: Remove all but Qt 5.15 generated code examples DRAFT STYLE: Remove all but Qt 5.15 generated code examples Sep 26, 2025
@hjmjohnson

This comment was marked as outdated.

Introduce two qmake CONFIG flags to control subdir builds:

- CONFIG+=generator_only       -> build just the wrapper generator
- CONFIG+=exclude_generator    -> build everything except the generator

Default remains unchanged (all subdirs). This enables CI to generate
wrappers first, then build without the generator to avoid redundant work.
@jcfr
Copy link
Contributor

jcfr commented Sep 27, 2025

@hjmjohnson Thanks for getting this started, I was able to spend a bit of time to improve the build-system and continuous integration accordingly.

@jcfr jcfr force-pushed the remove-old-generated-code branch 2 times, most recently from e23b02a to 2434015 Compare September 27, 2025 21:14
Split the pipeline in each job:
1) qmake build with CONFIG+=generator_only
2) run pythonqt_generator
3) qmake build with CONFIG+=exclude_generator and run tests
@jcfr jcfr force-pushed the remove-old-generated-code branch from 2434015 to 6aa308d Compare September 27, 2025 21:16
Default to `../generated_cpp` (generator output). If missing, probe the
exact-version dir (`generated_cpp_<MAJOR><MINOR>`, e.g., 515) and then the
legacy Qt5 fallbacks.

Also allow override via:

```
qmake PYTHONQT_GENERATED_PATH=/abs/path
```

When wrappers are absent, emit a concise error that lists the searched
paths and indicates how to generate them.
@jcfr jcfr force-pushed the remove-old-generated-code branch from 6aa308d to 3f119cb Compare September 27, 2025 21:40
@hjmjohnson
Copy link
Contributor Author

@jcfr You are awesome! Thank you for taking a closer look at the CI and improving its robustness.

@hjmjohnson
Copy link
Contributor Author

@jcfr Looks really close to working. I'm surprised that the debug variant passes, but the release variant fails with a missing header: https://github.com/MeVisLab/pythonqt/actions/runs/18065296643/job/51407182062?pr=313#step:9:124 error.

@hjmjohnson
Copy link
Contributor Author

@jcfr You may already know of this tool, but I thought I'd put it here for documentation purposes:

https://ddalcino.github.io/aqt-list-server/

@jcfr
Copy link
Contributor

jcfr commented Sep 28, 2025

Build / macOS (latest, 3.9, 5.9.*, release)

/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/bin/moc -DPYTHONQT_CATCH_ALL_EXCEPTIONS -DPYTHONQT_EXPORTS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB --include ./moc_predefs.h -I/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/mkspecs/macx-clang -I/Users/runner/work/pythonqt/pythonqt/src -I/Users/runner/work/pythonqt/pythonqt/src -I/Users/runner/work/pythonqt/pythonqt/src -I/Library/Frameworks/Python.framework/Versions/3.9/include/python3.9 -I/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/lib/QtWidgets.framework/Headers -I/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/lib/QtGui.framework/Headers -I/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/lib/QtCore.framework/Headers/5.9.9 -I/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/lib/QtCore.framework/Headers/5.9.9/QtCore -I/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/lib/QtCore.framework/Headers -I/Applications/Xcode_16.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.5.sdk/usr/include/c++/v1 -I/Applications/Xcode_16.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/17/include -I/Applications/Xcode_16.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.5.sdk/usr/include -I/Applications/Xcode_16.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -F/Users/runner/work/pythonqt/Qt/5.9.9/clang_64/lib ../generated_cpp/com_trolltech_qt_gui_builtin/com_trolltech_qt_gui_builtin0.h -o moc_com_trolltech_qt_gui_builtin0.cpp
In file included from ../generated_cpp/com_trolltech_qt_core_builtin/com_trolltech_qt_core_builtin0.cpp:1:
../generated_cpp/com_trolltech_qt_core_builtin/com_trolltech_qt_core_builtin0.h:1:10: fatal error: '../lib/QtCore.framework/Headers/qbitarray.h' file not found
    1 | #include <../lib/QtCore.framework/Headers/qbitarray.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../generated_cpp/com_trolltech_qt_gui_builtin/com_trolltech_qt_gui_builtin0.cpp:1:
../generated_cpp/com_trolltech_qt_gui_builtin/com_trolltech_qt_gui_builtin0.h:1:10: fatal error: '../lib/QtCore.framework/Headers/qbytearray.h' file not found
    1 | #include <../lib/QtCore.framework/Headers/qbytearray.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Follow-up of 19738be ("feat(generator): discover Qt include/framework
paths dynamically; add PYTHONQT_FRAMEWORK", 2025-09-18).

On macOS, headers parsed from framework paths like:
  .../QtCore.framework/Headers/qbytearray.h
  .../QtCore.framework/Versions/A/Headers/qbytearray.h
were emitted as relative framework paths.

Update `AbstractMetaBuilder::getRelativeInclude()` to detect both layouts
and emit only the basename (e.g., `<qbytearray.h>`).
@jcfr jcfr force-pushed the remove-old-generated-code branch from 69c29cf to dfeadb6 Compare September 28, 2025 20:11
@hjmjohnson hjmjohnson changed the title DRAFT STYLE: Remove all but Qt 5.15 generated code examples STYLE: Remove all but Qt 5.15 generated code examples Sep 28, 2025
@hjmjohnson hjmjohnson force-pushed the remove-old-generated-code branch 2 times, most recently from 6279678 to fc97c64 Compare September 29, 2025 13:26
@jcfr
Copy link
Contributor

jcfr commented Sep 29, 2025

re: error downloading Qt 6.9.3

I am able to reproduce locally:

$ uvx --from aqtinstall aqt install-qt linux desktop 6.9.* linux_gcc_64 --autodesktop --outputdir /tmp/Qt --modules qt5compat qtscxml qtpositioning qtwebchannel qtmultimedia qtwebengine
INFO    : aqtinstall(aqt) v3.3.0 on Python 3.10.12 [CPython GCC 11.4.0]
INFO    : Resolved spec '6.9.*' to 6.9.3
WARNING : Failed to download checksum for the file 'online/qtsdkrepository/linux_x64/desktop/qt6_693/qt6_693/Updates.xml'. This may happen on unofficial mirrors.
ERROR   : The packages ['qtwebengine'] were not found while parsing XML of package information!
==============================Suggested follow-up:==============================

... note that specifying 6.10 seem to work:

$ uvx --from aqtinstall aqt install-qt linux desktop 6.10.* linux_gcc_64 --autodesktop --outputdir /tmp/Qt --modules qt5compat qtscxml qtpositioning qtwebchannel qtmultimedia qtwebengine
INFO    : aqtinstall(aqt) v3.3.0 on Python 3.10.12 [CPython GCC 11.4.0]
INFO    : Resolved spec '6.10.*' to 6.10.0
INFO    : Found extension qtwebengine
INFO    : Found extension qtpdf
INFO    : Downloading qtscxml...
[...]

@jcfr
Copy link
Contributor

jcfr commented Sep 29, 2025

@jcfr
Copy link
Contributor

jcfr commented Sep 29, 2025

hjmjohnson and others added 3 commits September 29, 2025 11:31
Recommend that anyone using that Qt version to re-run the generator.

Remove redundant example directories.
  generated_cpp_50
  generated_cpp_53
  generated_cpp_54
  generated_cpp_56
  generated_cpp_511

The generated_cpp_515 serves as an example of what kind of code
is generated.
This also works around an issue where `aqtinstall` attempt was attempting
to download the non existing checksum associated with `qt6_693/qt6_693/Updates.xml`[^1].
Indeed, as of Sept 29th 2025, the file `qt6_693/qt6_693/Updates.xml.sha256`[^2] is not
available anymore.

[^1]: https://download.qt.io/online/qtsdkrepository/linux_x64/desktop/qt6_693/qt6_693/Updates.xml
[^2]: https://download.qt.io/online/qtsdkrepository/linux_x64/desktop/qt6_693/qt6_693/Updates.xml.sha256
…n explicit/generated path

Remove the hard-coded auto-selection of checked-in wrapper sets
(`generated_cpp_50`, `_54`, `_56`, `_511`, `_515`) for Qt5. The build
now relies solely on:

* an explicit `PYTHONQT_GENERATED_PATH` provided by the caller, **or**
* the default `$$PWD/../generated_cpp` when it exists,

and otherwise fails fast with a clear error message listing where we
looked.
@jcfr jcfr force-pushed the remove-old-generated-code branch from 4fc8297 to 253e01d Compare September 29, 2025 15:31
@jcfr

This comment was marked as outdated.

@hjmjohnson hjmjohnson changed the title STYLE: Remove all but Qt 5.15 generated code examples Build & generator cleanup: drop Qt5 wrapper fallbacks, switch CI to Qt 6.10, normalize macOS includes, add qmake toggles, and regenerate wrappers in CI Sep 29, 2025
… APIs

This changes the generator to exclude unsupported functions
in QJsonObject and QCborMap for Qt 6.10. The functions
asKeyValueRange, constKeyValueBegin, and constKeyValueEnd
are now marked for rejection.
@jcfr
Copy link
Contributor

jcfr commented Sep 29, 2025

@hjmjohnson This can now be marked as ready for review

@jcfr
Copy link
Contributor

jcfr commented Sep 29, 2025

@usiems @mrbean-bremen This is now ready for final review & integration 🚀 🙏

@hjmjohnson hjmjohnson marked this pull request as ready for review September 29, 2025 18:13
…ake toggles

- Drop claim that wrappers are pre-generated/checked-in.
- Document default generator output (../generated_cpp) and override via PYTHONQT_GENERATED_PATH.
- Describe qmake toggles (generator_only / exclude_generator) and switch build
  steps to top-level PythonQt.pro: first generate wrappers, then build runtime
  (and extensions) without rebuilding the generator.
@jcfr jcfr force-pushed the remove-old-generated-code branch from ddc9202 to 671a16c Compare September 29, 2025 18:20
Copy link
Contributor

@mrbean-bremen mrbean-bremen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! I've been reviewing this while it was ongoing, and I don't see any problems.
As usually, also want to see @usiems' opinion (best to review the commits separately).

@jcfr
Copy link
Contributor

jcfr commented Sep 29, 2025

🙏 @mrbean-bremen

And kudos to @hjmjohnson for keeping the momentum going 🚀

Copy link
Contributor Author

@hjmjohnson hjmjohnson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jcfr for working through the CI fixes

…ribution

This ensures that headers like `bits/wordsize.h` included from `qconfig.h`
found in multi-lib Qt distributions will properly define `__WORDSIZE` so that
the expected header `QtCore/qconfig-64.h` is included.
This changes the QTDIR to /usr/include/qt5 and passes the correct
include paths to the pythonqt_generator script, ensuring that necessary
headers are found without extra symbolic links.

Fixes MeVisLab#291
… QLibraryInfo

- Headers: if QTDIR/include exists, use it; otherwise treat QTDIR as the include root.
  This conditional append avoids re-introducing the /usr/include/qt5ln symlink workaround
  removed in previous commit.
- Frameworks (macOS): prefer QTDIR/lib; fallback to QLibraryInfo::LibrariesPath.
- Retains existing CLI/env include and framework overrides.
@jcfr
Copy link
Contributor

jcfr commented Sep 30, 2025

To conclude, the commit chore(generator): Prefer QTDIR for Qt headers/frameworks; fallback to QLibraryInfo addresses #302 (comment) from @usiems and avoid re-introducing the /usr/include/qt5ln symlink workaround

@jcfr
Copy link
Contributor

jcfr commented Sep 30, 2025

@he-hesce To follow-up on #314 (comment), this pull request fixes the generation of wrappers on Rocky Linux.

@jcfr
Copy link
Contributor

jcfr commented Sep 30, 2025

@mrbean-bremen @usiems Et voila, this is ready for another round of review. It now includes

@usiems
Copy link
Contributor

usiems commented Sep 30, 2025

I'm really happy with the changes. Good work!

@usiems usiems merged commit 9f074be into MeVisLab:master Sep 30, 2025
17 checks passed
@jcfr jcfr deleted the remove-old-generated-code branch September 30, 2025 13:38
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.

4 participants