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

WIP: examples: create a multi project to test multiple crates #598

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ members = [
"examples/demo_threading/rust",
"examples/qml_features/rust",
"examples/qml_minimal/rust",
"examples/meta_project/rust/main",
"examples/meta_project/rust/sub1",
"examples/meta_project/rust/sub2",

"tests/basic_cxx_only/rust",
"tests/basic_cxx_qt/rust",
Expand Down
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# When using `cargo test`
add_subdirectory(qml_features)
add_subdirectory(qml_minimal)
add_subdirectory(meta_project)

# TODO: get demo_threading working for wasm builds
if(NOT BUILD_WASM)
Expand Down
86 changes: 86 additions & 0 deletions examples/meta_project/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# SPDX-FileContributor: Andrew Hayzen <[email protected]>
#
# SPDX-License-Identifier: MIT OR Apache-2.0

cmake_minimum_required(VERSION 3.24)

project(example_meta_project)

# Rust always links against non-debug Windows runtime on *-msvc targets
# Note it is best to set this on the command line to ensure all targets are consistent
# https://github.com/corrosion-rs/corrosion/blob/master/doc/src/common_issues.md#linking-debug-cc-libraries-into-rust-fails-on-windows-msvc-targets
# https://github.com/rust-lang/rust/issues/39016
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
endif()

if(BUILD_WASM)
# Ensure Rust build for the correct target
set(Rust_CARGO_TARGET wasm32-unknown-emscripten)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CXXQT_QTCOMPONENTS Core Gui Qml QuickControls2 QuickTest Test)
if(NOT BUILD_WASM)
set(CXXQT_QTCOMPONENTS ${CXXQT_QTCOMPONENTS} QmlImportScanner)
endif()

if(NOT USE_QT5)
find_package(Qt6 COMPONENTS ${CXXQT_QTCOMPONENTS})
endif()
if(NOT Qt6_FOUND)
find_package(Qt5 5.15 COMPONENTS ${CXXQT_QTCOMPONENTS} REQUIRED)
endif()

find_package(CxxQt QUIET)
if(NOT CxxQt_FOUND)
include(FetchContent)
FetchContent_Declare(
CxxQt
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
GIT_TAG main
)

FetchContent_MakeAvailable(CxxQt)
endif()

cxx_qt_import_crate(MANIFEST_PATH rust/main/Cargo.toml CRATES qml_meta_project)
target_link_libraries(qml_meta_project INTERFACE Qt::Core Qt::Gui Qt::Qml Qt::QuickControls2)

cxx_qt_import_qml_module(qml_meta_project_main
URI "com.kdab.cxx_qt.demo"
SOURCE_CRATE qml_meta_project)

cxx_qt_import_qml_module(qml_meta_project_sub1
URI "com.kdab.cxx_qt.demo.sub1"
SOURCE_CRATE qml_meta_project)

cxx_qt_import_qml_module(qml_meta_project_sub2
URI "com.kdab.cxx_qt.demo.sub2"
SOURCE_CRATE qml_meta_project)

# Define the executable with the C++ source
if(BUILD_WASM)
# Currently need to use qt_add_executable
# for WASM builds, otherwise there is no
# HTML output.
#
# TODO: Figure out how to configure such that
# we can use add_executable for WASM
qt_add_executable(example_meta_project cpp/main.cpp)
else()
add_executable(example_meta_project cpp/main.cpp)
endif()

# Link to the qml module, which in turn links to the Rust qml_meta_project library
target_link_libraries(example_meta_project PRIVATE Qt::Core Qt::Gui Qt::Qml qml_meta_project_main qml_meta_project_sub1 qml_meta_project_sub2)

# If we are using a statically linked Qt then we need to import any qml plugins
qt_import_qml_plugins(example_meta_project)
32 changes: 32 additions & 0 deletions examples/meta_project/cpp/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// clang-format off
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// clang-format on
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
#include <QtGui/QGuiApplication>
#include <QtQml/QQmlApplicationEngine>

int
main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;

const QUrl url(
QStringLiteral("qrc:/qt/qml/com/kdab/cxx_qt/demo/qml/main.qml"));
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject* obj, const QUrl& objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);

engine.load(url);

return app.exec();
}
60 changes: 60 additions & 0 deletions examples/meta_project/qml/main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Window 2.12

import com.kdab.cxx_qt.demo 1.0
import com.kdab.cxx_qt.demo.sub1 1.0
import com.kdab.cxx_qt.demo.sub2 1.0

