You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Allow cxx-qt-build to deal with build scripts running in parallel (#999)
* refactor: Rename CXXQT_* variables to CXX_QT_*
This is more in line with our crate naming (cxx-qt, not cxxqt) and
is more consistent, as before we were using both.
Fix#996
* refactor: Rename cxxqt_ CMake functions to cxx_qt_
This is more consistent with all our other naming.
* fix: build: Use export_dir on final crate only
Cargo can sometimes build different configurations of the same crate in
parallel.
This caused some failures with our new build system.
However, we can solve this by reverting to the OUT_DIR again.
Using the OUT_DIR is the only supported way to write artifacts anyway.
However, we still need to export data for CMake.
Therefore, we define an additional flag for each exact crate that CMake
is trying to import.
Only this exact crate will then export its data.
As CMake should only build a single configuration at a time, this should
not conflict.
* book: Document user-facing changes to CMake build
* cmake: Resolve ${CRATE} and ${APP_NAME} variables
At least do so in `qml_minimal`. I got the feedback from Milian that
this is rather hard to read otherwise, which I agree with.
Especially as that's the code we include in our getting-started guide it
should be as simple as possible.
* book: Update internals documentation
This is now slightly different, as we're no longer using a shared export
directory
CXX-Qt could work with any C++ build system so long as the `QMAKE` and `CXXQT_EXPORT_DIR` environment variables are set before calling Cargo,
16
-
as documented in [CMake integration](../getting-started/5-cmake-integration.md). However, using C++ build systems besides CMake with CXX-Qt is untested.
15
+
CXX-Qt could work with any C++ build system so long as the `QMAKE`, `CXX_QT_EXPORT_DIR` and `CXX_QT_EXPORT_CRATE_<CRATE-NAME>` environment variables are set before calling Cargo.
16
+
Take a look at our CMake code for how this can be used.
17
+
However, using C++ build systems besides Cargo or CMake with CXX-Qt is untested and the use of these environment variables is SemVer-exempt!
Copy file name to clipboardExpand all lines: book/src/getting-started/2-our-first-cxx-qt-module.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -10,8 +10,8 @@ SPDX-License-Identifier: MIT OR Apache-2.0
10
10
As with all things Rust, we'll want to create a cargo project, run the following command inside the `tutorial` folder to initialize the Rust part of the project.
11
11
12
12
```shell
13
-
$ cargo new cxx-qt-tutorial
14
-
$ cdcxx-qt-tutorial
13
+
$ cargo new qml_minimal
14
+
$ cdqml_minimal
15
15
```
16
16
17
17
> If you want to skip building with Cargo and try building with CMake directly
Copy file name to clipboardExpand all lines: book/src/getting-started/5-cmake-integration.md
+26-17Lines changed: 26 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -37,20 +37,20 @@ You can add as much C++ code as you want in addition to this.
37
37
## Using Rust QObjects in C++
38
38
39
39
For every `#[cxx_qt::bridge]` that we define in Rust, CXX-Qt will generate a corresponding C++ header file.
40
-
They will always be in the `cxx-qt-gen/` include path and use the snake_case naming convention.
40
+
To include any of the generated files, use the crates name as the include directory.
41
41
The name of the header file will be the name of the Rust module of your `#[cxx_qt::bridge]`, followed by `.cxxqt.h`.
42
-
So in our case: `#include cxx-qt-gen/qobject.cxxqt.h`
42
+
So in our case: `#include <qml_minimal/qobject.cxxqt.h>`
43
43
44
44
> Note that the [`cxx_file_stem`](../bridge/index.md#cxx_file_stem) option can be specified in the bridge macro to choose the file name.
45
45
46
-
Including the generated header allows accessing the `MyObject` C++ class, just like any other C++ class.
46
+
Including the generated header allows us to access the `MyObject` C++ class, just like any other C++ class.
47
47
Inherit from it, connect signals and slots to it, put it in a QVector, do whatever you want with it.
48
48
That's the power of CXX-Qt.
49
49
50
50
## Cargo setup
51
51
52
52
Before we can get started on building Qt with CMake, we first need to make our Cargo build ready for it.
53
-
If you've generated your project with the`cargo new --lib` or `cargo init --lib [folder]` command, your `Cargo.toml` should look something like this:
53
+
If you've generated your project with e.g.`cargo new --lib qml_minimal` or `cargo init --lib [folder]` command, your `Cargo.toml` should look something like this:
54
54
55
55
```toml,ignore
56
56
[package]
@@ -107,7 +107,9 @@ The files and resources in the module are then exposed in the same way as the [q
107
107
108
108
> Note that in order for CXX-Qt to work, the `qmake` executable must be located. This is because CXX-Qt relies on `qmake` to locate the necessary Qt libraries and header files on your system.
109
109
>
110
-
> This will be done in the `CMakeLists.txt` file by setting the `QMAKE` environment variable from CMake, ensuring that CMake and Cargo use the same Qt binaries.
110
+
> Usually, the CMake code that CXX-Qt provides you to import a crate should already take care of this.
111
+
>
112
+
> To overwrite the path to qmake, you may pass the `QMAKE` option to cxx_qt_import_crate, ensuring that CMake and Cargo use the same Qt binaries.
111
113
112
114
We'll also need to remove the `src/main.rs` and replace it with a `src/lib.rs` file.
113
115
This file only needs to include a single line:
@@ -130,27 +132,34 @@ For this example, we are [supporting both Qt5 and Qt6 with CMake](https://doc.qt
To ensure that cxx-qt-build uses the same version of Qt as your CMake targets, use the `Qt` CMake target to locate the qmake executable. Then, pass `qmake` executable path to `build.rs` with the environment variable `QMAKE` using `corrosion_set_env_vars`.
141
+
This provides you with a few wrappers around [Corrosion](https://github.com/corrosion-rs/corrosion), a tool for integrating Rust libraries into CMake:
142
+
143
+
1.`cxx_qt_import_crate` - A wrapper around [corrosion_import_crate](https://corrosion-rs.github.io/corrosion/usage.html). It supports the same arguments as corrosion_import_crate, with two new optional arguments:
144
+
-`CXX_QT_EXPORT_DIR` - Manually specify the path where CXX-Qt artifacts will be exported to.
145
+
- This is usually not necessary. However, if you're importing the same crate with different feature sets in the same CMake build configuration, you will need to specify seperate `CXX_QT_EXPORT_DIR`s to avoid multiple versions of the crate exporting to the same directory.
146
+
-`QMAKE` - Override the path to the QMAKE executable
147
+
2.`cxx_qt_import_qml_module` - This function imports a QML modules as a new target. It requires the following arguments:
148
+
- TARGET_NAME - Specify the name of the CMake target that this function will create
149
+
-`URI` - The URI of the qml module to import - this needs to exactly match the URI in the `CxxQtBuilder::qml_module` call in your build script.
150
+
-`SOURCE_CRATE` The crate that exports the QML module (this crate must have been imported with `cxx_qt_import_crate`).
1.`qml_minimal` - The static library exported by our crate
159
+
2.`qml_minimal_qml_module` - The QML Module exported by our crate
160
+
- The `_qml_module` target will automatically link to the `qml_minimal` target, so linking to the `_qml_module` is sufficient for our executable target
152
161
153
-
Finally, create the CMake executable target and link it to the Rust library:
162
+
Finally, we can create the CMake executable target and link it to our crate:
Copy file name to clipboardExpand all lines: book/src/internals/build-system.md
+14-19Lines changed: 14 additions & 19 deletions
Original file line number
Diff line number
Diff line change
@@ -39,38 +39,33 @@ Somehow, all of this should be compatible with both CMake, and Cargo-only builds
39
39
40
40
## The plan (for now)
41
41
42
-
After many rounds of refactoring this, we believe the best way to go is to not rely on cargos OUT_DIR exclusivly.
43
-
Not being able to share artifacts between crates is very limiting.
42
+
After many rounds of refactoring this, we believe that we need to be able to share data between build scripts for this to work halfway ergonomically.
44
43
45
-
We want to use a similar approach to CXX, which stores its data within either:
44
+
We want to use a similar approach to CXX, which uses Cargos `links` key to ensure a correct build order (see the documentation [here](https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key)).
45
+
When building with cxx-qt-build, you may simply specify that your code depends on another crate.
46
+
Cargo will then make sure that the build scripts of the dependencies have run **before** the build script of this crate.
46
47
47
-
- Cargos `target/` directory under the `cxxbridge` subfolder.
48
-
- A custom `scratch` directory
48
+
We can additionally pass metadata between build scripts, which we use to find the `manifest.json` of each crate and the path to their "target" directory.
We will likely mirror this and use the `cxxqtbridge` naming.
52
+
Each build script can export artifacts into a folder with a well-known layout.
53
+
It is also required to export a `manifest.json` file that tells downstream dependencies which of these artifacts to include and how to configure their own build.
54
54
55
-
## Contents of `cxxqtbridge`
55
+
This "target" directory is usually in the OUT_DIR, but can be exported using `CXX_QT_EXPORT_DIR` and `CXX_QT_EXPORT_CRATE_[crate-name]` environment variables.
56
+
Which is used by CMake to import the artifacts. (See: [Integration with CMake](#integration-with-cmake))
56
57
57
58
### `crates` directory
58
59
59
-
Inside cxxqtbridge, there should be a `crates` folder with one subfolder per crate.
60
+
Inside the target directory, there should be a `crates` folder with one subfolder per crate.
60
61
Each crates subfolder should contain the following:
61
62
62
63
-`include/`
63
64
-`crate-name` - A folder for all headers that are exported by this crate
64
-
-`cxx-qt-lib -> ../../cxx-qt-lib/include` - Symbolic links for every dependency
65
+
-`cxx-qt-lib -> <path-to-dependency>/include/cxx-qt-lib` - Symbolic links for every dependency
65
66
-`manifest.json` - This file describes which headers this library makes available, if it needs any Qt modules, etc.
66
67
-`initializers.o` - The initializers of this crate + all it's dependencies to be linked in by CMake
67
68
68
-
When building with cxx-qt-build, you may simply specify that your code depends on another crate.
69
-
However, we also need to make sure that the order in which the build scripts are run works out, as e.g. the build script of cxx-qt-lib needs to run **before** any dependents build scripts run.
70
-
71
-
For this use-case, Cargo has the `links` key (see the documentation [here](https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key)).
72
-
It allows us to ensure the correct order, and also to pass metadata between build scripts.
73
-
We specifically use this to let downstream dependents know where to find our manifest.json.
74
69
Via the `manifest.json`, we are then able to figure out which header paths of this dependency to include, which Qt modules to link, etc.
75
70
76
71
To make sure the correct data ends up in the manifest.json, we provide the `cxx_qt_build::Interface` struct which uses the builder pattern to specify all the necessary data.
@@ -83,14 +78,14 @@ Each module should include a `plugin_init.o`, `.qmltypes`, `qmldir`, and any oth
83
78
84
79
## Integration with CMake
85
80
86
-
Via the `CXXQT_EXPORT_DIR` environment variable CMake should be able to change the location of the `cxxqtbridge` directory.
81
+
Via the `CXXQT_EXPORT_DIR` environment variable CMake should be able to change the location of the "target" directory.
87
82
CMake can then expect required artifacts to exist at pre-defined locations, which can be added as dependency, include directories, objects, etc. to the Crate target.
88
83
89
84
We will rely on Corrosion to import the crate and provide targets for it.
90
85
91
86
However, we also want to provide some custom functions that wrap corrosion and set up the import of our own artifacts.
92
87
93
-
Currently we plan to provide two functions:
88
+
Currently we provide two functions:
94
89
95
90
- cxxqt_import_crate
96
91
- A wrapper over corrosion_import_crate that defines the `CXXQT_EXPORT_DIR`, imports the initializers object files, etc.
message(FATAL_ERROR "cxxqt_import_crate: QMAKE is not defined and could not be queried from the Qt::qmake target!\nPlease use the QMAKE argument to specify the path to the qmake executable or use find_package(Qt) before calling this function.")
36
+
message(FATAL_ERROR "cxx_qt_import_crate: QMAKE is not defined and could not be queried from the Qt::qmake target!\nPlease use the QMAKE argument to specify the path to the qmake executable or use find_package(Qt) before calling cxx_qt_import_crate.")
0 commit comments