Skip to content

CXX-Qt 0.7 Release

Thursday, 31 October 2024 | KDAB on Qt

We just released CXX-Qt version 0.7!

CXX-Qt is a set of Rust crates for creating bidirectional Rust ⇄ C++ bindings with Qt. It supports integrating Rust into C++ applications using CMake or building Rust applications with Cargo. CXX-Qt provides tools for implementing QObject subclasses in Rust that can be used from C++, QML, and JavaScript.

For 0.7, we have stabilized the cxx-qt bridge macro API and there have been many internal refactors to ensure that we have a consistent baseline to support going forward. We encourage developers to reach out if they find any unclear areas or missing features, to help us ensure a roadmap for them, as this may be the final time we can adapt the API. In the next releases, we’re looking towards stabilizing the cxx-qt-build and getting the cxx-qt-lib APIs ready for 1.0.

Check out the new release through the usual channels:

Some of the most notable developer-facing changes:

Stabilized #[cxx_qt::bridge] macro

CXX-Qt 0.7 reaches a major milestone by stabilizing the bridge macro that is at the heart of CXX-Qt. You can now depend on your CXX-Qt bridges to remain compatible with future CXX-Qt versions. As we’re still pre-1.0, we may still introduce very minor breaking changes to fix critical bugs in the edge-cases of the API, but the vast majority of bridges should remain compatible with future versions.

This stabilization is also explicitly limited to the bridge API itself. Breaking changes may still occur in e.g. cxx-qt-lib, cxx-qt-build, and cxx-qt-cmake. We plan to stabilize those crates in the next releases.

Naming Changes

The handling of names internally has been refactored to ensure consistency across all usages. During this process, implicit automatic case conversion has been removed, so cxx_name and rust_name are now used to specify differing Rust and C++ names. Since the automatic case conversion is useful, it can be explicitly enabled using per extern block attributes auto_cxx_name and auto_rust_name, while still complimenting CXX. For more details on how these attributes can be used, visit the attributes page in the CXX-Qt book.


// with 0.6 implicit automatic case conversion
#[cxx_qt::bridge]
mod ffi {
  unsafe extern "RustQt" {
    #[qobject]
    #[qproperty(i32, my_number) // myNumber in C++
    type MyObject = super::MyObjectRust;

    fn my_method(self: &MyObject); // myMethod in C++
  }
}

// with 0.7 cxx_name / rust_name
#[cxx_qt::bridge]
mod ffi {
  unsafe extern "RustQt" {
    #[qobject]
    #[qproperty(i32, my_number, cxx_name = "myNumber")
    type MyObject = super::MyObjectRust;

    #[cxx_name = "myMethod"]
    fn my_method(self: &MyObject);
  }
}

// with 0.7 auto_cxx_name / auto_rust_name
#[cxx_qt::bridge]
mod ffi {
  #[auto_cxx_name] // <-- enables automatic cxx_name generation within the `extern "RustQt"` block
  unsafe extern "RustQt" {
    #[qobject]
    #[qproperty(i32, my_number) // myNumber in C++
    type MyObject = super::MyObjectRust;

    fn my_method(self: &MyObject); // myMethod in C++
  }
}

cxx_file_stem Removal

In previous releases, the output filename of generated C++ files used the cxx_file_stem attribute of the CXX-Qt bridge. This has been changed to use the filename of the Rust source file including the directory structure.

Previously, the code below would generate a C++ header path of my_file.cxxqt.h. After the changes, the cxx_file_stem must be removed and the generated C++ header path changes to crate-name/src/my_bridge.cxxqt.h. This follows a similar pattern to CXX.

// crate-name/src/my_bridge.rs

// with 0.6 a file stem was specified
#[cxx_qt::bridge(cxx_file_stem = "my_file")]
mod ffi {
...
}

// with 0.7 the file path is used
#[cxx_qt::bridge]
mod ffi {
...
}

Build System Changes

The internals of the build system have changed so that dependencies are automatically detected and configured by cxx-qt-build, libraries can pass build information to cxx-qt-build, and a CXX-Qt CMake module is now available providing convenience wrappers around corrosion. This means that the cxx-qt-lib-headers crate has been removed and only cxx-qt-lib is required. With these changes, there is now no need for the -header crates that existed before. Previously, some features were enabled by default in cxx-qt-lib. Now these are all opt-in. We have provided full and qt_full as convenience to enable all features; however, we would recommend opting in to the specific features you need.

We hope to improve the API of cxx-qt-build in the next cycle to match the internal changes and become more modular.

Further Improvements

CXX-Qt can now be successfully built for WASM, with documented steps available in the book and CI builds for WASM to ensure continued support.

Locking generation on the C++ side for all methods has been removed, which simplifies generation and improves performance. Using queue from cxx_qt::CxxQtThread is still safe, as it provides locking, but it is up to the developer to avoid incorrect multi-threading in C++ code (as in the CXX crate). Note that Qt generally works well here, with the signal/slot mechanism working safely across threads.

As with most releases, there are more Qt types wrapped in cxx-qt-lib and various other changes are detailed in the CHANGELOG.

Make sure to subscribe to the KDAB YouTube channel, where we’ll post more videos on CXX-Qt in the coming weeks.

Thanks to all of our contributors that helped us with this release:

  • Ben Ford
  • Laurent Montel
  • Matt Aber
  • knox (aka @knoxfighter)
  • Be Wilson
  • Joshua Goins
  • Alessandro Ambrosano
  • Alexander Kiselev
  • Alois Wohlschlager
  • Darshan Phaldesai
  • Jacob Alexander
  • Sander Vocke

About KDAB

If you like this article and want to read similar material, consider subscribing via our RSS feed.

Subscribe to KDAB TV for similar informative short video content.

KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.

The post CXX-Qt 0.7 Release appeared first on KDAB.