From 6c99e9e83ccc355b2b66221de32c2cbec2fb8b46 Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 7 Oct 2025 14:36:39 +0100 Subject: [PATCH] cxx-qt-build: inject QML_FOREIGN types for qmllint/qmlls This allows them to understand the std numerics when namespaced as Qt only registers int32_t not ::std::int32_t so qmllint and qmlls state the type is not resolved. --- crates/cxx-qt-build/cpp/builtins.h | 94 ++++++++++++++++++++++++++++++ crates/cxx-qt-build/src/lib.rs | 13 ++++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 crates/cxx-qt-build/cpp/builtins.h diff --git a/crates/cxx-qt-build/cpp/builtins.h b/crates/cxx-qt-build/cpp/builtins.h new file mode 100644 index 000000000..ec987bb7a --- /dev/null +++ b/crates/cxx-qt-build/cpp/builtins.h @@ -0,0 +1,94 @@ +// clang-format off +// SPDX-FileCopyrightText: 2025 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#pragma once + +#include + +#include + +// This is similar to the builtins file in qtdeclarative +// https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/qml/qqmlbuiltins_p.h?h=v6.9.3 +// +// We need this to be able to alias namespaced std numerics to types that QML +// understands. +// +// We do not need to build this file but the moc JSON output to give to +// qmltyperegistrar so that qmllint and qmlls can understand the types. +// +// If Qt ever registered qualified versions of the numerics this could be +// removed. +// +// qqmlbuiltins uses the following values for QML_USING so we should copy +// i8, u8 -> qint8, quint8 +// i16, u16 -> short, ushort +// i32, u32 -> int, uint +// i64, u64 -> qlonglong, qulonglong + +struct QQmlCxxQtStdInt8TForeign +{ + Q_GADGET + QML_FOREIGN(::std::int8_t) + QML_USING(qint8) +}; +static_assert(sizeof(::std::int8_t) == sizeof(qint8)); + +struct QQmlCxxQtStdUInt8TForeign +{ + Q_GADGET + QML_FOREIGN(::std::uint8_t) + QML_USING(quint8) +}; +static_assert(sizeof(::std::uint8_t) == sizeof(quint8)); + +struct QQmlCxxQtStdInt16TForeign +{ + Q_GADGET + QML_FOREIGN(::std::int16_t) + QML_USING(short) +}; +static_assert(sizeof(::std::int16_t) == sizeof(short)); + +struct QQmlCxxQtStdUInt16TForeign +{ + Q_GADGET + QML_FOREIGN(::std::uint16_t) + QML_USING(ushort) +}; +static_assert(sizeof(::std::uint16_t) == sizeof(ushort)); + +struct QQmlCxxQtStdInt32TForeign +{ + Q_GADGET + QML_FOREIGN(::std::int32_t) + QML_USING(int) +}; +static_assert(sizeof(::std::int32_t) == sizeof(int)); + +struct QQmlCxxQtStdUInt32TForeign +{ + Q_GADGET + QML_FOREIGN(::std::uint32_t) + QML_USING(uint) +}; +static_assert(sizeof(::std::uint32_t) == sizeof(uint)); + +struct QQmlCxxQtStdInt64TForeign +{ + Q_GADGET + QML_FOREIGN(::std::int64_t) + QML_USING(qlonglong) +}; +static_assert(sizeof(::std::int64_t) == sizeof(qlonglong)); + +struct QQmlCxxQtStdUInt64TForeign +{ + Q_GADGET + QML_FOREIGN(::std::uint64_t) + QML_USING(qulonglong) +}; +static_assert(sizeof(::std::uint64_t) == sizeof(qulonglong)); diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index e32fb57ec..0318b5c59 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -853,11 +853,22 @@ impl CxxQtBuilder { let cc_builder = &mut self.cc_builder; qtbuild.cargo_link_libraries(cc_builder); - let qml_metatypes_json: Vec = moc_products + let mut qml_metatypes_json: Vec = moc_products .iter() .map(|products| products.metatypes_json.clone()) .collect(); + // Inject CXX-Qt builtin meta types + let builtins_path = dir::out().join("builtins.h"); + std::fs::write(&builtins_path, include_str!("../cpp/builtins.h")) + .expect("Failed to write builtins.h"); + qml_metatypes_json.push( + qtbuild + .moc() + .compile(builtins_path, MocArguments::default()) + .metatypes_json, + ); + let qml_module_registration_files = qtbuild.register_qml_module( &qml_metatypes_json, &qml_module.uri,