Skip to content

Commit 87270e6

Browse files
committed
cxx-qt-gen: require cxx_file_stem until Span::source_file is stable
Closes #855
1 parent 7b3f154 commit 87270e6

27 files changed

+60
-39
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4646
- Add CMake wrappers around corrosion to simplify importing crates and qml modules that were built with cxx-qt-build
4747
- CMake code has been extracted into a separate repository for faster downloads (kdab/cxx-qt-cmake)
4848
- Folder structure of Rust bridges is now considered in the same way as CXX in `CxxQtBuilder`
49+
- All `#[cxx_qt::bridge]` macros must specify a `cxx_file_stem` until `Span::source_file()` is stable
4950

5051
### Removed
5152

book/src/bridge/extern_rustqt.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ mod ffi {
2323

2424
The `extern "RustQt"` section of a CXX bridge declares Rust types and signatures to be made available to Qt and C++.
2525

26-
The CXX code generator uses your `extern "Rust"` section(s) to produce a C++ header file containing the corresponding C++ declarations. The generated header has a file name matching the module ident or the `cxx_file_stem` field in the `#[cxx_qt::bridge]` attribute and with a `.cxxqt.h` file extension.
26+
The CXX code generator uses your `extern "Rust"` section(s) to produce a C++ header file containing the corresponding C++ declarations. The generated header has a file name of the `cxx_file_stem` field in the `#[cxx_qt::bridge]` attribute and with a `.cxxqt.h` file extension.
27+
28+
> Note that once there is support for `source_file` or similar in the `Span` macro we want to support copying the file name like CXX.
2729
2830
A bridge module may contain zero or more `extern "RustQt"` blocks.
2931

book/src/bridge/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ By default, the name of the generated C++ header file will be the name of the mo
3030

3131
This can cause issues as the module is normally called `ffi` or `qobject`, so collisions would occur.
3232

33-
The `cxx_file_stem` option allow a file name to be specified to avoid collisions.
33+
The `cxx_file_stem` option allows a file name to be specified to avoid collisions.
3434

3535
```rust,ignore
3636
{{#include ../../../examples/qml_features/rust/src/types.rs:book_cxx_file_stem}}

book/src/getting-started/5-cmake-integration.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ You can add as much C++ code as you want in addition to this.
3838

3939
For every `#[cxx_qt::bridge]` that we define in Rust, CXX-Qt will generate a corresponding C++ header file.
4040
To include any of the generated files, use the crates name as the include directory.
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 <qml_minimal/qobject.cxxqt.h>`
41+
The name of the header file will be the folder names, combined with the `cxx_file_stem` of your `#[cxx_qt::bridge]`, followed by `.cxxqt.h`.
42+
So in our case: `#include <qml_minimal/src/cxxqt_object.cxxqt.h>`
4343

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.
44+
> Note that the [`cxx_file_stem`](../bridge/index.md#cxx_file_stem) option must be specified in the bridge macro to choose the file name.
45+
46+
> Note that once `Span::source_file()` is stable the `cxx_file_stem` will be optional and the file name will be the default like CXX>
47+
48+
> Note any folders relative to the cargo manifest are considered hence the `src` folder.
4549
4650
Including the generated header allows us to access the `MyObject` C++ class, just like any other C++ class.
4751
Inherit from it, connect signals and slots to it, put it in a QVector, do whatever you want with it.

crates/cxx-qt-build/src/lib.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,9 @@ impl GeneratedCpp {
138138
let rust_tokens = write_rust(&generated_rust);
139139

140140
// Use the relative path with the cxx_file_stem
141-
//
142-
// TODO: ideally CXX-Qt would also use the file name
143-
// but it uses the module or cxx_file_stem for now
144-
// https://github.com/KDAB/cxx-qt/pull/200/commits/4861c92e66c3a022d3f0dedd9f8fd20db064b42b
145141
file_ident = relative_path
146142
.as_ref()
147-
.with_file_name(parser.cxx_file_stem)
143+
.with_file_name(parser.cxx_file_stem())
148144
.to_str()
149145
.unwrap()
150146
.clone_into(&mut file_ident);
@@ -275,7 +271,6 @@ fn generate_cxxqt_cpp_files(
275271

276272
let mut generated_file_paths: Vec<GeneratedCppFilePaths> = Vec::with_capacity(rs_source.len());
277273
for rs_path in rs_source {
278-
let cpp_directory = cxx_qt_dir.join("src");
279274
let path = manifest_dir.join(rs_path);
280275
println!("cargo:rerun-if-changed={}", path.to_string_lossy());
281276

@@ -286,7 +281,7 @@ fn generate_cxxqt_cpp_files(
286281
std::process::exit(1);
287282
}
288283
};
289-
generated_file_paths.push(generated_code.write_to_directories(cpp_directory, &header_dir));
284+
generated_file_paths.push(generated_code.write_to_directories(cxx_qt_dir, &header_dir));
290285
}
291286

292287
generated_file_paths

crates/cxx-qt-gen/src/generator/cpp/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl GeneratedCppBlocks {
6666
Ok(GeneratedCppBlocks {
6767
forward_declares,
6868
includes,
69-
cxx_file_stem: parser.cxx_file_stem.clone(),
69+
cxx_file_stem: parser.cxx_file_stem(),
7070
qobjects: structures
7171
.qobjects
7272
.iter()
@@ -119,7 +119,7 @@ mod tests {
119119
#[test]
120120
fn test_generated_cpp_blocks() {
121121
let module: ItemMod = parse_quote! {
122-
#[cxx_qt::bridge]
122+
#[cxx_qt::bridge(cxx_file_stem = "ffi")]
123123
mod ffi {
124124
extern "RustQt" {
125125
#[qobject]
@@ -157,7 +157,7 @@ mod tests {
157157
#[test]
158158
fn test_generated_cpp_blocks_namespace() {
159159
let module: ItemMod = parse_quote! {
160-
#[cxx_qt::bridge(namespace = "cxx_qt")]
160+
#[cxx_qt::bridge(cxx_file_stem = "ffi", namespace = "cxx_qt")]
161161
mod ffi {
162162
extern "RustQt" {
163163
#[qobject]

crates/cxx-qt-gen/src/generator/rust/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl GeneratedRustBlocks {
8686
fn generate_include(parser: &Parser) -> Result<Item> {
8787
let import_path = format!(
8888
"{header_prefix}/{}.cxxqt.h",
89-
parser.cxx_file_stem,
89+
parser.cxx_file_stem(),
9090
header_prefix = writer::get_header_prefix()
9191
);
9292

crates/cxx-qt-gen/src/parser/mod.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ pub struct Parser {
4040
/// all type names that were found in this module, including CXX types
4141
pub(crate) type_names: TypeNames,
4242
/// The stem of the file that the CXX headers for this module will be generated into
43-
pub cxx_file_stem: String,
43+
pub(crate) cxx_file_stem: Option<String>,
4444
}
4545

4646
impl Parser {
47-
fn parse_mod_attributes(module: &mut ItemMod) -> Result<(Option<String>, String)> {
47+
fn parse_mod_attributes(module: &mut ItemMod) -> Result<(Option<String>, Option<String>)> {
4848
let mut namespace = None;
49-
let mut cxx_file_stem = module.ident.to_string();
49+
let mut cxx_file_stem = None;
5050

5151
// Remove the cxx_qt::bridge attribute
5252
if let Some(attr) = attribute_take_path(&mut module.attrs, &["cxx_qt", "bridge"]) {
@@ -62,13 +62,21 @@ impl Parser {
6262
namespace = Some(expr_to_string(&name_value.value)?);
6363
// Parse any custom file stem
6464
} else if name_value.path.is_ident("cxx_file_stem") {
65-
cxx_file_stem = expr_to_string(&name_value.value)?;
65+
cxx_file_stem = Some(expr_to_string(&name_value.value)?);
6666
}
6767
}
6868
_others => {}
6969
}
7070
}
7171
}
72+
73+
// Temporary until Span::source_file() is stable
74+
if cxx_file_stem.is_none() {
75+
return Err(Error::new(
76+
module.span(),
77+
"All cxx_qt::bridge macros specify a cxx_file_stem until Span::source_file() is stable https://github.com/rust-lang/rust/issues/54725",
78+
));
79+
}
7280
} else {
7381
return Err(Error::new(
7482
module.span(),
@@ -150,6 +158,17 @@ impl Parser {
150158
cxx_file_stem,
151159
})
152160
}
161+
162+
/// Determine the file stem to use for this macro
163+
pub fn cxx_file_stem(&self) -> String {
164+
if let Some(cxx_file_stem) = self.cxx_file_stem.as_ref() {
165+
cxx_file_stem.clone()
166+
} else {
167+
// TODO: ideally CXX-Qt would also use the file name but it uses the cxx_file_stem for now
168+
// https://github.com/KDAB/cxx-qt/pull/200/commits/4861c92e66c3a022d3f0dedd9f8fd20db064b42b
169+
unimplemented!("Missing cxx_file_stem, once Span::source_file() is stable we can determine the file name")
170+
}
171+
}
153172
}
154173

155174
#[cfg(test)]

crates/cxx-qt-gen/test_inputs/inheritance.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[cxx_qt::bridge]
1+
#[cxx_qt::bridge(cxx_file_stem = "inheritance")]
22
mod inheritance {
33
extern "C++" {
44
include!("cxx-qt-lib/qmodelindex.h");

crates/cxx-qt-gen/test_inputs/invokables.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[cxx_qt::bridge(namespace = "cxx_qt::my_object")]
1+
#[cxx_qt::bridge(cxx_file_stem = "invokables", namespace = "cxx_qt::my_object")]
22
mod ffi {
33
#[namespace = ""]
44
unsafe extern "C++" {

crates/cxx-qt-gen/test_inputs/properties.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[cxx_qt::bridge(namespace = "cxx_qt::my_object")]
1+
#[cxx_qt::bridge(cxx_file_stem = "properties", namespace = "cxx_qt::my_object")]
22
mod ffi {
33
#[namespace = ""]
44
unsafe extern "C++" {

crates/cxx-qt-gen/test_inputs/qenum.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[cxx_qt::bridge(namespace = "cxx_qt::my_object")]
1+
#[cxx_qt::bridge(cxx_file_stem = "qenum", namespace = "cxx_qt::my_object")]
22
mod ffi {
33
#[qenum(MyObject)]
44
enum MyEnum {

crates/cxx-qt-gen/test_inputs/shebang.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/
22
// Test for qtitem and qtfile, for code coverage
3-
#[cxx_qt::bridge]
3+
#[cxx_qt::bridge(cxx_file_stem = "shebang")]
44
mod ffi {
55
extern "RustQt" {
66
#[qobject]

crates/cxx-qt-gen/test_inputs/signals.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[cxx_qt::bridge(namespace = "cxx_qt::my_object")]
1+
#[cxx_qt::bridge(cxx_file_stem = "signals", namespace = "cxx_qt::my_object")]
22
mod ffi {
33
#[namespace = ""]
44
unsafe extern "C++" {

crates/cxx-qt-gen/test_outputs/invokables.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "cxx-qt-gen/ffi.cxxqt.h"
1+
#include "cxx-qt-gen/invokables.cxxqt.h"
22

33
namespace cxx_qt::my_object {
44
void

crates/cxx-qt-gen/test_outputs/invokables.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ using MyObjectCxxQtThread = ::rust::cxxqt1::CxxQtThread<MyObject>;
1010

1111
} // namespace cxx_qt::my_object
1212

13-
#include "cxx-qt-gen/ffi.cxx.h"
13+
#include "cxx-qt-gen/invokables.cxx.h"
1414

1515
namespace cxx_qt::my_object {
1616
class MyObject

crates/cxx-qt-gen/test_outputs/invokables.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mod ffi {
2525
type QMetaObjectConnection = cxx_qt::QMetaObjectConnection;
2626
}
2727
unsafe extern "C++" {
28-
include!("cxx-qt-gen/ffi.cxxqt.h");
28+
include!("cxx-qt-gen/invokables.cxxqt.h");
2929
}
3030
unsafe extern "C++" {
3131
#[doc = "The C++ type for the QObject "]

crates/cxx-qt-gen/test_outputs/properties.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "cxx-qt-gen/ffi.cxxqt.h"
1+
#include "cxx-qt-gen/properties.cxxqt.h"
22

33
// Define namespace otherwise we hit a GCC bug
44
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480

crates/cxx-qt-gen/test_outputs/properties.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ using MyObjectCxxQtSignalHandlermyOnChanged =
3232
::rust::cxxqt1::SignalHandler<struct MyObjectCxxQtSignalParamsmyOnChanged*>;
3333
} // namespace cxx_qt::my_object::rust::cxxqtgen1
3434

35-
#include "cxx-qt-gen/ffi.cxx.h"
35+
#include "cxx-qt-gen/properties.cxx.h"
3636

3737
namespace cxx_qt::my_object::rust::cxxqtgen1 {
3838
::QMetaObject::Connection

crates/cxx-qt-gen/test_outputs/properties.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod ffi {
1818
type QMetaObjectConnection = cxx_qt::QMetaObjectConnection;
1919
}
2020
unsafe extern "C++" {
21-
include!("cxx-qt-gen/ffi.cxxqt.h");
21+
include!("cxx-qt-gen/properties.cxxqt.h");
2222
}
2323
unsafe extern "C++" {
2424
#[doc = "The C++ type for the QObject "]

crates/cxx-qt-gen/test_outputs/qenum.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "cxx-qt-gen/ffi.cxxqt.h"
1+
#include "cxx-qt-gen/qenum.cxxqt.h"
22

33
namespace cxx_qt::my_object {
44
void

crates/cxx-qt-gen/test_outputs/qenum.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ enum class MyRenamedEnum : ::std::int32_t
7272
};
7373
} // namespace cxx_qt::my_object
7474

75-
#include "cxx-qt-gen/ffi.cxx.h"
75+
#include "cxx-qt-gen/qenum.cxx.h"
7676

7777
namespace cxx_qt::my_object {
7878
class MyObject

crates/cxx-qt-gen/test_outputs/qenum.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ mod ffi {
6262
type MyRenamedEnum;
6363
}
6464
unsafe extern "C++" {
65-
include!("cxx-qt-gen/ffi.cxxqt.h");
65+
include!("cxx-qt-gen/qenum.cxxqt.h");
6666
}
6767
unsafe extern "C++" {
6868
#[doc = "The C++ type for the QObject "]

crates/cxx-qt-gen/test_outputs/signals.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "cxx-qt-gen/ffi.cxxqt.h"
1+
#include "cxx-qt-gen/signals.cxxqt.h"
22

33
// Define namespace otherwise we hit a GCC bug
44
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480

crates/cxx-qt-gen/test_outputs/signals.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ using QTimerCxxQtSignalHandlertimeout =
3030
::rust::cxxqt1::SignalHandler<struct QTimerCxxQtSignalParamstimeout*>;
3131
} // namespace cxx_qt::my_object::rust::cxxqtgen1
3232

33-
#include "cxx-qt-gen/ffi.cxx.h"
33+
#include "cxx-qt-gen/signals.cxx.h"
3434

3535
namespace cxx_qt::my_object::rust::cxxqtgen1 {
3636
::QMetaObject::Connection

crates/cxx-qt-gen/test_outputs/signals.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ mod ffi {
1919
type QMetaObjectConnection = cxx_qt::QMetaObjectConnection;
2020
}
2121
unsafe extern "C++" {
22-
include!("cxx-qt-gen/ffi.cxxqt.h");
22+
include!("cxx-qt-gen/signals.cxxqt.h");
2323
}
2424
unsafe extern "C++" {
2525
#[doc = "The C++ type for the QObject "]

examples/qml_minimal/rust/src/cxxqt_object.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// ANCHOR: book_bridge_macro
1010

1111
/// The bridge definition for our QObject
12-
#[cxx_qt::bridge]
12+
#[cxx_qt::bridge(cxx_file_stem = "cxxqt_object")]
1313
pub mod qobject {
1414
// ANCHOR_END: book_bridge_macro
1515

0 commit comments

Comments
 (0)