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

cxx-qt-gen: allow for unused unsafe blocks and resolve no-exception issues #1124

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/KDAB/cxx-qt/compare/v0.7.0...HEAD)

### Fixed

- Build warnings due to unused unsafe blocks since CXX 1.0.130
- Build failures with WASM due to `cc` crate setting `-fno-exceptions` since 1.2.0

## [0.7.0](https://github.com/KDAB/cxx-qt/compare/v0.6.1...v0.7.0) - 2024-10-30

### Added
Expand Down
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,9 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[workspace.lints.clippy]
incompatible_msrv = "deny"
incompatible_msrv = "deny"

[patch.crates-io]
cxx = { git = 'https://github.com/ahayzen-kdab/cxx.git', branch = "trycatch-no-exceptions" }
cxx-build = { git = 'https://github.com/ahayzen-kdab/cxx.git', branch = "trycatch-no-exceptions" }
cxx-gen = { git = 'https://github.com/ahayzen-kdab/cxx.git', branch = "trycatch-no-exceptions" }
9 changes: 9 additions & 0 deletions book/src/concepts/wasm-builds.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,12 @@ error[E0433]: failed to resolve: use of undeclared type `IovLen`
`socket2` is a dependency of `async-io`, which is a dependency of `async-std`.

There is discussion around supporting wasm in the GitHub repository for `async-std`, and the progress is being tracked [here](https://github.com/async-rs/async-std/issues/220).

### Cannot use throw / try catch with exceptions disabled

CXX and CXX-Qt can generate code that attempts to use exceptions but these are disabled
for most WASM platforms.

The cmake-qt-cmake builder will attempt to set a define of `RUST_CXX_NO_EXCEPTIONS` which should
causes the code not to be compiled. But if this doesn't work try adding `-DRUST_CXX_NO_EXCEPTIONS`
to a `CXXFLAGS` enviornment variable while building.
4 changes: 4 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ impl GeneratedRustBlocks {
);
let cxx_mod = parse_quote! {
#[cxx::bridge(namespace = #namespace)]
// We need to allow for unused unsafe otherwise we get build failures
// due to changes in CXX 1.0.130
// https://github.com/dtolnay/cxx/commit/46fedc68464f80587057c436b4f6b6debeb9f714
#[allow(unused_unsafe)]
#(#docs)*
#module
};
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-gen/test_outputs/inheritance.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cxx::bridge(namespace = "")]
#[allow(unused_unsafe)]
mod inheritance {
extern "C++" {
include!("cxx-qt-lib/qmodelindex.h");
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-gen/test_outputs/invokables.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cxx::bridge(namespace = "cxx_qt::my_object")]
#[allow(unused_unsafe)]
mod ffi {
#[namespace = ""]
unsafe extern "C++" {
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cxx::bridge(namespace = "cxx_qt::multi_object")]
#[allow(unused_unsafe)]
pub mod ffi {
const MAX: u16 = 65535;
enum Event {
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-gen/test_outputs/properties.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cxx::bridge(namespace = "cxx_qt::my_object")]
#[allow(unused_unsafe)]
mod ffi {
#[namespace = ""]
unsafe extern "C++" {
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-gen/test_outputs/qenum.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cxx::bridge(namespace = "cxx_qt::my_object")]
#[allow(unused_unsafe)]
mod ffi {
unsafe extern "C++" {
include ! (< QtCore / QObject >);
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-gen/test_outputs/signals.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cxx::bridge(namespace = "cxx_qt::my_object")]
#[allow(unused_unsafe)]
mod ffi {
#[namespace = ""]
unsafe extern "C++" {
Expand Down
4 changes: 0 additions & 4 deletions crates/cxx-qt-lib/include/core/qanystringview.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ namespace cxxqtlib1 {

QAnyStringView
qanystringviewInitFromRustString(::rust::Str string);
QAnyStringView
qanystringviewInitFromQString(const QString& string);
::rust::String
qanystringviewToRustString(const QAnyStringView& string);

::rust::isize
qanystringviewLen(const QAnyStringView& string);
Expand Down
6 changes: 0 additions & 6 deletions crates/cxx-qt-lib/src/core/qanystringview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ qanystringviewInitFromRustString(::rust::Str string)
return QAnyStringView(string.data(), string.size());
}

QAnyStringView
qanystringviewInitFromQString(const QString& string)
{
return QAnyStringView(string);
}

::rust::isize
qanystringviewLen(const QAnyStringView& string)
{
Expand Down
31 changes: 24 additions & 7 deletions crates/cxx-qt-lib/src/core/qanystringview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-FileContributor: Joshua Goins <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::QString;
use crate::{QByteArray, QString};
use core::ffi::c_void;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
Expand All @@ -14,6 +14,9 @@ mod ffi {
include!("cxx-qt-lib/qanystringview.h");
type QAnyStringView<'a> = super::QAnyStringView<'a>;

include!("cxx-qt-lib/qbytearray.h");
type QByteArray = crate::QByteArray;

include!("cxx-qt-lib/qstring.h");
type QString = crate::QString;

Expand All @@ -24,6 +27,10 @@ mod ffi {
/// Returns true if this string is null; otherwise returns false.
#[rust_name = "is_null"]
fn isNull(self: &QAnyStringView) -> bool;

/// Returns a deep copy of this string view's data as a QString.
#[rust_name = "to_qstring"]
fn toString(self: &QAnyStringView) -> QString;
}

#[namespace = "rust::cxxqtlib1"]
Expand All @@ -35,13 +42,16 @@ mod ffi {
fn construct() -> QAnyStringView<'static>;
#[doc(hidden)]
#[rust_name = "QAnyStringView_init_from_rust_string"]
fn qanystringviewInitFromRustString<'a>(string: &str) -> QAnyStringView<'a>;
fn qanystringviewInitFromRustString<'a>(string: &'a str) -> QAnyStringView<'a>;
#[doc(hidden)]
#[rust_name = "QAnyStringView_init_from_qbytearray"]
fn construct<'a>(bytes: &'a QByteArray) -> QAnyStringView<'a>;
#[doc(hidden)]
#[rust_name = "QAnyStringView_init_from_qstring"]
fn qanystringviewInitFromQString<'a>(string: &QString) -> QAnyStringView<'a>;
fn construct<'a>(string: &'a QString) -> QAnyStringView<'a>;
#[doc(hidden)]
#[rust_name = "QAnyStringView_init_from_QAnyStringView"]
fn construct<'a>(string: &QAnyStringView) -> QAnyStringView<'a>;
fn construct<'a>(string: &QAnyStringView<'a>) -> QAnyStringView<'a>;

#[doc(hidden)]
#[rust_name = "QAnyStringView_eq"]
Expand Down Expand Up @@ -90,14 +100,21 @@ impl Eq for QAnyStringView<'_> {}

impl<'a> From<&'a str> for QAnyStringView<'a> {
/// Constructs a QAnyStringView from a Rust string
fn from(str: &str) -> Self {
fn from(str: &'a str) -> Self {
ffi::QAnyStringView_init_from_rust_string(str)
}
}

impl From<&QString> for QAnyStringView<'_> {
impl<'a> From<&'a QByteArray> for QAnyStringView<'a> {
/// Constructs a QAnyStringView from a QByteArray
fn from(bytes: &'a QByteArray) -> Self {
ffi::QAnyStringView_init_from_qbytearray(bytes)
}
}

impl<'a> From<&'a QString> for QAnyStringView<'a> {
/// Constructs a QAnyStringView from a QString
fn from(string: &QString) -> Self {
fn from(string: &'a QString) -> Self {
ffi::QAnyStringView_init_from_qstring(string)
}
}
Expand Down
14 changes: 14 additions & 0 deletions crates/cxx-qt/include/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
#pragma once

#include <iostream>
#include <memory>
#include <mutex>
#include <shared_mutex>
Expand Down Expand Up @@ -58,8 +59,14 @@ class CxxQtThread final
// Ensure that we can read the pointer and it's not being written to
const auto guard = ::std::shared_lock(m_obj->mutex);
if (!m_obj->ptr) {
#if defined(RUST_CXX_NO_EXCEPTIONS)
std::cerr << "Cannot queue function pointer as object has been destroyed"
<< std::endl;
std::abort();
#else
throw ::std::runtime_error(
"Cannot queue function pointer as object has been destroyed");
#endif
return;
}

Expand All @@ -81,8 +88,15 @@ class CxxQtThread final
// Add the lambda to the queue
if (!QMetaObject::invokeMethod(
m_obj->ptr, ::std::move(lambda), Qt::QueuedConnection)) {
#if defined(RUST_CXX_NO_EXCEPTIONS)
std::cerr
<< "Cannot queue function pointer as invokeMethod on object failed"
<< std::endl;
std::abort();
#else
throw ::std::runtime_error(
"Cannot queue function pointer as invokeMethod on object failed");
#endif
}
}

Expand Down
3 changes: 2 additions & 1 deletion examples/demo_threading/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ if(NOT CxxQt_FOUND)
FetchContent_Declare(
CxxQt
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
GIT_TAG main
GIT_TAG wasm-set-cxxflags
# GIT_TAG main
)

FetchContent_MakeAvailable(CxxQt)
Expand Down
3 changes: 2 additions & 1 deletion examples/qml_features/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ if(NOT CxxQt_FOUND)
FetchContent_Declare(
CxxQt
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
GIT_TAG main
GIT_TAG wasm-set-cxxflags
# GIT_TAG main
)

FetchContent_MakeAvailable(CxxQt)
Expand Down
3 changes: 2 additions & 1 deletion examples/qml_minimal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ if(NOT CxxQt_FOUND)
CxxQt
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
# ANCHOR_END: book_cmake_find_cxx_qt_start
GIT_TAG main
GIT_TAG wasm-set-cxxflags
# GIT_TAG main
# ANCHOR: book_cmake_find_cxx_qt_end
)

Expand Down
3 changes: 2 additions & 1 deletion tests/basic_cxx_only/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ if(NOT CxxQt_FOUND)
FetchContent_Declare(
CxxQt
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
GIT_TAG main
GIT_TAG wasm-set-cxxflags
# GIT_TAG main
)

FetchContent_MakeAvailable(CxxQt)
Expand Down
3 changes: 2 additions & 1 deletion tests/basic_cxx_qt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ if(NOT CxxQt_FOUND)
FetchContent_Declare(
CxxQt
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
GIT_TAG main
GIT_TAG wasm-set-cxxflags
# GIT_TAG main
)

FetchContent_MakeAvailable(CxxQt)
Expand Down
3 changes: 2 additions & 1 deletion tests/qt_types_standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ if(NOT CxxQt_FOUND)
FetchContent_Declare(
CxxQt
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
GIT_TAG main
GIT_TAG wasm-set-cxxflags
# GIT_TAG main
)

FetchContent_MakeAvailable(CxxQt)
Expand Down
18 changes: 14 additions & 4 deletions tests/qt_types_standalone/rust/src/qanystringview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,27 @@ mod qanystringview_cxx {

extern "Rust" {
fn construct_qanystringview(str: &str) -> QAnyStringView;
}

// This method must be unsafe otherwise we hit
// must be `unsafe fn` in order to expose explicit lifetimes to C++
//
// But then Rust complains about unused unsafe so we need to allow for this
#[allow(unused_unsafe)]
extern "Rust" {
unsafe fn construct_qanystringview_qstring<'a>(str: &'a QString) -> QAnyStringView<'a>;
unsafe fn clone_qanystringview<'a>(l: &'a QAnyStringView) -> QAnyStringView<'a>;
unsafe fn clone_qanystringview<'a>(l: &QAnyStringView<'a>) -> QAnyStringView<'a>;
}
}

fn construct_qanystringview(str: &str) -> QAnyStringView {
fn construct_qanystringview<'a>(str: &'a str) -> QAnyStringView<'a> {
QAnyStringView::from(str)
}
fn construct_qanystringview_qstring(str: &QString) -> QAnyStringView {

fn construct_qanystringview_qstring<'a>(str: &'a QString) -> QAnyStringView<'a> {
QAnyStringView::from(str)
}
fn clone_qanystringview<'a>(l: &'a QAnyStringView) -> QAnyStringView<'a> {

fn clone_qanystringview<'a>(l: &QAnyStringView<'a>) -> QAnyStringView<'a> {
l.clone()
}
Loading