ApplicationWindow {
id: window
minimumHeight: 480
minimumWidth: 640
title: qsTr("CXX-Qt: Hello World")
visible: true

MainObject {
id: main
}

Sub1Object {
id: sub1
}

Sub2Object {
id: sub2
}

Column {
anchors.fill: parent
anchors.margins: 10
spacing: 10

Label {
text: "Main: " + main.string
}

Label {
text: "Sub1: " + sub1.string
}

Label {
text: "Sub2: " + sub2.string
}

Button {
text: "Increment Number"

onClicked: {
main.increment();
sub1.increment();
sub2.increment();
}
}
}
}
28 changes: 28 additions & 0 deletions examples/meta_project/rust/main/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# SPDX-FileContributor: Andrew Hayzen <[email protected]>
#
# SPDX-License-Identifier: MIT OR Apache-2.0
[package]
name = "qml_meta_project"
version = "0.1.0"
authors = ["Andrew Hayzen <[email protected]>"]
edition = "2021"
license = "MIT OR Apache-2.0"
# Linking CXX-Qt crates as rlibs requires a compiler feature
# that was stabilized in Rust 1.74,
# combining +whole-archive and +bundle link modifiers: https://github.com/rust-lang/rust/pull/113301
rust-version = "1.74"

[lib]
crate-type = ["staticlib"]

[dependencies]
sub1 = { path = "../sub1" }
sub2 = { path = "../sub2" }

cxx.workspace = true
cxx-qt.workspace = true
cxx-qt-lib.workspace = true

[build-dependencies]
cxx-qt-build.workspace = true
18 changes: 18 additions & 0 deletions examples/meta_project/rust/main/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use cxx_qt_build::{CxxQtBuilder, QmlModule};

fn main() {
CxxQtBuilder::new()
.qt_module("Network")
.qml_module(QmlModule::<_, &str> {
uri: "com.kdab.cxx_qt.demo",
rust_files: &["src/main_object.rs"],
qml_files: &["../../qml/main.qml"],
..Default::default()
})
.build();
}
12 changes: 12 additions & 0 deletions examples/meta_project/rust/main/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0

mod main_object;

// Ensure the symbols from the rlib dependencies end up
// in the staticlib (if you use Rust symbols from these
// crates in this crate, you can skip these `extern crate` statements).
extern crate sub1;
extern crate sub2;
42 changes: 42 additions & 0 deletions examples/meta_project/rust/main/src/main_object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0

#[cxx_qt::bridge]
pub mod qobject {
unsafe extern "C++" {
include!("cxx-qt-lib/qstring.h");
type QString = cxx_qt_lib::QString;
}

unsafe extern "RustQt" {
#[qobject]
#[qml_element]
#[qproperty(QString, string)]
type MainObject = super::MainObjectRust;

#[qinvokable]
fn increment(self: Pin<&mut MainObject>);
}
}

use core::pin::Pin;
use cxx_qt::CxxQtType;
use cxx_qt_lib::QString;

#[derive(Default)]
pub struct MainObjectRust {
string: QString,

pub counter: u32,
}

impl qobject::MainObject {
pub fn increment(mut self: Pin<&mut Self>) {
self.as_mut().rust_mut().counter = self.rust().counter + 1;

let new_string = QString::from(&self.rust().counter.to_string());
self.as_mut().set_string(new_string);
}
}
22 changes: 22 additions & 0 deletions examples/meta_project/rust/sub1/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# SPDX-FileContributor: Andrew Hayzen <[email protected]>
#
# SPDX-License-Identifier: MIT OR Apache-2.0
[package]
name = "sub1"
version = "0.1.0"
authors = [
"Andrew Hayzen <[email protected]>",
]
edition = "2021"
license = "MIT OR Apache-2.0"

links = "sub1"

[dependencies]
cxx.workspace = true
cxx-qt.workspace = true
cxx-qt-lib.workspace = true

[build-dependencies]
cxx-qt-build.workspace = true
18 changes: 18 additions & 0 deletions examples/meta_project/rust/sub1/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use cxx_qt_build::{CxxQtBuilder, Interface, QmlModule};

fn main() {
let interface = Interface::default();
CxxQtBuilder::library(interface)
.qt_module("Network")
.qml_module(QmlModule::<_, &str> {
uri: "com.kdab.cxx_qt.demo.sub1",
rust_files: &["src/sub1_object.rs"],
..Default::default()
})
.build();
}
13 changes: 13 additions & 0 deletions examples/meta_project/rust/sub1/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0

// We need to enable packed bundled libs to allow for +bundle and +whole-archive
// https://github.com/rust-lang/rust/issues/108081

mod sub1_object;

pub fn increment(number: u32) -> u32 {
number + 2
}
Loading
Loading